WIP
Fiat-Shamir dark alchemy implemented in Solidity as a way for users to provide proofs of secret offchain knowledge without sending hashes vulnerable to dictionary attacks. Instead of a trusted setup ceremony as with a zk-snark, the "zk-niro" users derive proofs with a secret random nonce and and public random challenge from the contract during each proof verification.
- Offchain password/data verification. Users can manage their own data locally and offchain and verify it's existance against a smart contract.
For concrete example see test
- Generate a random prime number (n) and generator value(g).
- Hash secret data offchain (x) Calculate (y) value as: y = gx (mod n)
- Send (n, g, y) as seed values to the
FiatShamirZKP.registerSeed()
function. - Later, when the user wishes to verify offchain data, retrieve random challenge (c) from contract with
FiatShamirZKP.getChallenge()
- User generates a random number (v) between 0 and n and calculates (t) as: t = gv (mod n)
- User calculates (r) as: r = v - c * x
- User sends t and r as the zkproof to
FiatShamirZKP.verify()
. (At no point is x or v sent to the contract) - The contract calculates ( gr (mod n) * yc (mod n) ) verifying the resulting value with t.
The proof works because:
gr yc = g v-cx (gx)c
= gv-cx gxc
= gv-cx+cx
= gv
Currently the library works well within the confines of solidity's 256 bit word sizes. This is ok for the purposes of research and experimentation, however it is more desirable to have a smart contract system that plays well with very large primes. Fortunately, new iterations of the EVM have included opcodes that map to bignumber precompile operations (mod, expmod, etc.) and there has been some research and development integrating these functions into solidity.
How To Prove Yourself: Practical Solutions to Identification and Signature Problems
Special thanks to Professor Bill Buchanan, OBE