lastmjs / homomorphic-encryption-playground

Just playing around with homomorphic encryption
MIT License
0 stars 0 forks source link

Private ERC20 #2

Open lastmjs opened 4 years ago

lastmjs commented 4 years ago

I think this might be feasible. An ERC20 token, or an extension of the token, which has encrypted balances. The FHE can add and subtract and ensure balances are correct. Otherwise, all inputs to functions are encrypted, and the balances themselves are encrypted. Microsoft SEAL might be able to do this. We could use the WebAssembly version and deploy on eWASM maybe, or somehow get the C++ code into Solidity, or compile the Wasm to EVM bytecode

lastmjs commented 4 years ago

I think I might be able to use node-seal to get this to work, for one user. Multikey support is essential to creating an actual cryptocurrency with private balances. But a proof of concept could just allow one user to deposit and withdraw funds to their own account. The problem that still needs to be solved is asserting that the deposits and withdrawals are allowable. I'm not sure that I can do encrypted comparisons. I've opened up a few issues to look into this:

lastmjs commented 4 years ago

Okay, I might be able to do this without branching or comparison per se. Imagine this. Let's say Bob wants to send Alice some coins. Bob sends an amount A, and he has balance B. First, we compute the difference between A and B, and store it as D. If D is positive, everything is good. If D is negative, then we know that Bob was being bad. Bad Bob. The problem is, to enforce this it makes sense that we would need to do a comparison to check if D is positive or to check that A is less than or equal to B. That is hard though, homomorphically. So what if instead we had a polynomial P that evaluated to 1 if D is positive and 0 otherwise? Then we could set B equal to B minus A times P, and we could set Alice's balance to her balance minus A times P as well...could this work? A times P will be A if D is positive, and will be 0 otherwise. So, if you try to spend funds you don't have, each balance will be updated by 0 and you'll just waste gas.

lastmjs commented 4 years ago

Now I'm thinking binary will help out. If we do the balance and transfer amount subtraction in two's complement binary, we should be able to get the first bit to be 1 if the answer is negative, and 0 if it is positive. We can then take this result and multiply it by the transfer amount, which will be a decimal. Actually, we need the 1 to be a 0 if it is negative, hopefully we can do something to get that to work. So then we can multiply the binary most significant bit by the decimal amount, and it will be 0 if the subtraction from the balance was negative, and it will be the transfer amount otherwise. Then we can continue with the calculation of the new balance

lastmjs commented 4 years ago

When converting binary to decimal homomorphically, make sure to relinearize after multiplying the arrays. After that, you can add them together just fine.

lastmjs commented 4 years ago

A = amount (decimal) B = balance (decimal) D = difference (decimal) C = D converted to binary

Convert D to two's complement binary and store it in C. The first bit in C should be 0 if D is positive and 1 if D is negative. Negate C. Add 1 to C. Multiply A by that result. Subtract that result from B and from the other person's balance.

lastmjs commented 4 years ago

Do it all in binary. Take D, the first bit should be 1 if negative and 0 otherwise. Multiply it by an array with 1 as the first bit and the rest 0s. Do the negation thing as above. Sum the array. This will turn it into all 1s or all 0s depending on the first element. Then take that and multiply it by the amount A. Then, we should have either an array of 0s or the original A. Then we can subtract this from the balances!