parent
677ca5403d
commit
2077c92095
@ -1,26 +0,0 @@ |
||||
|
||||
## CIRCOM ZKP SEMAPHORE WORKSPACE |
||||
|
||||
Welcome to the Remix Circom ZKP Semaphore Workspace. |
||||
|
||||
The workspace comprises two main directories: |
||||
|
||||
### circuits: Contains sample semaphore contracts. These can be compiled to generate a witness using 'Circom ZKP Compiler' plugin. |
||||
|
||||
### scripts: Provides a sample script designed for a trusted setup using snarkjs. This script also aids in generating Solidity code, which is essential for on-chain deployment. |
||||
|
||||
### first steps: |
||||
|
||||
#### 1) compile the semaphore circuit using the remix circom compiler. This will generate artifacts. |
||||
|
||||
#### 2) execute the file `run_setup.ts`: |
||||
This step generate a verification key that can be used for generating proof, it will also generate a Solidity contract for on-chain verification. |
||||
Note that this section should only be used for development purposes as this way of running the setup is heavily centralized (although some pieces of this script can be used to achieve that). |
||||
This generates a verification key (`./zk/build/verification_key.json`) and artifacts from the setup (`./zk/build/zk_setup.txt`). |
||||
|
||||
#### 3) execute the file `run_verification.ts`: |
||||
This script: |
||||
- create a list of identity commitments and add it to a `IncrementalMerkleTree`. The tree is used to generate a merkle proof that a specified identity is actually in the tree (see`tree.createProof(0)`). |
||||
- generate a witness and a proof of execution. |
||||
- verify that the proof is valid `(snarkjs.groth16.verify)` |
||||
- ultimately verify that the hash generated by the circom compiler is the same as the root hash for the Tree. `(proof1.root.toString() === publicSignals[0]`). This assert that the identity provided to the circuit is actually part of that semaphore group. |
@ -1,57 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
include "./eff_ecdsa.circom"; |
||||
include "./tree.circom"; |
||||
include "./to_address/zk-identity/eth.circom"; |
||||
|
||||
/** |
||||
* AddrMembership |
||||
* ============== |
||||
* |
||||
* Checks that an inputted efficient ECDSA signature (definition and discussion |
||||
* can be found at https://personaelabs.org/posts/efficient-ecdsa-1/) |
||||
* is signed by a public key that when converted to an address is a member of |
||||
* a Merkle tree of addresses. The public key is extracted from the efficient |
||||
* ECDSA signature in EfficientECDSA(), and converted to an address by Keccak |
||||
* hashing the public key in PubkeyToAddress(). |
||||
*/ |
||||
template AddrMembership(nLevels) { |
||||
signal input s; |
||||
signal input root; |
||||
signal input Tx; |
||||
signal input Ty; |
||||
signal input Ux; |
||||
signal input Uy; |
||||
signal input pathIndices[nLevels]; |
||||
signal input siblings[nLevels]; |
||||
|
||||
component effEcdsa = EfficientECDSA(); |
||||
effEcdsa.Tx <== Tx; |
||||
effEcdsa.Ty <== Ty; |
||||
effEcdsa.Ux <== Ux; |
||||
effEcdsa.Uy <== Uy; |
||||
effEcdsa.s <== s; |
||||
|
||||
component pubKeyXBits = Num2Bits(256); |
||||
pubKeyXBits.in <== effEcdsa.pubKeyX; |
||||
|
||||
component pubKeyYBits = Num2Bits(256); |
||||
pubKeyYBits.in <== effEcdsa.pubKeyY; |
||||
|
||||
component pubToAddr = PubkeyToAddress(); |
||||
|
||||
for (var i = 0; i < 256; i++) { |
||||
pubToAddr.pubkeyBits[i] <== pubKeyYBits.out[i]; |
||||
pubToAddr.pubkeyBits[i + 256] <== pubKeyXBits.out[i]; |
||||
} |
||||
|
||||
component merkleProof = MerkleTreeInclusionProof(nLevels); |
||||
merkleProof.leaf <== pubToAddr.address; |
||||
|
||||
for (var i = 0; i < nLevels; i++) { |
||||
merkleProof.pathIndices[i] <== pathIndices[i]; |
||||
merkleProof.siblings[i] <== siblings[i]; |
||||
} |
||||
|
||||
root === merkleProof.root; |
||||
} |
@ -1,39 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
include "./secp256k1/mul.circom"; |
||||
include "circomlib/circuits/bitify.circom"; |
||||
|
||||
/** |
||||
* EfficientECDSA |
||||
* ==================== |
||||
* |
||||
* Converts inputted efficient ECDSA signature to an public key. There is no |
||||
* public key validation included. |
||||
*/ |
||||
template EfficientECDSA() { |
||||
var bits = 256; |
||||
signal input s; |
||||
signal input Tx; // T = r^-1 * R |
||||
signal input Ty; |
||||
signal input Ux; // U = -(m * r^-1 * G) |
||||
signal input Uy; |
||||
|
||||
signal output pubKeyX; |
||||
signal output pubKeyY; |
||||
|
||||
// sMultT = s * T |
||||
component sMultT = Secp256k1Mul(); |
||||
sMultT.scalar <== s; |
||||
sMultT.xP <== Tx; |
||||
sMultT.yP <== Ty; |
||||
|
||||
// pubKey = sMultT + U |
||||
component pubKey = Secp256k1AddComplete(); |
||||
pubKey.xP <== sMultT.outX; |
||||
pubKey.yP <== sMultT.outY; |
||||
pubKey.xQ <== Ux; |
||||
pubKey.yQ <== Uy; |
||||
|
||||
pubKeyX <== pubKey.outX; |
||||
pubKeyY <== pubKey.outY; |
||||
} |
@ -1,42 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
include "./eff_ecdsa.circom"; |
||||
include "./to_address/zk-identity/eth.circom"; |
||||
|
||||
/** |
||||
* EfficientECDSAToAddr |
||||
* ==================== |
||||
* |
||||
* Converts inputted efficient ECDSA signature to an address. |
||||
*/ |
||||
template EfficientECDSAToAddr() { |
||||
var bits = 256; |
||||
signal input s; |
||||
signal input Tx; // T = r^-1 * R |
||||
signal input Ty; |
||||
signal input Ux; // U = -(m * r^-1 * G) |
||||
signal input Uy; |
||||
signal output addr; |
||||
|
||||
component effEcdsa = EfficientECDSA(); |
||||
effEcdsa.s <== s; |
||||
effEcdsa.Tx <== Tx; |
||||
effEcdsa.Ty <== Ty; |
||||
effEcdsa.Ux <== Ux; |
||||
effEcdsa.Uy <== Uy; |
||||
|
||||
component pubKeyXBits = Num2Bits(256); |
||||
pubKeyXBits.in <== effEcdsa.pubKeyX; |
||||
|
||||
component pubKeyYBits = Num2Bits(256); |
||||
pubKeyYBits.in <== effEcdsa.pubKeyY; |
||||
|
||||
component pubToAddr = PubkeyToAddress(); |
||||
|
||||
for (var i = 0; i < 256; i++) { |
||||
pubToAddr.pubkeyBits[i] <== pubKeyYBits.out[i]; |
||||
pubToAddr.pubkeyBits[i + 256] <== pubKeyXBits.out[i]; |
||||
} |
||||
|
||||
addr <== pubToAddr.address; |
||||
} |
@ -1,46 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
include "./eff_ecdsa.circom"; |
||||
include "./tree.circom"; |
||||
include "../poseidon/poseidon.circom"; |
||||
|
||||
/** |
||||
* PubkeyMembership |
||||
* ================ |
||||
* |
||||
* Checks that an inputted efficient ECDSA signature (definition and discussion |
||||
* can be found at https://personaelabs.org/posts/efficient-ecdsa-1/) |
||||
* is signed by a public key that is in a Merkle tree of public keys. Avoids the |
||||
* SNARK-unfriendly Keccak hash that must be performed when validating if the |
||||
* public key is in a Merkle tree of addresses. |
||||
*/ |
||||
template PubKeyMembership(nLevels) { |
||||
signal input s; |
||||
signal input root; |
||||
signal input Tx; |
||||
signal input Ty; |
||||
signal input Ux; |
||||
signal input Uy; |
||||
signal input pathIndices[nLevels]; |
||||
signal input siblings[nLevels]; |
||||
|
||||
component ecdsa = EfficientECDSA(); |
||||
ecdsa.Tx <== Tx; |
||||
ecdsa.Ty <== Ty; |
||||
ecdsa.Ux <== Ux; |
||||
ecdsa.Uy <== Uy; |
||||
ecdsa.s <== s; |
||||
|
||||
component pubKeyHash = Poseidon(); |
||||
pubKeyHash.inputs[0] <== ecdsa.pubKeyX; |
||||
pubKeyHash.inputs[1] <== ecdsa.pubKeyY; |
||||
|
||||
component merkleProof = MerkleTreeInclusionProof(nLevels); |
||||
merkleProof.leaf <== pubKeyHash.out; |
||||
|
||||
for (var i = 0; i < nLevels; i++) { |
||||
merkleProof.pathIndices[i] <== pathIndices[i]; |
||||
merkleProof.siblings[i] <== siblings[i]; |
||||
} |
||||
root === merkleProof.root; |
||||
} |
@ -1,125 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
include "circomlib/circuits/comparators.circom"; |
||||
include "circomlib/circuits/gates.circom"; |
||||
|
||||
/** |
||||
* Secp256k1AddIncomplete |
||||
* ====================== |
||||
* |
||||
* Adds two points (xP, yP) and (xQ, yQ) on the secp256k1 curve. This function |
||||
* only works for points where xP != xQ and are not at infinity. We can implement |
||||
* the raw formulae for this operation as we are doing right field arithmetic |
||||
* (we are doing secp256k1 base field arithmetic in the secq256k1 scalar field, |
||||
* which are equal). Should work for any short Weierstrass curve (Pasta, P-256). |
||||
*/ |
||||
template Secp256k1AddIncomplete() { |
||||
signal input xP; |
||||
signal input yP; |
||||
signal input xQ; |
||||
signal input yQ; |
||||
signal output outX; |
||||
signal output outY; |
||||
|
||||
signal lambda; |
||||
signal dx; |
||||
signal dy; |
||||
|
||||
dx <== xP - xQ; |
||||
dy <== yP - yQ; |
||||
|
||||
lambda <-- dy / dx; |
||||
dx * lambda === dy; |
||||
|
||||
outX <== lambda * lambda - xP - xQ; |
||||
outY <== lambda * (xP - outX) - yP; |
||||
} |
||||
|
||||
/** |
||||
* Secp256k1AddComplete |
||||
* ==================== |
||||
* |
||||
* Implements https://zcash.github.io/halo2/design/gadgets/ecc/addition.html#complete-addition |
||||
* so we can add any pair of points. Assumes (0, 0) is not a valid point (which |
||||
* is true for secp256k1) and is used as the point at infinity. |
||||
*/ |
||||
template Secp256k1AddComplete() { |
||||
signal input xP; |
||||
signal input yP; |
||||
signal input xQ; |
||||
signal input yQ; |
||||
|
||||
signal output outX; |
||||
signal output outY; |
||||
|
||||
signal xPSquared <== xP * xP; |
||||
|
||||
component isXEqual = IsEqual(); |
||||
isXEqual.in[0] <== xP; |
||||
isXEqual.in[1] <== xQ; |
||||
|
||||
component isXpZero = IsZero(); |
||||
isXpZero.in <== xP; |
||||
|
||||
component isXqZero = IsZero(); |
||||
isXqZero.in <== xQ; |
||||
|
||||
component isXEitherZero = IsZero(); |
||||
isXEitherZero.in <== (1 - isXpZero.out) * (1 - isXqZero.out); |
||||
|
||||
// dx = xQ - xP |
||||
// dy = xP != xQ ? yQ - yP : 0 |
||||
// lambdaA = xP != xQ ? (yQ - yP) / (xQ - xP) : 0 |
||||
signal dx <== xQ - xP; |
||||
signal dy <== (yQ - yP) * (1 - isXEqual.out); |
||||
signal lambdaA <-- ((yQ - yP) / dx) * (1 - isXEqual.out); |
||||
dx * lambdaA === dy; |
||||
|
||||
// lambdaB = (3 * xP^2) / (2 * yP) |
||||
signal lambdaB <-- ((3 * xPSquared) / (2 * yP)); |
||||
lambdaB * 2 * yP === 3 * xPSquared; |
||||
|
||||
// lambda = xP != xQ ? lambdaA : lambdaB |
||||
signal lambda <== (lambdaB * isXEqual.out) + lambdaA; |
||||
|
||||
// outAx = lambda^2 - xP - xQ |
||||
// outAy = lambda * (xP - outAx) - yP |
||||
signal outAx <== lambda * lambda - xP - xQ; |
||||
signal outAy <== lambda * (xP - outAx) - yP; |
||||
|
||||
// (outBx, outBy) = xP != 0 and xQ != 0 ? (outAx, outAy) : (0, 0) |
||||
signal outBx <== outAx * (1 - isXEitherZero.out); |
||||
signal outBy <== outAy * (1 - isXEitherZero.out); |
||||
|
||||
//(outCx, outCy) = xP = 0 ? (xQ, yQ) : (0, 0) |
||||
signal outCx <== isXpZero.out * xQ; |
||||
signal outCy <== isXpZero.out * yQ; |
||||
|
||||
// (outDx, outDy) = xQ = 0 ? (xP, yP) : (0, 0) |
||||
signal outDx <== isXqZero.out * xP; |
||||
signal outDy <== isXqZero.out * yP; |
||||
|
||||
// zeroizeA = (xP = xQ and yP = -yQ) ? 1 : 0 |
||||
component zeroizeA = IsEqual(); |
||||
zeroizeA.in[0] <== isXEqual.out; |
||||
zeroizeA.in[1] <== 1 - (yP + yQ); |
||||
|
||||
// zeroizeB = (xP = 0 and xQ = 0) ? 1 : 0 |
||||
component zeroizeB = AND(); |
||||
zeroizeB.a <== isXpZero.out; |
||||
zeroizeB.b <== isXqZero.out; |
||||
|
||||
// zeroize = (xP = xQ and yP = -yQ) or (xP = 0 and xQ = 0) ? 1 : 0 |
||||
// for this case we want to output the point at infinity (0, 0) |
||||
component zeroize = OR(); |
||||
zeroize.a <== zeroizeA.out; |
||||
zeroize.b <== zeroizeB.out; |
||||
|
||||
// The below three conditionals are mutually exclusive when zeroize = 0, |
||||
// so we can safely sum the outputs. |
||||
// outBx != 0 iff xP != 0 and xQ != 0 |
||||
// outCx != 0 iff xP = 0 |
||||
// outDx != 0 iff xQ = 0 |
||||
outX <== (outBx + outCx + outDx) * (1 - zeroize.out); |
||||
outY <== (outBy + outCy + outDy) * (1 - zeroize.out); |
||||
} |
@ -1,27 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
/** |
||||
* Secp256k1Double |
||||
* =============== |
||||
* |
||||
* Double a specific point (xP, yP) on the secp256k1 curve. Should work for any |
||||
* short Weierstrass curve (Pasta, P-256). |
||||
*/ |
||||
template Secp256k1Double() { |
||||
signal input xP; |
||||
signal input yP; |
||||
|
||||
signal output outX; |
||||
signal output outY; |
||||
|
||||
signal lambda; |
||||
signal xPSquared; |
||||
|
||||
xPSquared <== xP * xP; |
||||
|
||||
lambda <-- (3 * xPSquared) / (2 * yP); |
||||
lambda * 2 * yP === 3 * xPSquared; |
||||
|
||||
outX <== lambda * lambda - (2 * xP); |
||||
outY <== lambda * (xP - outX) - yP; |
||||
} |
@ -1,190 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
include "./add.circom"; |
||||
include "./double.circom"; |
||||
include "circomlib/circuits/bitify.circom"; |
||||
include "circomlib/circuits/comparators.circom"; |
||||
include "circomlib/circuits/gates.circom"; |
||||
|
||||
// |
||||
|
||||
/** |
||||
* Secp256k1Mul |
||||
* ============ |
||||
* |
||||
* Implements https://zcash.github.io/halo2/design/gadgets/ecc/var-base-scalar-mul.html |
||||
* which allows us to use incomplete addition for the majority of the addition steps |
||||
* and only use complete addition for the final 3 steps. |
||||
*/ |
||||
template Secp256k1Mul() { |
||||
var bits = 256; |
||||
signal input scalar; |
||||
signal input xP; |
||||
signal input yP; |
||||
signal output outX; |
||||
signal output outY; |
||||
|
||||
component kBits = K(); |
||||
kBits.s <== scalar; |
||||
|
||||
component acc0 = Secp256k1Double(); |
||||
acc0.xP <== xP; |
||||
acc0.yP <== yP; |
||||
|
||||
component PIncomplete[bits-3]; |
||||
component accIncomplete[bits]; |
||||
|
||||
for (var i = 0; i < bits-3; i++) { |
||||
if (i == 0) { |
||||
PIncomplete[i] = Secp256k1AddIncomplete(); // (Acc + P) |
||||
PIncomplete[i].xP <== xP; // kBits[i] ? xP : -xP; |
||||
PIncomplete[i].yP <== -yP;// kBits[i] ? xP : -xP; |
||||
PIncomplete[i].xQ <== acc0.outX; |
||||
PIncomplete[i].yQ <== acc0.outY; |
||||
|
||||
|
||||
accIncomplete[i] = Secp256k1AddIncomplete(); // (Acc + P) + Acc |
||||
accIncomplete[i].xP <== acc0.outX; |
||||
accIncomplete[i].yP <== acc0.outY; |
||||
accIncomplete[i].xQ <== PIncomplete[i].outX; |
||||
accIncomplete[i].yQ <== PIncomplete[i].outY; |
||||
} else { |
||||
PIncomplete[i] = Secp256k1AddIncomplete(); // (Acc + P) |
||||
PIncomplete[i].xP <== xP; // k_i ? xP : -xP; |
||||
PIncomplete[i].yP <== (2 * kBits.out[bits-i] - 1) * yP;// k_i ? xP : -xP; |
||||
PIncomplete[i].xQ <== accIncomplete[i-1].outX; |
||||
PIncomplete[i].yQ <== accIncomplete[i-1].outY; |
||||
|
||||
accIncomplete[i] = Secp256k1AddIncomplete(); // (Acc + P) + Acc |
||||
accIncomplete[i].xP <== accIncomplete[i-1].outX; |
||||
accIncomplete[i].yP <== accIncomplete[i-1].outY; |
||||
accIncomplete[i].xQ <== PIncomplete[i].outX; |
||||
accIncomplete[i].yQ <== PIncomplete[i].outY; |
||||
} |
||||
} |
||||
|
||||
component PComplete[bits-3]; |
||||
component accComplete[3]; |
||||
|
||||
for (var i = 0; i < 3; i++) { |
||||
PComplete[i] = Secp256k1AddComplete(); // (Acc + P) |
||||
|
||||
PComplete[i].xP <== xP; // k_i ? xP : -xP; |
||||
PComplete[i].yP <== (2 * kBits.out[3 - i] - 1) * yP;// k_i ? xP : -xP; |
||||
if (i == 0) { |
||||
PComplete[i].xQ <== accIncomplete[252].outX; |
||||
PComplete[i].yQ <== accIncomplete[252].outY; |
||||
} else { |
||||
PComplete[i].xQ <== accComplete[i-1].outX; |
||||
PComplete[i].yQ <== accComplete[i-1].outY; |
||||
} |
||||
|
||||
accComplete[i] = Secp256k1AddComplete(); // (Acc + P) + Acc |
||||
if (i == 0) { |
||||
accComplete[i].xP <== accIncomplete[252].outX; |
||||
accComplete[i].yP <== accIncomplete[252].outY; |
||||
} else { |
||||
accComplete[i].xP <== accComplete[i-1].outX; |
||||
accComplete[i].yP <== accComplete[i-1].outY; |
||||
} |
||||
|
||||
accComplete[i].xQ <== PComplete[i].outX; |
||||
accComplete[i].yQ <== PComplete[i].outY; |
||||
} |
||||
|
||||
component out = Secp256k1AddComplete(); |
||||
out.xP <== accComplete[2].outX; |
||||
out.yP <== accComplete[2].outY; |
||||
out.xQ <== (1 - kBits.out[0]) * xP; |
||||
out.yQ <== (1 - kBits.out[0]) * -yP; |
||||
|
||||
outX <== out.outX; |
||||
outY <== out.outY; |
||||
} |
||||
|
||||
// Calculate k = (s + tQ) % q as follows: |
||||
// Define notation: (s + tQ) / q = (quotient, remainder) |
||||
// We can calculate the quotient and remainder as: |
||||
// (s + tQ) < q ? = (0, s - tQ) : (1, (s - tQ) - q) |
||||
// We use 128-bit registers to calculate the above since (s + tQ) can be larger than p. |
||||
template K() { |
||||
var bits = 256; |
||||
signal input s; |
||||
signal output out[bits]; |
||||
|
||||
// Split elemnts into 128 bit registers |
||||
|
||||
var q = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141; // The order of the scalar field |
||||
var qlo = q & ((2 ** 128) - 1); |
||||
var qhi = q >> 128; |
||||
var tQ = 115792089237316195423570985008687907852405143892509244725752742275123193348738; // (q - 2^256) % q; |
||||
var tQlo = tQ & (2 ** (128) - 1); |
||||
var tQhi = tQ >> 128; |
||||
signal slo <-- s & (2 ** (128) - 1); |
||||
signal shi <-- s >> 128; |
||||
|
||||
// Get carry bit of (slo + tQlo) |
||||
|
||||
component inBits = Num2Bits(128 + 1); |
||||
inBits.in <== slo + tQlo; |
||||
signal carry <== inBits.out[128]; |
||||
|
||||
// check a >= b |
||||
// where |
||||
// a = (s + tQ) |
||||
// b = q |
||||
|
||||
// - alpha: ahi > bhi |
||||
// - beta: ahi = bhi |
||||
// - gamma: alo ≥ blo |
||||
// if alpha or (beta and gamma) then a >= b |
||||
|
||||
signal ahi <== shi + tQhi + carry; |
||||
signal bhi <== qhi; |
||||
signal alo <== slo + tQlo - (carry * 2 ** 128); |
||||
signal blo <== qlo; |
||||
|
||||
component alpha = GreaterThan(129); |
||||
alpha.in[0] <== ahi; |
||||
alpha.in[1] <== bhi; |
||||
|
||||
component beta = IsEqual(); |
||||
beta.in[0] <== ahi; |
||||
beta.in[1] <== bhi; |
||||
|
||||
component gamma = GreaterEqThan(129); |
||||
gamma.in[0] <== alo; |
||||
gamma.in[1] <== blo; |
||||
|
||||
component betaANDgamma = AND(); |
||||
betaANDgamma.a <== beta.out; |
||||
betaANDgamma.b <== gamma.out; |
||||
|
||||
component isQuotientOne = OR(); |
||||
isQuotientOne.a <== betaANDgamma.out; |
||||
isQuotientOne.b <== alpha.out; |
||||
|
||||
// theta: (slo + tQlo) < qlo |
||||
component theta = GreaterThan(129); |
||||
theta.in[0] <== qlo; |
||||
theta.in[1] <== slo + tQlo; |
||||
|
||||
// borrow: (slo + tQlo) < qlo and isQuotientOne ? 1 : 0 |
||||
component borrow = AND(); |
||||
borrow.a <== theta.out; |
||||
borrow.b <== isQuotientOne.out; |
||||
|
||||
signal klo <== (slo + tQlo + borrow.out * (2 ** 128)) - isQuotientOne.out * qlo; |
||||
signal khi <== (shi + tQhi - borrow.out * 1) - isQuotientOne.out * qhi; |
||||
|
||||
component kloBits = Num2Bits(256); |
||||
kloBits.in <== klo; |
||||
|
||||
component khiBits = Num2Bits(256); |
||||
khiBits.in <== khi; |
||||
|
||||
for (var i = 0; i < 128; i++) { |
||||
out[i] <== kloBits.out[i]; |
||||
out[i + 128] <== khiBits.out[i]; |
||||
} |
||||
} |
@ -1,183 +0,0 @@ |
||||
pragma circom 2.0.2; |
||||
|
||||
include "./utils.circom"; |
||||
include "./permutations.circom"; |
||||
|
||||
template Pad(nBits) { |
||||
signal input in[nBits]; |
||||
|
||||
var blockSize=136*8; |
||||
signal output out[blockSize]; |
||||
signal out2[blockSize]; |
||||
|
||||
var i; |
||||
|
||||
for (i=0; i<nBits; i++) { |
||||
out2[i] <== in[i]; |
||||
} |
||||
var domain = 0x01; |
||||
for (i=0; i<8; i++) { |
||||
out2[nBits+i] <== (domain >> i) & 1; |
||||
} |
||||
for (i=nBits+8; i<blockSize; i++) { |
||||
out2[i] <== 0; |
||||
} |
||||
component aux = OrArray(8); |
||||
for (i=0; i<8; i++) { |
||||
aux.a[i] <== out2[blockSize-8+i]; |
||||
aux.b[i] <== (0x80 >> i) & 1; |
||||
} |
||||
for (i=0; i<8; i++) { |
||||
out[blockSize-8+i] <== aux.out[i]; |
||||
} |
||||
for (i=0; i<blockSize-8; i++) { |
||||
out[i]<==out2[i]; |
||||
} |
||||
} |
||||
|
||||
template KeccakfRound(r) { |
||||
signal input in[25*64]; |
||||
signal output out[25*64]; |
||||
var i; |
||||
|
||||
component theta = Theta(); |
||||
component rhopi = RhoPi(); |
||||
component chi = Chi(); |
||||
component iota = Iota(r); |
||||
|
||||
for (i=0; i<25*64; i++) { |
||||
theta.in[i] <== in[i]; |
||||
} |
||||
for (i=0; i<25*64; i++) { |
||||
rhopi.in[i] <== theta.out[i]; |
||||
} |
||||
for (i=0; i<25*64; i++) { |
||||
chi.in[i] <== rhopi.out[i]; |
||||
} |
||||
for (i=0; i<25*64; i++) { |
||||
iota.in[i] <== chi.out[i]; |
||||
} |
||||
for (i=0; i<25*64; i++) { |
||||
out[i] <== iota.out[i]; |
||||
} |
||||
} |
||||
|
||||
template Absorb() { |
||||
var blockSizeBytes=136; |
||||
|
||||
signal input s[25*64]; |
||||
signal input block[blockSizeBytes*8]; |
||||
signal output out[25*64]; |
||||
var i; |
||||
var j; |
||||
|
||||
component aux[blockSizeBytes/8]; |
||||
component newS = Keccakf(); |
||||
|
||||
for (i=0; i<blockSizeBytes/8; i++) { |
||||
aux[i] = XorArray(64); |
||||
for (j=0; j<64; j++) { |
||||
aux[i].a[j] <== s[i*64+j]; |
||||
aux[i].b[j] <== block[i*64+j]; |
||||
} |
||||
for (j=0; j<64; j++) { |
||||
newS.in[i*64+j] <== aux[i].out[j]; |
||||
} |
||||
} |
||||
// fill the missing s that was not covered by the loop over |
||||
// blockSizeBytes/8 |
||||
for (i=(blockSizeBytes/8)*64; i<25*64; i++) { |
||||
newS.in[i] <== s[i]; |
||||
} |
||||
for (i=0; i<25*64; i++) { |
||||
out[i] <== newS.out[i]; |
||||
} |
||||
} |
||||
|
||||
template Final(nBits) { |
||||
signal input in[nBits]; |
||||
signal output out[25*64]; |
||||
var blockSize=136*8; |
||||
var i; |
||||
|
||||
// pad |
||||
component pad = Pad(nBits); |
||||
for (i=0; i<nBits; i++) { |
||||
pad.in[i] <== in[i]; |
||||
} |
||||
// absorb |
||||
component abs = Absorb(); |
||||
for (i=0; i<blockSize; i++) { |
||||
abs.block[i] <== pad.out[i]; |
||||
} |
||||
for (i=0; i<25*64; i++) { |
||||
abs.s[i] <== 0; |
||||
} |
||||
for (i=0; i<25*64; i++) { |
||||
out[i] <== abs.out[i]; |
||||
} |
||||
} |
||||
|
||||
template Squeeze(nBits) { |
||||
signal input s[25*64]; |
||||
signal output out[nBits]; |
||||
var i; |
||||
var j; |
||||
|
||||
for (i=0; i<25; i++) { |
||||
for (j=0; j<64; j++) { |
||||
if (i*64+j<nBits) { |
||||
out[i*64+j] <== s[i*64+j]; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
template Keccakf() { |
||||
signal input in[25*64]; |
||||
signal output out[25*64]; |
||||
var i; |
||||
var j; |
||||
|
||||
// 24 rounds |
||||
component round[24]; |
||||
signal midRound[24*25*64]; |
||||
for (i=0; i<24; i++) { |
||||
round[i] = KeccakfRound(i); |
||||
if (i==0) { |
||||
for (j=0; j<25*64; j++) { |
||||
midRound[j] <== in[j]; |
||||
} |
||||
} |
||||
for (j=0; j<25*64; j++) { |
||||
round[i].in[j] <== midRound[i*25*64+j]; |
||||
} |
||||
if (i<23) { |
||||
for (j=0; j<25*64; j++) { |
||||
midRound[(i+1)*25*64+j] <== round[i].out[j]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
for (i=0; i<25*64; i++) { |
||||
out[i] <== round[23].out[i]; |
||||
} |
||||
} |
||||
|
||||
template Keccak(nBitsIn, nBitsOut) { |
||||
signal input in[nBitsIn]; |
||||
signal output out[nBitsOut]; |
||||
var i; |
||||
|
||||
component f = Final(nBitsIn); |
||||
for (i=0; i<nBitsIn; i++) { |
||||
f.in[i] <== in[i]; |
||||
} |
||||
component squeeze = Squeeze(nBitsOut); |
||||
for (i=0; i<25*64; i++) { |
||||
squeeze.s[i] <== f.out[i]; |
||||
} |
||||
for (i=0; i<nBitsOut; i++) { |
||||
out[i] <== squeeze.out[i]; |
||||
} |
||||
} |
@ -1,796 +0,0 @@ |
||||
pragma circom 2.0.2; |
||||
|
||||
include "./utils.circom"; |
||||
|
||||
|
||||
// Theta |
||||
|
||||
template D(n, shl, shr) { |
||||
// d = b ^ (a<<shl | a>>shr) |
||||
signal input a[n]; |
||||
signal input b[n]; |
||||
signal output out[n]; |
||||
var i; |
||||
|
||||
component aux0 = ShR(64, shr); |
||||
for (i=0; i<64; i++) { |
||||
aux0.in[i] <== a[i]; |
||||
} |
||||
component aux1 = ShL(64, shl); |
||||
for (i=0; i<64; i++) { |
||||
aux1.in[i] <== a[i]; |
||||
} |
||||
component aux2 = OrArray(64); |
||||
for (i=0; i<64; i++) { |
||||
aux2.a[i] <== aux0.out[i]; |
||||
aux2.b[i] <== aux1.out[i]; |
||||
} |
||||
component aux3 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
aux3.a[i] <== b[i]; |
||||
aux3.b[i] <== aux2.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[i] <== aux3.out[i]; |
||||
} |
||||
} |
||||
|
||||
template Theta() { |
||||
signal input in[25*64]; |
||||
signal output out[25*64]; |
||||
|
||||
var i; |
||||
|
||||
component c0 = Xor5(64); |
||||
for (i=0; i<64; i++) { |
||||
c0.a[i] <== in[i]; |
||||
c0.b[i] <== in[5*64+i]; |
||||
c0.c[i] <== in[10*64+i]; |
||||
c0.d[i] <== in[15*64+i]; |
||||
c0.e[i] <== in[20*64+i]; |
||||
} |
||||
|
||||
component c1 = Xor5(64); |
||||
for (i=0; i<64; i++) { |
||||
c1.a[i] <== in[1*64+i]; |
||||
c1.b[i] <== in[6*64+i]; |
||||
c1.c[i] <== in[11*64+i]; |
||||
c1.d[i] <== in[16*64+i]; |
||||
c1.e[i] <== in[21*64+i]; |
||||
} |
||||
|
||||
component c2 = Xor5(64); |
||||
for (i=0; i<64; i++) { |
||||
c2.a[i] <== in[2*64+i]; |
||||
c2.b[i] <== in[7*64+i]; |
||||
c2.c[i] <== in[12*64+i]; |
||||
c2.d[i] <== in[17*64+i]; |
||||
c2.e[i] <== in[22*64+i]; |
||||
} |
||||
|
||||
component c3 = Xor5(64); |
||||
for (i=0; i<64; i++) { |
||||
c3.a[i] <== in[3*64+i]; |
||||
c3.b[i] <== in[8*64+i]; |
||||
c3.c[i] <== in[13*64+i]; |
||||
c3.d[i] <== in[18*64+i]; |
||||
c3.e[i] <== in[23*64+i]; |
||||
} |
||||
|
||||
component c4 = Xor5(64); |
||||
for (i=0; i<64; i++) { |
||||
c4.a[i] <== in[4*64+i]; |
||||
c4.b[i] <== in[9*64+i]; |
||||
c4.c[i] <== in[14*64+i]; |
||||
c4.d[i] <== in[19*64+i]; |
||||
c4.e[i] <== in[24*64+i]; |
||||
} |
||||
|
||||
// d = c4 ^ (c1<<1 | c1>>(64-1)) |
||||
component d0 = D(64, 1, 64-1); |
||||
for (i=0; i<64; i++) { |
||||
d0.a[i] <== c1.out[i]; |
||||
d0.b[i] <== c4.out[i]; |
||||
} |
||||
// r[0] = a[0] ^ d |
||||
component r0 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r0.a[i] <== in[i]; |
||||
r0.b[i] <== d0.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[i] <== r0.out[i]; |
||||
} |
||||
// r[5] = a[5] ^ d |
||||
component r5 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r5.a[i] <== in[5*64+i]; |
||||
r5.b[i] <== d0.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[5*64+i] <== r5.out[i]; |
||||
} |
||||
// r[10] = a[10] ^ d |
||||
component r10 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r10.a[i] <== in[10*64+i]; |
||||
r10.b[i] <== d0.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[10*64+i] <== r10.out[i]; |
||||
} |
||||
// r[15] = a[15] ^ d |
||||
component r15 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r15.a[i] <== in[15*64+i]; |
||||
r15.b[i] <== d0.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[15*64+i] <== r15.out[i]; |
||||
} |
||||
// r[20] = a[20] ^ d |
||||
component r20 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r20.a[i] <== in[20*64+i]; |
||||
r20.b[i] <== d0.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[20*64+i] <== r20.out[i]; |
||||
} |
||||
|
||||
// d = c0 ^ (c2<<1 | c2>>(64-1)) |
||||
component d1 = D(64, 1, 64-1); |
||||
for (i=0; i<64; i++) { |
||||
d1.a[i] <== c2.out[i]; |
||||
d1.b[i] <== c0.out[i]; |
||||
} |
||||
// r[1] = a[1] ^ d |
||||
component r1 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r1.a[i] <== in[1*64+i]; |
||||
r1.b[i] <== d1.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[1*64+i] <== r1.out[i]; |
||||
} |
||||
// r[6] = a[6] ^ d |
||||
component r6 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r6.a[i] <== in[6*64+i]; |
||||
r6.b[i] <== d1.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[6*64+i] <== r6.out[i]; |
||||
} |
||||
// r[11] = a[11] ^ d |
||||
component r11 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r11.a[i] <== in[11*64+i]; |
||||
r11.b[i] <== d1.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[11*64+i] <== r11.out[i]; |
||||
} |
||||
// r[16] = a[16] ^ d |
||||
component r16 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r16.a[i] <== in[16*64+i]; |
||||
r16.b[i] <== d1.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[16*64+i] <== r16.out[i]; |
||||
} |
||||
// r[21] = a[21] ^ d |
||||
component r21 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r21.a[i] <== in[21*64+i]; |
||||
r21.b[i] <== d1.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[21*64+i] <== r21.out[i]; |
||||
} |
||||
|
||||
// d = c1 ^ (c3<<1 | c3>>(64-1)) |
||||
component d2 = D(64, 1, 64-1); |
||||
for (i=0; i<64; i++) { |
||||
d2.a[i] <== c3.out[i]; |
||||
d2.b[i] <== c1.out[i]; |
||||
} |
||||
// r[2] = a[2] ^ d |
||||
component r2 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r2.a[i] <== in[2*64+i]; |
||||
r2.b[i] <== d2.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[2*64+i] <== r2.out[i]; |
||||
} |
||||
// r[7] = a[7] ^ d |
||||
component r7 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r7.a[i] <== in[7*64+i]; |
||||
r7.b[i] <== d2.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[7*64+i] <== r7.out[i]; |
||||
} |
||||
// r[12] = a[12] ^ d |
||||
component r12 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r12.a[i] <== in[12*64+i]; |
||||
r12.b[i] <== d2.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[12*64+i] <== r12.out[i]; |
||||
} |
||||
// r[17] = a[17] ^ d |
||||
component r17 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r17.a[i] <== in[17*64+i]; |
||||
r17.b[i] <== d2.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[17*64+i] <== r17.out[i]; |
||||
} |
||||
// r[22] = a[22] ^ d |
||||
component r22 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r22.a[i] <== in[22*64+i]; |
||||
r22.b[i] <== d2.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[22*64+i] <== r22.out[i]; |
||||
} |
||||
|
||||
// d = c2 ^ (c4<<1 | c4>>(64-1)) |
||||
component d3 = D(64, 1, 64-1); |
||||
for (i=0; i<64; i++) { |
||||
d3.a[i] <== c4.out[i]; |
||||
d3.b[i] <== c2.out[i]; |
||||
} |
||||
// r[3] = a[3] ^ d |
||||
component r3 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r3.a[i] <== in[3*64+i]; |
||||
r3.b[i] <== d3.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[3*64+i] <== r3.out[i]; |
||||
} |
||||
// r[8] = a[8] ^ d |
||||
component r8 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r8.a[i] <== in[8*64+i]; |
||||
r8.b[i] <== d3.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[8*64+i] <== r8.out[i]; |
||||
} |
||||
// r[13] = a[13] ^ d |
||||
component r13 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r13.a[i] <== in[13*64+i]; |
||||
r13.b[i] <== d3.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[13*64+i] <== r13.out[i]; |
||||
} |
||||
// r[18] = a[18] ^ d |
||||
component r18 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r18.a[i] <== in[18*64+i]; |
||||
r18.b[i] <== d3.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[18*64+i] <== r18.out[i]; |
||||
} |
||||
// r[23] = a[23] ^ d |
||||
component r23 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r23.a[i] <== in[23*64+i]; |
||||
r23.b[i] <== d3.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[23*64+i] <== r23.out[i]; |
||||
} |
||||
|
||||
// d = c3 ^ (c0<<1 | c0>>(64-1)) |
||||
component d4 = D(64, 1, 64-1); |
||||
for (i=0; i<64; i++) { |
||||
d4.a[i] <== c0.out[i]; |
||||
d4.b[i] <== c3.out[i]; |
||||
} |
||||
// r[4] = a[4] ^ d |
||||
component r4 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r4.a[i] <== in[4*64+i]; |
||||
r4.b[i] <== d4.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[4*64+i] <== r4.out[i]; |
||||
} |
||||
// r[9] = a[9] ^ d |
||||
component r9 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r9.a[i] <== in[9*64+i]; |
||||
r9.b[i] <== d4.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[9*64+i] <== r9.out[i]; |
||||
} |
||||
// r[14] = a[14] ^ d |
||||
component r14 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r14.a[i] <== in[14*64+i]; |
||||
r14.b[i] <== d4.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[14*64+i] <== r14.out[i]; |
||||
} |
||||
// r[19] = a[19] ^ d |
||||
component r19 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r19.a[i] <== in[19*64+i]; |
||||
r19.b[i] <== d4.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[19*64+i] <== r19.out[i]; |
||||
} |
||||
// r[24] = a[24] ^ d |
||||
component r24 = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
r24.a[i] <== in[24*64+i]; |
||||
r24.b[i] <== d4.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[24*64+i] <== r24.out[i]; |
||||
} |
||||
} |
||||
|
||||
// RhoPi |
||||
|
||||
template stepRhoPi(shl, shr) { |
||||
// out = a<<shl|a>>shr |
||||
signal input a[64]; |
||||
signal output out[64]; |
||||
var i; |
||||
|
||||
component aux0 = ShR(64, shr); |
||||
for (i=0; i<64; i++) { |
||||
aux0.in[i] <== a[i]; |
||||
} |
||||
component aux1 = ShL(64, shl); |
||||
for (i=0; i<64; i++) { |
||||
aux1.in[i] <== a[i]; |
||||
} |
||||
component aux2 = OrArray(64); |
||||
for (i=0; i<64; i++) { |
||||
aux2.a[i] <== aux0.out[i]; |
||||
aux2.b[i] <== aux1.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[i] <== aux2.out[i]; |
||||
} |
||||
} |
||||
template RhoPi() { |
||||
signal input in[25*64]; |
||||
signal output out[25*64]; |
||||
|
||||
var i; |
||||
|
||||
// r[10] = a[1]<<1|a[1]>>(64-1) |
||||
component s10 = stepRhoPi(1, 64-1); |
||||
for (i=0; i<64; i++) { |
||||
s10.a[i] <== in[1*64+i]; |
||||
} |
||||
// r[7] = a[10]<<3|a[10]>>(64-3) |
||||
component s7 = stepRhoPi(3, 64-3); |
||||
for (i=0; i<64; i++) { |
||||
s7.a[i] <== in[10*64+i]; |
||||
} |
||||
// r[11] = a[7]<<6|a[7]>>(64-6) |
||||
component s11 = stepRhoPi(6, 64-6); |
||||
for (i=0; i<64; i++) { |
||||
s11.a[i] <== in[7*64+i]; |
||||
} |
||||
// r[17] = a[11]<<10|a[11]>>(64-10) |
||||
component s17 = stepRhoPi(10, 64-10); |
||||
for (i=0; i<64; i++) { |
||||
s17.a[i] <== in[11*64+i]; |
||||
} |
||||
// r[18] = a[17]<<15|a[17]>>(64-15) |
||||
component s18 = stepRhoPi(15, 64-15); |
||||
for (i=0; i<64; i++) { |
||||
s18.a[i] <== in[17*64+i]; |
||||
} |
||||
// r[3] = a[18]<<21|a[18]>>(64-21) |
||||
component s3 = stepRhoPi(21, 64-21); |
||||
for (i=0; i<64; i++) { |
||||
s3.a[i] <== in[18*64+i]; |
||||
} |
||||
// r[5] = a[3]<<28|a[3]>>(64-28) |
||||
component s5 = stepRhoPi(28, 64-28); |
||||
for (i=0; i<64; i++) { |
||||
s5.a[i] <== in[3*64+i]; |
||||
} |
||||
// r[16] = a[5]<<36|a[5]>>(64-36) |
||||
component s16 = stepRhoPi(36, 64-36); |
||||
for (i=0; i<64; i++) { |
||||
s16.a[i] <== in[5*64+i]; |
||||
} |
||||
// r[8] = a[16]<<45|a[16]>>(64-45) |
||||
component s8 = stepRhoPi(45, 64-45); |
||||
for (i=0; i<64; i++) { |
||||
s8.a[i] <== in[16*64+i]; |
||||
} |
||||
// r[21] = a[8]<<55|a[8]>>(64-55) |
||||
component s21 = stepRhoPi(55, 64-55); |
||||
for (i=0; i<64; i++) { |
||||
s21.a[i] <== in[8*64+i]; |
||||
} |
||||
// r[24] = a[21]<<2|a[21]>>(64-2) |
||||
component s24 = stepRhoPi(2, 64-2); |
||||
for (i=0; i<64; i++) { |
||||
s24.a[i] <== in[21*64+i]; |
||||
} |
||||
// r[4] = a[24]<<14|a[24]>>(64-14) |
||||
component s4 = stepRhoPi(14, 64-14); |
||||
for (i=0; i<64; i++) { |
||||
s4.a[i] <== in[24*64+i]; |
||||
} |
||||
// r[15] = a[4]<<27|a[4]>>(64-27) |
||||
component s15 = stepRhoPi(27, 64-27); |
||||
for (i=0; i<64; i++) { |
||||
s15.a[i] <== in[4*64+i]; |
||||
} |
||||
// r[23] = a[15]<<41|a[15]>>(64-41) |
||||
component s23 = stepRhoPi(41, 64-41); |
||||
for (i=0; i<64; i++) { |
||||
s23.a[i] <== in[15*64+i]; |
||||
} |
||||
// r[19] = a[23]<<56|a[23]>>(64-56) |
||||
component s19 = stepRhoPi(56, 64-56); |
||||
for (i=0; i<64; i++) { |
||||
s19.a[i] <== in[23*64+i]; |
||||
} |
||||
// r[13] = a[19]<<8|a[19]>>(64-8) |
||||
component s13 = stepRhoPi(8, 64-8); |
||||
for (i=0; i<64; i++) { |
||||
s13.a[i] <== in[19*64+i]; |
||||
} |
||||
// r[12] = a[13]<<25|a[13]>>(64-25) |
||||
component s12 = stepRhoPi(25, 64-25); |
||||
for (i=0; i<64; i++) { |
||||
s12.a[i] <== in[13*64+i]; |
||||
} |
||||
// r[2] = a[12]<<43|a[12]>>(64-43) |
||||
component s2 = stepRhoPi(43, 64-43); |
||||
for (i=0; i<64; i++) { |
||||
s2.a[i] <== in[12*64+i]; |
||||
} |
||||
// r[20] = a[2]<<62|a[2]>>(64-62) |
||||
component s20 = stepRhoPi(62, 64-62); |
||||
for (i=0; i<64; i++) { |
||||
s20.a[i] <== in[2*64+i]; |
||||
} |
||||
// r[14] = a[20]<<18|a[20]>>(64-18) |
||||
component s14 = stepRhoPi(18, 64-18); |
||||
for (i=0; i<64; i++) { |
||||
s14.a[i] <== in[20*64+i]; |
||||
} |
||||
// r[22] = a[14]<<39|a[14]>>(64-39) |
||||
component s22 = stepRhoPi(39, 64-39); |
||||
for (i=0; i<64; i++) { |
||||
s22.a[i] <== in[14*64+i]; |
||||
} |
||||
// r[9] = a[22]<<61|a[22]>>(64-61) |
||||
component s9 = stepRhoPi(61, 64-61); |
||||
for (i=0; i<64; i++) { |
||||
s9.a[i] <== in[22*64+i]; |
||||
} |
||||
// r[6] = a[9]<<20|a[9]>>(64-20) |
||||
component s6 = stepRhoPi(20, 64-20); |
||||
for (i=0; i<64; i++) { |
||||
s6.a[i] <== in[9*64+i]; |
||||
} |
||||
// r[1] = a[6]<<44|a[6]>>(64-44) |
||||
component s1 = stepRhoPi(44, 64-44); |
||||
for (i=0; i<64; i++) { |
||||
s1.a[i] <== in[6*64+i]; |
||||
} |
||||
|
||||
for (i=0; i<64; i++) { |
||||
out[i] <== in[i]; |
||||
out[10*64+i] <== s10.out[i]; |
||||
out[7*64+i] <== s7.out[i]; |
||||
out[11*64+i] <== s11.out[i]; |
||||
out[17*64+i] <== s17.out[i]; |
||||
out[18*64+i] <== s18.out[i]; |
||||
out[3*64+i] <== s3.out[i]; |
||||
out[5*64+i] <== s5.out[i]; |
||||
out[16*64+i] <== s16.out[i]; |
||||
out[8*64+i] <== s8.out[i]; |
||||
out[21*64+i] <== s21.out[i]; |
||||
out[24*64+i] <== s24.out[i]; |
||||
out[4*64+i] <== s4.out[i]; |
||||
out[15*64+i] <== s15.out[i]; |
||||
out[23*64+i] <== s23.out[i]; |
||||
out[19*64+i] <== s19.out[i]; |
||||
out[13*64+i] <== s13.out[i]; |
||||
out[12*64+i] <== s12.out[i]; |
||||
out[2*64+i] <== s2.out[i]; |
||||
out[20*64+i] <== s20.out[i]; |
||||
out[14*64+i] <== s14.out[i]; |
||||
out[22*64+i] <== s22.out[i]; |
||||
out[9*64+i] <== s9.out[i]; |
||||
out[6*64+i] <== s6.out[i]; |
||||
out[1*64+i] <== s1.out[i]; |
||||
} |
||||
} |
||||
|
||||
|
||||
// Chi |
||||
|
||||
template stepChi() { |
||||
// out = a ^ (^b) & c |
||||
signal input a[64]; |
||||
signal input b[64]; |
||||
signal input c[64]; |
||||
signal output out[64]; |
||||
var i; |
||||
|
||||
// ^b |
||||
component bXor = XorArraySingle(64); |
||||
for (i=0; i<64; i++) { |
||||
bXor.a[i] <== b[i]; |
||||
} |
||||
// (^b)&c |
||||
component bc = AndArray(64); |
||||
for (i=0; i<64; i++) { |
||||
bc.a[i] <== bXor.out[i]; |
||||
bc.b[i] <== c[i]; |
||||
} |
||||
// a^(^b)&c |
||||
component abc = XorArray(64); |
||||
for (i=0; i<64; i++) { |
||||
abc.a[i] <== a[i]; |
||||
abc.b[i] <== bc.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[i] <== abc.out[i]; |
||||
} |
||||
} |
||||
|
||||
template Chi() { |
||||
signal input in[25*64]; |
||||
signal output out[25*64]; |
||||
|
||||
var i; |
||||
|
||||
component r0 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r0.a[i] <== in[i]; |
||||
r0.b[i] <== in[1*64+i]; |
||||
r0.c[i] <== in[2*64+i]; |
||||
} |
||||
component r1 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r1.a[i] <== in[1*64+i]; |
||||
r1.b[i] <== in[2*64+i]; |
||||
r1.c[i] <== in[3*64+i]; |
||||
} |
||||
component r2 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r2.a[i] <== in[2*64+i]; |
||||
r2.b[i] <== in[3*64+i]; |
||||
r2.c[i] <== in[4*64+i]; |
||||
} |
||||
component r3 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r3.a[i] <== in[3*64+i]; |
||||
r3.b[i] <== in[4*64+i]; |
||||
r3.c[i] <== in[0*64+i]; |
||||
} |
||||
component r4 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r4.a[i] <== in[4*64+i]; |
||||
r4.b[i] <== in[i]; |
||||
r4.c[i] <== in[1*64+i]; |
||||
} |
||||
|
||||
component r5 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r5.a[i] <== in[5*64+i]; |
||||
r5.b[i] <== in[6*64+i]; |
||||
r5.c[i] <== in[7*64+i]; |
||||
} |
||||
component r6 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r6.a[i] <== in[6*64+i]; |
||||
r6.b[i] <== in[7*64+i]; |
||||
r6.c[i] <== in[8*64+i]; |
||||
} |
||||
component r7 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r7.a[i] <== in[7*64+i]; |
||||
r7.b[i] <== in[8*64+i]; |
||||
r7.c[i] <== in[9*64+i]; |
||||
} |
||||
component r8 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r8.a[i] <== in[8*64+i]; |
||||
r8.b[i] <== in[9*64+i]; |
||||
r8.c[i] <== in[5*64+i]; |
||||
} |
||||
component r9 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r9.a[i] <== in[9*64+i]; |
||||
r9.b[i] <== in[5*64+i]; |
||||
r9.c[i] <== in[6*64+i]; |
||||
} |
||||
|
||||
component r10 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r10.a[i] <== in[10*64+i]; |
||||
r10.b[i] <== in[11*64+i]; |
||||
r10.c[i] <== in[12*64+i]; |
||||
} |
||||
component r11 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r11.a[i] <== in[11*64+i]; |
||||
r11.b[i] <== in[12*64+i]; |
||||
r11.c[i] <== in[13*64+i]; |
||||
} |
||||
component r12 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r12.a[i] <== in[12*64+i]; |
||||
r12.b[i] <== in[13*64+i]; |
||||
r12.c[i] <== in[14*64+i]; |
||||
} |
||||
component r13 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r13.a[i] <== in[13*64+i]; |
||||
r13.b[i] <== in[14*64+i]; |
||||
r13.c[i] <== in[10*64+i]; |
||||
} |
||||
component r14 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r14.a[i] <== in[14*64+i]; |
||||
r14.b[i] <== in[10*64+i]; |
||||
r14.c[i] <== in[11*64+i]; |
||||
} |
||||
|
||||
component r15 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r15.a[i] <== in[15*64+i]; |
||||
r15.b[i] <== in[16*64+i]; |
||||
r15.c[i] <== in[17*64+i]; |
||||
} |
||||
component r16 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r16.a[i] <== in[16*64+i]; |
||||
r16.b[i] <== in[17*64+i]; |
||||
r16.c[i] <== in[18*64+i]; |
||||
} |
||||
component r17 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r17.a[i] <== in[17*64+i]; |
||||
r17.b[i] <== in[18*64+i]; |
||||
r17.c[i] <== in[19*64+i]; |
||||
} |
||||
component r18 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r18.a[i] <== in[18*64+i]; |
||||
r18.b[i] <== in[19*64+i]; |
||||
r18.c[i] <== in[15*64+i]; |
||||
} |
||||
component r19 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r19.a[i] <== in[19*64+i]; |
||||
r19.b[i] <== in[15*64+i]; |
||||
r19.c[i] <== in[16*64+i]; |
||||
} |
||||
|
||||
component r20 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r20.a[i] <== in[20*64+i]; |
||||
r20.b[i] <== in[21*64+i]; |
||||
r20.c[i] <== in[22*64+i]; |
||||
} |
||||
component r21 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r21.a[i] <== in[21*64+i]; |
||||
r21.b[i] <== in[22*64+i]; |
||||
r21.c[i] <== in[23*64+i]; |
||||
} |
||||
component r22 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r22.a[i] <== in[22*64+i]; |
||||
r22.b[i] <== in[23*64+i]; |
||||
r22.c[i] <== in[24*64+i]; |
||||
} |
||||
component r23 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r23.a[i] <== in[23*64+i]; |
||||
r23.b[i] <== in[24*64+i]; |
||||
r23.c[i] <== in[20*64+i]; |
||||
} |
||||
component r24 = stepChi(); |
||||
for (i=0; i<64; i++) { |
||||
r24.a[i] <== in[24*64+i]; |
||||
r24.b[i] <== in[20*64+i]; |
||||
r24.c[i] <== in[21*64+i]; |
||||
} |
||||
|
||||
for (i=0; i<64; i++) { |
||||
out[i] <== r0.out[i]; |
||||
out[1*64+i] <== r1.out[i]; |
||||
out[2*64+i] <== r2.out[i]; |
||||
out[3*64+i] <== r3.out[i]; |
||||
out[4*64+i] <== r4.out[i]; |
||||
|
||||
out[5*64+i] <== r5.out[i]; |
||||
out[6*64+i] <== r6.out[i]; |
||||
out[7*64+i] <== r7.out[i]; |
||||
out[8*64+i] <== r8.out[i]; |
||||
out[9*64+i] <== r9.out[i]; |
||||
|
||||
out[10*64+i] <== r10.out[i]; |
||||
out[11*64+i] <== r11.out[i]; |
||||
out[12*64+i] <== r12.out[i]; |
||||
out[13*64+i] <== r13.out[i]; |
||||
out[14*64+i] <== r14.out[i]; |
||||
|
||||
out[15*64+i] <== r15.out[i]; |
||||
out[16*64+i] <== r16.out[i]; |
||||
out[17*64+i] <== r17.out[i]; |
||||
out[18*64+i] <== r18.out[i]; |
||||
out[19*64+i] <== r19.out[i]; |
||||
|
||||
out[20*64+i] <== r20.out[i]; |
||||
out[21*64+i] <== r21.out[i]; |
||||
out[22*64+i] <== r22.out[i]; |
||||
out[23*64+i] <== r23.out[i]; |
||||
out[24*64+i] <== r24.out[i]; |
||||
} |
||||
} |
||||
|
||||
// Iota |
||||
|
||||
template RC(r) { |
||||
signal output out[64]; |
||||
var rc[24] = [ |
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808A, |
||||
0x8000000080008000, 0x000000000000808B, 0x0000000080000001, |
||||
0x8000000080008081, 0x8000000000008009, 0x000000000000008A, |
||||
0x0000000000000088, 0x0000000080008009, 0x000000008000000A, |
||||
0x000000008000808B, 0x800000000000008B, 0x8000000000008089, |
||||
0x8000000000008003, 0x8000000000008002, 0x8000000000000080, |
||||
0x000000000000800A, 0x800000008000000A, 0x8000000080008081, |
||||
0x8000000000008080, 0x0000000080000001, 0x8000000080008008 |
||||
]; |
||||
for (var i=0; i<64; i++) { |
||||
out[i] <== (rc[r] >> i) & 1; |
||||
} |
||||
} |
||||
|
||||
template Iota(r) { |
||||
signal input in[25*64]; |
||||
signal output out[25*64]; |
||||
var i; |
||||
|
||||
component rc = RC(r); |
||||
|
||||
component iota = XorArray(64); |
||||
for (var i=0; i<64; i++) { |
||||
iota.a[i] <== in[i]; |
||||
iota.b[i] <== rc.out[i]; |
||||
} |
||||
for (i=0; i<64; i++) { |
||||
out[i] <== iota.out[i]; |
||||
} |
||||
for (i=64; i<25*64; i++) { |
||||
out[i] <== in[i]; |
||||
} |
||||
} |
||||
|
@ -1,115 +0,0 @@ |
||||
pragma circom 2.0.2; |
||||
|
||||
include "circomlib/circuits/gates.circom"; |
||||
include "circomlib/circuits/sha256/xor3.circom"; |
||||
include "circomlib/circuits/sha256/shift.circom"; // contains ShiftRight |
||||
|
||||
template Xor5(n) { |
||||
signal input a[n]; |
||||
signal input b[n]; |
||||
signal input c[n]; |
||||
signal input d[n]; |
||||
signal input e[n]; |
||||
signal output out[n]; |
||||
var i; |
||||
|
||||
component xor3 = Xor3(n); |
||||
for (i=0; i<n; i++) { |
||||
xor3.a[i] <== a[i]; |
||||
xor3.b[i] <== b[i]; |
||||
xor3.c[i] <== c[i]; |
||||
} |
||||
component xor4 = XorArray(n); |
||||
for (i=0; i<n; i++) { |
||||
xor4.a[i] <== xor3.out[i]; |
||||
xor4.b[i] <== d[i]; |
||||
} |
||||
component xor5 = XorArray(n); |
||||
for (i=0; i<n; i++) { |
||||
xor5.a[i] <== xor4.out[i]; |
||||
xor5.b[i] <== e[i]; |
||||
} |
||||
for (i=0; i<n; i++) { |
||||
out[i] <== xor5.out[i]; |
||||
} |
||||
} |
||||
|
||||
template XorArray(n) { |
||||
signal input a[n]; |
||||
signal input b[n]; |
||||
signal output out[n]; |
||||
var i; |
||||
|
||||
component aux[n]; |
||||
for (i=0; i<n; i++) { |
||||
aux[i] = XOR(); |
||||
aux[i].a <== a[i]; |
||||
aux[i].b <== b[i]; |
||||
} |
||||
for (i=0; i<n; i++) { |
||||
out[i] <== aux[i].out; |
||||
} |
||||
} |
||||
|
||||
template XorArraySingle(n) { |
||||
signal input a[n]; |
||||
signal output out[n]; |
||||
var i; |
||||
|
||||
component aux[n]; |
||||
for (i=0; i<n; i++) { |
||||
aux[i] = XOR(); |
||||
aux[i].a <== a[i]; |
||||
aux[i].b <== 1; |
||||
} |
||||
for (i=0; i<n; i++) { |
||||
out[i] <== aux[i].out; |
||||
} |
||||
} |
||||
|
||||
template OrArray(n) { |
||||
signal input a[n]; |
||||
signal input b[n]; |
||||
signal output out[n]; |
||||
var i; |
||||
|
||||
component aux[n]; |
||||
for (i=0; i<n; i++) { |
||||
aux[i] = OR(); |
||||
aux[i].a <== a[i]; |
||||
aux[i].b <== b[i]; |
||||
} |
||||
for (i=0; i<n; i++) { |
||||
out[i] <== aux[i].out; |
||||
} |
||||
} |
||||
|
||||
template AndArray(n) { |
||||
signal input a[n]; |
||||
signal input b[n]; |
||||
signal output out[n]; |
||||
var i; |
||||
|
||||
component aux[n]; |
||||
for (i=0; i<n; i++) { |
||||
aux[i] = AND(); |
||||
aux[i].a <== a[i]; |
||||
aux[i].b <== b[i]; |
||||
} |
||||
for (i=0; i<n; i++) { |
||||
out[i] <== aux[i].out; |
||||
} |
||||
} |
||||
|
||||
template ShL(n, r) { |
||||
signal input in[n]; |
||||
signal output out[n]; |
||||
|
||||
for (var i=0; i<n; i++) { |
||||
if (i < r) { |
||||
out[i] <== 0; |
||||
} else { |
||||
out[i] <== in[ i-r ]; |
||||
} |
||||
} |
||||
} |
@ -1,91 +0,0 @@ |
||||
pragma circom 2.0.2; |
||||
|
||||
include "../vocdoni-keccak/keccak.circom"; |
||||
|
||||
include "circomlib/circuits/bitify.circom"; |
||||
|
||||
/* |
||||
* Possibly generalizable, but for now just flatten a single pubkey from k n-bit chunks to a * single bit array |
||||
* representing the entire pubkey |
||||
* |
||||
*/ |
||||
template FlattenPubkey(numBits, k) { |
||||
signal input chunkedPubkey[2][k]; |
||||
|
||||
signal output pubkeyBits[512]; |
||||
|
||||
// must be able to hold entire pubkey in input |
||||
assert(numBits*k >= 256); |
||||
|
||||
// convert pubkey to a single bit array |
||||
// - concat x and y coords |
||||
// - convert each register's number to corresponding bit array |
||||
// - concatenate all bit arrays in order |
||||
|
||||
component chunks2BitsY[k]; |
||||
for(var chunk = 0; chunk < k; chunk++){ |
||||
chunks2BitsY[chunk] = Num2Bits(numBits); |
||||
chunks2BitsY[chunk].in <== chunkedPubkey[1][chunk]; |
||||
|
||||
for(var bit = 0; bit < numBits; bit++){ |
||||
var bitIndex = bit + numBits * chunk; |
||||
if(bitIndex < 256) { |
||||
pubkeyBits[bitIndex] <== chunks2BitsY[chunk].out[bit]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
component chunks2BitsX[k]; |
||||
for(var chunk = 0; chunk < k; chunk++){ |
||||
chunks2BitsX[chunk] = Num2Bits(numBits); |
||||
chunks2BitsX[chunk].in <== chunkedPubkey[0][chunk]; |
||||
|
||||
for(var bit = 0; bit < numBits; bit++){ |
||||
var bitIndex = bit + 256 + (numBits * chunk); |
||||
if(bitIndex < 512) { |
||||
pubkeyBits[bitIndex] <== chunks2BitsX[chunk].out[bit]; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* |
||||
* Helper for verifying an eth address refers to the correct public key point |
||||
* |
||||
* NOTE: uses https://github.com/vocdoni/keccak256-circom, a highly experimental keccak256 implementation |
||||
*/ |
||||
template PubkeyToAddress() { |
||||
// public key is (x, y) curve point. this is a 512-bit little-endian bitstring representation of y + 2**256 * x |
||||
signal input pubkeyBits[512]; |
||||
|
||||
signal output address; |
||||
|
||||
// our representation is little-endian 512-bit bitstring |
||||
// keccak template operates on bytestrings one byte at a time, starting with the biggest byte |
||||
// but bytes are represented as little-endian 8-bit bitstrings |
||||
signal reverse[512]; |
||||
|
||||
for (var i = 0; i < 512; i++) { |
||||
reverse[i] <== pubkeyBits[511-i]; |
||||
} |
||||
|
||||
component keccak = Keccak(512, 256); |
||||
for (var i = 0; i < 512 / 8; i += 1) { |
||||
for (var j = 0; j < 8; j++) { |
||||
keccak.in[8*i + j] <== reverse[8*i + (7-j)]; |
||||
} |
||||
} |
||||
|
||||
// convert the last 160 bits (20 bytes) into the number corresponding to address |
||||
// the output of keccak is 32 bytes. bytes are arranged from largest to smallest |
||||
// but bytes themselves are little-endian bitstrings of 8 bits |
||||
// we just want a little-endian bitstring of 160 bits |
||||
component bits2Num = Bits2Num(160); |
||||
for (var i = 0; i < 20; i++) { |
||||
for (var j = 0; j < 8; j++) { |
||||
bits2Num.in[8*i + j] <== keccak.out[256 - 8*(i+1) + j]; |
||||
} |
||||
} |
||||
|
||||
address <== bits2Num.out; |
||||
} |
@ -1,48 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
include "../poseidon/poseidon.circom"; |
||||
include "circomlib/circuits/mux1.circom"; |
||||
|
||||
/** |
||||
* MerkleTreeInclusionProof |
||||
* ======================== |
||||
* |
||||
* Copy of the Merkle Tree implementation in Semaphore: |
||||
* https://github.com/semaphore-protocol/semaphore/blob/main/packages/circuits/tree.circom |
||||
* Instead of using the circomlib Poseidon, we use our own implementation which |
||||
* uses constants specific to the secp256k1 curve. |
||||
*/ |
||||
template MerkleTreeInclusionProof(nLevels) { |
||||
signal input leaf; |
||||
signal input pathIndices[nLevels]; |
||||
signal input siblings[nLevels]; |
||||
|
||||
signal output root; |
||||
|
||||
component poseidons[nLevels]; |
||||
component mux[nLevels]; |
||||
|
||||
signal hashes[nLevels + 1]; |
||||
hashes[0] <== leaf; |
||||
|
||||
for (var i = 0; i < nLevels; i++) { |
||||
pathIndices[i] * (1 - pathIndices[i]) === 0; |
||||
|
||||
poseidons[i] = Poseidon(); |
||||
mux[i] = MultiMux1(2); |
||||
|
||||
mux[i].c[0][0] <== hashes[i]; |
||||
mux[i].c[0][1] <== siblings[i]; |
||||
|
||||
mux[i].c[1][0] <== siblings[i]; |
||||
mux[i].c[1][1] <== hashes[i]; |
||||
|
||||
mux[i].s <== pathIndices[i]; |
||||
|
||||
poseidons[i].inputs[0] <== mux[i].out[0]; |
||||
poseidons[i].inputs[1] <== mux[i].out[1]; |
||||
|
||||
hashes[i + 1] <== poseidons[i].out; |
||||
} |
||||
|
||||
root <== hashes[nLevels]; |
||||
} |
@ -1,5 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
include "../eff_ecdsa_membership/addr_membership.circom"; |
||||
|
||||
component main { public[ root, Tx, Ty, Ux, Uy ]} = AddrMembership(20); |
@ -1,5 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
include "../eff_ecdsa_membership/pubkey_membership.circom"; |
||||
|
||||
component main { public[ root, Tx, Ty, Ux, Uy ]} = PubKeyMembership(20); |
@ -1,158 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
include "./poseidon_constants.circom"; |
||||
|
||||
template SBox() { |
||||
signal input in; |
||||
signal output out; |
||||
|
||||
signal inDouble <== in * in; |
||||
signal inQuadruple <== inDouble * inDouble; |
||||
|
||||
|
||||
out <== inQuadruple * in; |
||||
} |
||||
|
||||
template MatrixMul() { |
||||
var t = 3; |
||||
signal input state[t]; |
||||
signal output out[t]; |
||||
var mds_matrix[t][t] = MDS_MATRIX(); |
||||
|
||||
for (var i = 0; i < t; i++) { |
||||
var tmp = 0; |
||||
for (var j = 0; j < t; j++) { |
||||
tmp += state[j] * mds_matrix[i][j]; |
||||
} |
||||
out[i] <== tmp; |
||||
} |
||||
} |
||||
|
||||
template AddRoundConst(pos) { |
||||
var t = 3; |
||||
signal input state[t]; |
||||
signal output out[t]; |
||||
var round_keys[192] = ROUND_KEYS(); |
||||
|
||||
for (var i = 0; i < t; i++) { |
||||
out[i] <== state[i] + round_keys[pos + i]; |
||||
} |
||||
} |
||||
|
||||
template FullRound(pos) { |
||||
var t = 3; |
||||
signal input state[t]; |
||||
signal output out[t]; |
||||
component constAdded = AddRoundConst(pos); |
||||
for (var i = 0; i < t; i++) { |
||||
constAdded.state[i] <== state[i]; |
||||
} |
||||
|
||||
|
||||
component sBoxes[t]; |
||||
for (var i = 0; i < t; i++) { |
||||
sBoxes[i] = SBox(); |
||||
sBoxes[i].in <== constAdded.out[i]; |
||||
} |
||||
|
||||
component matrixMul = MatrixMul(); |
||||
for (var i = 0; i < t; i++) { |
||||
matrixMul.state[i] <== sBoxes[i].out; |
||||
} |
||||
|
||||
for (var i = 0; i < t; i++) { |
||||
out[i] <== matrixMul.out[i]; |
||||
} |
||||
} |
||||
|
||||
template PartialRound(pos) { |
||||
var t = 3; |
||||
signal input state[t]; |
||||
signal output out[t]; |
||||
|
||||
component constAdded = AddRoundConst(pos); |
||||
for (var i = 0; i < t; i++) { |
||||
constAdded.state[i] <== state[i]; |
||||
} |
||||
|
||||
component sBox = SBox(); |
||||
sBox.in <== constAdded.out[0]; |
||||
|
||||
component matrixMul = MatrixMul(); |
||||
for (var i = 0; i < t; i++) { |
||||
if (i == 0) { |
||||
matrixMul.state[i] <== sBox.out; |
||||
} else { |
||||
matrixMul.state[i] <== constAdded.out[i]; |
||||
} |
||||
} |
||||
|
||||
for (var i = 0; i < t; i++) { |
||||
out[i] <== matrixMul.out[i]; |
||||
} |
||||
} |
||||
|
||||
template Poseidon() { |
||||
var numInputs = 2; |
||||
var t = numInputs + 1; |
||||
signal input inputs[numInputs]; |
||||
var numFullRoundsHalf = 4; |
||||
var numPartialRounds = 56; |
||||
signal output out; |
||||
|
||||
var stateIndex = 0; |
||||
|
||||
signal initState[3]; |
||||
|
||||
initState[0] <== 3; |
||||
initState[1] <== inputs[0]; |
||||
initState[2] <== inputs[1]; |
||||
|
||||
component fRoundsFirst[numFullRoundsHalf]; |
||||
for (var j = 0; j < numFullRoundsHalf; j++) { |
||||
fRoundsFirst[j] = FullRound(stateIndex * t); |
||||
if (j == 0) { |
||||
for (var i = 0; i < t; i++) { |
||||
fRoundsFirst[j].state[i] <== initState[i]; |
||||
} |
||||
} else { |
||||
for (var i = 0; i < t; i++) { |
||||
fRoundsFirst[j].state[i] <== fRoundsFirst[j - 1].out[i]; |
||||
} |
||||
} |
||||
stateIndex++; |
||||
} |
||||
|
||||
|
||||
component pRounds[numPartialRounds]; |
||||
for (var j = 0; j < numPartialRounds; j++) { |
||||
pRounds[j] = PartialRound(stateIndex * t); |
||||
if (j == 0) { |
||||
for (var i = 0; i < t; i++) { |
||||
pRounds[j].state[i] <== fRoundsFirst[numFullRoundsHalf - 1].out[i]; |
||||
} |
||||
} else { |
||||
for (var i = 0; i < t; i++) { |
||||
pRounds[j].state[i] <== pRounds[j - 1].out[i]; |
||||
} |
||||
} |
||||
stateIndex++; |
||||
} |
||||
|
||||
component fRoundsLast[numFullRoundsHalf]; |
||||
for (var j = 0; j < numFullRoundsHalf; j++) { |
||||
fRoundsLast[j] = FullRound(stateIndex * t); |
||||
if (j == 0) { |
||||
for (var i = 0; i < t; i++) { |
||||
fRoundsLast[j].state[i] <== pRounds[numPartialRounds - 1].out[i]; |
||||
} |
||||
} else { |
||||
for (var i = 0; i < t; i++) { |
||||
fRoundsLast[j].state[i] <== fRoundsLast[j - 1].out[i]; |
||||
} |
||||
} |
||||
stateIndex++; |
||||
} |
||||
|
||||
out <== fRoundsLast[numFullRoundsHalf-1].out[1]; |
||||
} |
@ -1,218 +0,0 @@ |
||||
pragma circom 2.1.2; |
||||
|
||||
function ROUND_KEYS() { |
||||
return [ |
||||
15180568604901803243989155929934437997245952775071395385994322939386074967328, |
||||
98155933184944822056372510812105826951789406432246960633912199752807271851218, |
||||
32585497418154084368870158853355239726261349829448673320273043226636389078017, |
||||
66713968576806622579829258440960693099797917756640662361943757758980796487698, |
||||
61296025743283504825054745787375839406507895949474930140819919915792438454216, |
||||
64548089412749542282115556935384382035671782881737715696939837764375912217104, |
||||
108421562972909537718478936575770973463273651828765393113349044862621092658552, |
||||
93957623861448681916560847065407918286434708744548934125771289238599801659600, |
||||
31886767595881910145119755249133120645312710313371225820300496900248094187131, |
||||
36511615103248888903406040506250394762206798360602726106046630438239169384653, |
||||
21193239787133737740669439860809806837993750509086389566475677877580362491125, |
||||
15159189447883181997488877417695825734356570617827322308691834229181804753656, |
||||
19272373877630561389686073945290625876718814210798194797601715657476609730306, |
||||
23132197996397121955527964729507651432518694856862854469217474256539272053037, |
||||
9869753235007825662020275771343858285582964429845049469800863115040150206544, |
||||
36536341316285671890133896506951910369952562161551585116256678375995315827743, |
||||
62582239167707347777855528698896708360409296899261565735324151945083720570858, |
||||
96597358901965097853721114962031771931271685249979807653919643952343419105640, |
||||
99475971754252188104003224702005940217163363685728394033034788135108600073953, |
||||
52080483875928847502018688921126796935417602445765802481027972679966274137987, |
||||
101922748752417217354391348649359865075718358385248454632698502400961567227929, |
||||
26980595292132221181330746499613907829041623688147011560382352796984836870749, |
||||
7059991836806083192408106370472821784612460308866802565871813230060135266390, |
||||
19329812920723038526370491239817117039289784665617181727933894076969997926129, |
||||
65570620823578601926240439251563587376966657231502120214692324496443514623818, |
||||
58403733332589349613112270854204921427257113546270812628317365115158685715742, |
||||
45021021211732634759643776743541935700591354899980928498981462362035961745443, |
||||
313468157086800401026946312285365733155132234906935411743639256319782592571, |
||||
101316949793045093761117346380310841944294663456931203380573537653884068660109, |
||||
23683935571424619534194393788101669168630123784066421490798386323411538828592, |
||||
45470730427236677197026094498490008082250264942279323465121581539984407294442, |
||||
48141067373531800337373447278127981363951468257064369512416205750641258258193, |
||||
42554919225040466028330117313396362347164995917041931400909482795914116747618, |
||||
11551941832988244108260444347046942236051939264069344013774353630451796870907, |
||||
60185799182545404739011626517355854847787627814101363386450657535504094743765, |
||||
81823160578900678880708744457872721685515019032370491632046212317701226128393, |
||||
7165646831054215773988859638722974820791178194871546344315162343128362695647, |
||||
75289707601640398424243937567716657896680380639974371761136292031415717685949, |
||||
7150842764562742184396161198129263121409208675362553300851082062734889620953, |
||||
24380904705269761063866540342138412601132455197711667167747524315310027386226, |
||||
9728986075621437350131504894128984146939551938810073671231633620616345344412, |
||||
10579382052089733216628873394134968879891026686695240299956972154694558493896, |
||||
8171994519466002143995890536756742287314780571933910736618431096190430536601, |
||||
30420144259409274775063072923609924427757612539094840146996944760708902708570, |
||||
63962155989812703023698320394024694856871261481871757094333286947755599007133, |
||||
25280070391177856032024336895094721131222985610587247589336316615596140400436, |
||||
15305872319988027006162258914083163651002306183917888172691618513722838997098, |
||||
51545603291342006705870081001071419395633279951502747769141857387796043104608, |
||||
91109680756552587805002537489407348773333405839144382221272597323798859182191, |
||||
72175452855185658158184807496160149169667221240389196996344579971523681433202, |
||||
30361989157454953234766224747536334157139256334148153290771332849307087761025, |
||||
38169634499980959088614671703639492517637815232220682121652135514105493936992, |
||||
49591153263237620796156788742811547511792615129981565620486914545749079774827, |
||||
47403873018260745456113868791119169163627014766514972598212646481717066065016, |
||||
93989849689047144228924801010853106857960399638657695410345207191739048300111, |
||||
10590240512802509131776989274411792739339398409955259174829387591089799115255, |
||||
29183703335869638067547208413224742887766212046438654772943025958628178245227, |
||||
4131650227136944095885036960767735080970262672750406866066212532739784907379, |
||||
43395510588213653537697670365796375057855260611965666448183946252832290017444, |
||||
95246795133940226900907730059125298420936467652619708443128629427116119621152, |
||||
6012209003558496814495903476753006089125143165365334812097313083703216071080, |
||||
26183233284429251459198269925441295879550203824094631575778521083706115817955, |
||||
26058994700533582730528567480051558438548299522338811756875396252016497202713, |
||||
107240485663145290290374164860301805857261278222480421976433215167444496066511, |
||||
84412820763898503096477800002865877536719992495674955119188074297975154406587, |
||||
52386303852182662900790700046090769869460994629239741773176060026198900130384, |
||||
95746062835936512160025091603469309809932540674474329021370075533568318932379, |
||||
22711334660013961010382652754865456251782349529764119853461446587583972054666, |
||||
16959835233095757670013367728627149851239789174357906293937455553277911805495, |
||||
15116421110200928832147360650392633091242147433006813656250997138988179879750, |
||||
107878787525302837370688492081178689950008165750500003692400517211520334656293, |
||||
44210105558575948369921579518078229089923760124167628288943900602376706136436, |
||||
90305995748749060889452130219544332384396626628663475498252761213618628372367, |
||||
104941997925797907872686462815914481945432760720471803254797908465921520138024, |
||||
100036855232527386145662094141100441220151775745916101660987264242446845728894, |
||||
103285582836474146806606752170525767341430483568396209591447274936228630298052, |
||||
82197692939371228160449741709034077803239992888716859217989995857278406253737, |
||||
10040764964044995095453717286623030376397745892179877153575434454090155545240, |
||||
27304226040425863042893623786832369758179176309230053449707879364285977952630, |
||||
42627232144930751842910170221862679057276668485045156742021958050665662768084, |
||||
76972394926916659428228833084621905890924612368412796262119501852346293848159, |
||||
39796921406297542196667238133893946368231540421737718098283349901435707131075, |
||||
14745047092916651495052563068083093689676472592445845983334785004125684263162, |
||||
43421479365783318841667739359312715738029447177150400204380817518608837765863, |
||||
107871536756946365977710326147511195471121248998432910212631960353348700694610, |
||||
39505942243687894211614489736115535754716239859353578295470352855493707198619, |
||||
59676442091621150164811367352362126934419932715789994860508056194143441226580, |
||||
94470526851498636320865653968033227263836954414283116133326109455334870036212, |
||||
15044796858044094866329855531761112645684343559112419720568996573556805975600, |
||||
67157729293641241473980125231288476062565688273917759533572275886277269201651, |
||||
72911083146182058225942884942982388217243826839805061121973109250798137784134, |
||||
102973386186208530972563015865701244407271836208547629083437627219683649557477, |
||||
57485522356347377122696081086816661784954498123948319434326439317393351620564, |
||||
23112275556906805064863694321486306070917598599342299357379251070160695202292, |
||||
107618884362423342584703700349292347754139538760798319916678240538294838342400, |
||||
83961260400031958812820990908241261093246389047082613562825737834833753517337, |
||||
42726953951733266282750892844947149703751388034177248277671157488506520215317, |
||||
39379570934119946602507737250800178347029772561352879974941214627084076473292, |
||||
72203650529122342092280763801468513707870760755235719535090090101623606334441, |
||||
13389660788942842724553143053013919883368472759564135119390935439369513690496, |
||||
101745263541280877725997503552978999350831489463993178838531539940805924817361, |
||||
76849182334465191824607032600721023780793694103840553871800174717760598910761, |
||||
53896256317996838683363773836826653859512780625932638736752563553878867538095, |
||||
24688792501674999263943657175455335814404948006469220532686392550824320454904, |
||||
69132683906595821927803530074656979217668636557563597358799899743174233903941, |
||||
2861982085506615225917620192781928414994576134281371548401916333754363567986, |
||||
37311353286221616083824584705974993449107063556724405440534160586561042968316, |
||||
83718085796857523832195255218519255973031752296424117786202083986118546906913, |
||||
103633177691684814414226251117070754499104739002759424774194851613917008856616, |
||||
84968411062305024171594435878414659990735518025357685215223731503921265946461, |
||||
41865099330909055069143724769818364262362915440371474104937435863183989905059, |
||||
46156624920251322979270606388518884047396423747179340919303543598300663968593, |
||||
64416327466854458915398302811825971539792429791049027619471115285308743811583, |
||||
94942471312481523091911417289540395651121558150571128515230470225155209280585, |
||||
109682618775735319282534546194470743032129102295907200313471041846112653687024, |
||||
61531999191737540795124202104235799899980935519651613893518293245268304980543, |
||||
17797352534596268622733030076742840951214734697361029060619245779495726996632, |
||||
2323150752778983462106829021155031678603044899339819935981200101818542000989, |
||||
16998018904363448507967526489917057882529252665835717172712095240271574074587, |
||||
110634872413902251217040490777568744431854972018399530234679399294372694506842, |
||||
31639545145649753705216327198217551838008233610574104460826956396569310697060, |
||||
107845103764339268987018917144483935480716224058844669233389185480836000033760, |
||||
46240297572174662698030819651333060930818959915797061274854448535534474175039, |
||||
53065607123105696930220421963755520777674094852857308823370049733888025985616, |
||||
16931881300947470270453776207625163368485560075525342751440832370220475352149, |
||||
79254110800481916763656344422402393723573490114487681345184594841431920461089, |
||||
42268569642639492314994307446626647824927989776691987788682655102426770655233, |
||||
9749633319307409894058984489496091535125232227316143918000642155415596066903, |
||||
57606597628648270579042266322415267200058617178318601782866227410456726724976, |
||||
56082250485913115488341301630850455009935943641292622301678990296508134206571, |
||||
17957245764842844288802777667800779232762688847417238921175068882796163705248, |
||||
94356229516444419318132697346021621194464273500135725160277725602263001442644, |
||||
52536631226748676066386651084538409050048707922045928887930261833545619358914, |
||||
107794922118166328243581272159394479176678094739027519706768813902978100436849, |
||||
92984368734102511759118281503078145182557799453616537383408606074187034371208, |
||||
59652553897137603386525572460411404882917571255327541516871354737502335133690, |
||||
49012645345644326995052653072578673750516379655033952006121214224119466671764, |
||||
79025576845143484310735291619293962982804358365838961371044480386743856799994, |
||||
5437377540613244374799729812489584777222423091155743557287567155811057717409, |
||||
100687592213090267900708728796310211082532607828753010566886681655775031329660, |
||||
99074462968857696481475128596339544396152341206708424767062829343406495063192, |
||||
67476872698289965626550204192782761730653024363949045140720348870736942130242, |
||||
103307125141718054130755829916960708430672826104789971350239945481960770107890, |
||||
74087383014714668160537499936376991041273055222568604413015844459913259357334, |
||||
40924049099780965904051946083599822761993164889139026432053420731164022206736, |
||||
32594924940463736641240515015317856157169105212942308502676422036626316673214, |
||||
98990663138035055774586216545398054668349058134877723031747421828753359974443, |
||||
55821766022768786066770462759796825978667805772707620106340033118519147871694, |
||||
4001942224536365489828915551180230767516454384395893814399938353050969198154, |
||||
30136373426492646221252150708518703998248891683881870400906269276900707426865, |
||||
34943205764464817266133164313915763122699935186597909347522822673832250079664, |
||||
27737330737483170511275902246508559278973986181590368845166383812793468814968, |
||||
96292398813565494438359802278723334615526914389306923046282571355958508916558, |
||||
97147334956505986101750230325438660094766812949748276042292963837380833668274, |
||||
24754519562402723848413674701792328284127274989440581643644298347747941238812, |
||||
76111103490248669364580390783887028636436246028943665707064153006971943621186, |
||||
33764090322658516047637223655525551979364055499647855895233821795694749902854, |
||||
100536990630540359004783976190215234627391515555181073681294901127179838732969, |
||||
55991997435987096996680289872758998763908676069536901375395297778729059185671, |
||||
32860959903680178324832991459746631238726690317249285658471597044247794502256, |
||||
70074816806976994707467706079200635184034023598764203123459335544110485476930, |
||||
46213940675829172331116620705134022102338250410334045747023950259088879662946, |
||||
77000624259024986585504351395777746568094934279771127334532438603183524642061, |
||||
21719649576090832101273013788716623377603297433777804572370785470329817725170, |
||||
29209622978540575483991966565508890231057362045066230397327380085945876837821, |
||||
2445742484263083651472035320255578071935687960412507452207899496253120999364, |
||||
86846812580007547526361109808384103509272544750564766849178767957571523649544, |
||||
43025640639926253696325070988523609146060819319830735794100778654425057363895, |
||||
108957662689228031021948854644435971168708642184764962508575441689859324862868, |
||||
83891545396650121758556392255189778590486277180642660527000882403085396114823, |
||||
42527013475786190604202451803064937203698027000671529418992521798122995373551, |
||||
115180194520889678365425151865713593680657747284471744934804370945935167043862, |
||||
28979598171177052880917135045920701144584888536299261666846302083645491369348, |
||||
68351312608110279019109436395199010412431777911149851157132527077210966351650, |
||||
61759623963943995967580147094342313397376358019837276043205235302342147116585, |
||||
80714625408576660514217469096827255752431164791924432025682445176737446783085, |
||||
33048555646676368266608424610100449208381357250300222636992099726804869416731, |
||||
50682223610667325089810868083131721901859473966415125289975106060759036109476, |
||||
4271213571706787092297985431667190050727614825584809797590204884727103716461, |
||||
101314046722405990971733763321368296660561930294000591067108115987088407142646, |
||||
55565500177602146197728150332647093173137211885612327122425918553270191254877, |
||||
65556764608648687291293889343854786421750589271167654521933267288313526422497, |
||||
66877533773422945979143954094644173219583178339199697252673545117318799706373, |
||||
30511098623357801425494143655999121699575856091238269679669864984061501512835, |
||||
95900192636363991637086954986559552472749485926252879461208179855482821976623, |
||||
37879946127489462347049192209554168578320892231852882971030128420645686965013, |
||||
80479504274334215471057938992198620419540634144266821121799003865782336406529, |
||||
13326262422954139210095783388743602482455840337093117010479445267213907605425, |
||||
16047106134611124637925332265703907202779549268127518502853950466090054176776, |
||||
71499356105233640605079063493613576024353801558965221134519779175477723594865, |
||||
28438981751956157476540225984733791304599172905715743025543841239013139121102, |
||||
56066317647068426981453448715118237747130321302262827290362392918472904421147 |
||||
]; |
||||
} |
||||
|
||||
function MDS_MATRIX() { |
||||
return [ |
||||
[ |
||||
92469348809186613947252340883344274339611751744959319352506666082431267346705, |
||||
100938028378191533449096235266991198229563815869344032449592738345766724371160, |
||||
77486311749148948616988559783475694076613010381924638436641318334458515006661 |
||||
], |
||||
[ |
||||
110352262556914082363749654180080464794716701228558638957603951672835474954408, |
||||
27607004873684391669404739690441550149894883072418944161048725383958774443141, |
||||
29671705769502357195586268679831947082918094959101307962374709600277676341325 |
||||
], |
||||
[ |
||||
77762103796341032609398578911486222569419103128091016773380377798879650228751, |
||||
1753012011204964731088925227042671869111026487299375073665493007998674391999, |
||||
70274477372358662369456035572054501601454406272695978931839980644925236550307 |
||||
] |
||||
]; |
||||
} |
@ -1,44 +0,0 @@ |
||||
export default async () => { |
||||
return { |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/secp256k1/add.circom': (await import('raw-loader!./circuits/eff_ecdsa_membership/secp256k1/add.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/secp256k1/double.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/secp256k1/double.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/secp256k1/mul.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/secp256k1/mul.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/to_address/vocdoni-keccak/keccak.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/to_address/vocdoni-keccak/keccak.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/to_address/vocdoni-keccak/permutations.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/to_address/vocdoni-keccak/permutations.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/to_address/vocdoni-keccak/utils.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/to_address/vocdoni-keccak/utils.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/to_address/zk-identity/eth.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/to_address/zk-identity/eth.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/addr_membership.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/addr_membership.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/eff_ecdsa_to_addr.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/eff_ecdsa_to_addr.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/eff_ecdsa.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/eff_ecdsa.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/pubkey_membership.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/pubkey_membership.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/eff_ecdsa_membership/tree.circom': (await import('!!raw-loader!./circuits/eff_ecdsa_membership/tree.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/instances/addr_membership.circom': (await import('!!raw-loader!./circuits/instances/addr_membership.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/instances/pubkey_membership.circom': (await import('!!raw-loader!./circuits/instances/pubkey_membership.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/poseidon/poseidon_constants.circom': (await import('!!raw-loader!./circuits/poseidon/poseidon_constants.circom')).default, |
||||
// @ts-ignore
|
||||
'circuits/poseidon/poseidon.circom': (await import('!!raw-loader!./circuits/poseidon/poseidon.circom')).default, |
||||
// @ts-ignore
|
||||
'scripts/run_setup.ts': (await import('!!raw-loader!./scripts/run_setup.ts')).default, |
||||
// @ts-ignore
|
||||
'scripts/run_verification.ts': (await import('!!raw-loader!./scripts/run_verification.ts')).default, |
||||
// @ts-ignore
|
||||
'templates/groth16_verifier.sol.ejs': (await import('!!raw-loader!./templates/groth16_verifier.sol.ejs')).default, |
||||
// @ts-ignore
|
||||
'README.md': (await import('raw-loader!./README.md')).default |
||||
} |
||||
} |
@ -1,56 +0,0 @@ |
||||
import { ethers, BigNumber } from 'ethers' |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const snarkjs = require('snarkjs'); |
||||
|
||||
(async () => { |
||||
try { |
||||
// @ts-ignore
|
||||
await remix.call('circuit-compiler', 'generateR1cs', 'circuits/instances/pubkey_membership.circom'); |
||||
|
||||
const ptau_final = "https://ipfs-cluster.ethdevops.io/ipfs/QmTiT4eiYz5KF7gQrDsgfCSTRv3wBPYJ4bRN1MmTRshpnW"; |
||||
// @ts-ignore
|
||||
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/instances/.bin/pubkey_membership.r1cs', true); |
||||
// @ts-ignore
|
||||
const r1cs = new Uint8Array(r1csBuffer); |
||||
const zkey_0 = { type: "mem" }; |
||||
const zkey_1 = { type: "mem" }; |
||||
const zkey_final = { type: "mem" }; |
||||
|
||||
console.log('newZkey') |
||||
await snarkjs.zKey.newZKey(r1cs, ptau_final, zkey_0); |
||||
|
||||
console.log('contribute') |
||||
await snarkjs.zKey.contribute(zkey_0, zkey_1, "p2_C1", "pa_Entropy1"); |
||||
|
||||
console.log('beacon') |
||||
await snarkjs.zKey.beacon(zkey_1, zkey_final, "B3", "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", 10); |
||||
|
||||
console.log('verifyFromR1cs') |
||||
const verifyFromR1csResult = await snarkjs.zKey.verifyFromR1cs(r1cs, ptau_final, zkey_final); |
||||
console.assert(verifyFromR1csResult); |
||||
|
||||
console.log('verifyFromInit') |
||||
const verifyFromInit = await snarkjs.zKey.verifyFromInit(zkey_0, ptau_final, zkey_final); |
||||
console.assert(verifyFromInit); |
||||
|
||||
console.log('exportVerificationKey') |
||||
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final) |
||||
await remix.call('fileManager', 'writeFile', './zk/build/verification_key.json', JSON.stringify(vKey)) |
||||
|
||||
const templates = { |
||||
groth16: await remix.call('fileManager', 'readFile', 'templates/groth16_verifier.sol.ejs') |
||||
} |
||||
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates) |
||||
|
||||
await remix.call('fileManager', 'writeFile', './zk/build/zk_verifier.sol', solidityContract) |
||||
|
||||
console.log('buffer', (zkey_final as any).data.length) |
||||
await remix.call('fileManager', 'writeFile', './zk/build/zk_setup.txt', JSON.stringify(Array.from(((zkey_final as any).data)))) |
||||
|
||||
console.log('setup done.') |
||||
|
||||
} catch (e) { |
||||
console.error(e.message) |
||||
} |
||||
})() |
@ -1,122 +0,0 @@ |
||||
// @ts-ignore
|
||||
import { Poseidon, Tree, computeEffEcdsaPubInput } from "@personaelabs/spartan-ecdsa" |
||||
// @ts-ignore
|
||||
import { privateToPublic, hashPersonalMessage, ecsign, utf8ToBytes, bytesToHex } from "@ethereumjs/util" |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const snarkjs = require('snarkjs'); |
||||
|
||||
const logger = { |
||||
info: (...args) => console.log(...args), |
||||
debug: (...args) => console.log(...args), |
||||
error: (...args) => console.error(...args), |
||||
} |
||||
|
||||
function getEffEcdsaCircuitInput (privKey, msg) { |
||||
const msgHash = hashPersonalMessage(msg) |
||||
const { v, r: _r, s } = ecsign(msgHash, privKey) |
||||
const r = BigInt('0x' + _r.map(byte => byte.toString(16).padStart(2, '0')).join('')) |
||||
const circuitPubInput = computeEffEcdsaPubInput(r, v, msgHash) |
||||
|
||||
const input = { |
||||
s: BigInt('0x' + s.map(byte => byte.toString(16).padStart(2, '0')).join('')), |
||||
Tx: circuitPubInput.Tx, |
||||
Ty: circuitPubInput.Ty, |
||||
Ux: circuitPubInput.Ux, |
||||
Uy: circuitPubInput.Uy |
||||
} |
||||
|
||||
return input |
||||
} |
||||
|
||||
(async () => { |
||||
try { |
||||
// @ts-ignore
|
||||
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/instances/.bin/pubkey_membership.r1cs', true) |
||||
// @ts-ignore
|
||||
const r1cs = new Uint8Array(r1csBuffer) |
||||
// @ts-ignore
|
||||
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/instances/.bin/pubkey_membership.wasm', true) |
||||
// @ts-ignore
|
||||
const wasm = new Uint8Array(wasmBuffer) |
||||
|
||||
const zkey_final = { |
||||
type: "mem", |
||||
data: new Uint8Array(JSON.parse(await remix.call('fileManager', 'readFile', './zk/build/zk_setup.txt'))) |
||||
} |
||||
const wtns = { type: "mem" } |
||||
|
||||
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/build/verification_key.json')) |
||||
// Construct the tree
|
||||
const poseidon = new Poseidon() |
||||
|
||||
await poseidon.initWasm() |
||||
|
||||
const nLevels = 10 |
||||
const tree = new Tree(nLevels, poseidon) |
||||
|
||||
console.log('done') |
||||
|
||||
const privKeys = [ |
||||
utf8ToBytes("".padStart(16, "🧙")), |
||||
utf8ToBytes("".padStart(16, "🪄")), |
||||
utf8ToBytes("".padStart(16, "🔮")) |
||||
] |
||||
|
||||
// Store public key hashes
|
||||
const pubKeyHashes: bigint[] = [] |
||||
|
||||
// Compute public key hashes
|
||||
for (const privKey of privKeys) { |
||||
const pubKey = privateToPublic(privKey) |
||||
const pubKeyHex = bytesToHex(pubKey) |
||||
const hexWithoutPrefix = pubKeyHex.startsWith('0x') ? pubKeyHex.slice(2) : pubKeyHex; |
||||
const pubKeyHash = poseidon.hashPubKey(hexWithoutPrefix) |
||||
|
||||
pubKeyHashes.push(pubKeyHash) |
||||
} |
||||
|
||||
// Insert the pubkey hashes into the tree
|
||||
for (const pubKeyHash of pubKeyHashes) { |
||||
tree.insert(pubKeyHash) |
||||
} |
||||
|
||||
// Sign
|
||||
const index = 0; // Use privKeys[0] for proving
|
||||
const privKey = privKeys[index] |
||||
const msg = utf8ToBytes("hello world".padStart(16, " ")) |
||||
|
||||
// Prepare signature proof input
|
||||
const effEcdsaInput = getEffEcdsaCircuitInput(privKey, msg) |
||||
|
||||
const merkleProof = tree.createProof(index) |
||||
|
||||
const signals = { |
||||
...effEcdsaInput, |
||||
siblings: merkleProof.siblings, |
||||
pathIndices: merkleProof.pathIndices, |
||||
root: tree.root() |
||||
} |
||||
|
||||
console.log('signals: ', signals) |
||||
|
||||
console.log('calculate') |
||||
await snarkjs.wtns.calculate(signals, wasm, wtns) |
||||
|
||||
// console.log('check')
|
||||
// await snarkjs.wtns.check(r1cs, wtns, logger)
|
||||
|
||||
|
||||
// console.log('prove')
|
||||
// const { proof, publicSignals } = await snarkjs.groth16.prove(zkey_final, wtns);
|
||||
|
||||
// const verified = await snarkjs.groth16.verify(vKey, publicSignals, proof, logger);
|
||||
// console.log('zk proof validity', verified);
|
||||
// proof1.root.toString() === publicSignals[0] ? console.log('merkle proof valid') : console.log('merkle proof invalid')
|
||||
|
||||
|
||||
|
||||
} catch (e) { |
||||
console.error(e.message) |
||||
} |
||||
})() |
@ -1,165 +0,0 @@ |
||||
// SPDX-License-Identifier: GPL-3.0 |
||||
/* |
||||
Copyright 2021 0KIMS association. |
||||
|
||||
This file is generated with [snarkJS](https://github.com/iden3/snarkjs). |
||||
|
||||
snarkJS is a free software: you can redistribute it and/or modify it |
||||
under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
snarkJS is distributed in the hope that it will be useful, but WITHOUT |
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
||||
License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with snarkJS. If not, see <https://www.gnu.org/licenses/>. |
||||
*/ |
||||
|
||||
pragma solidity >=0.7.0 <0.9.0; |
||||
|
||||
contract Groth16Verifier { |
||||
// Scalar field size |
||||
uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; |
||||
// Base field size |
||||
uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; |
||||
|
||||
// Verification Key data |
||||
uint256 constant alphax = <%= vk_alpha_1[0] %>; |
||||
uint256 constant alphay = <%= vk_alpha_1[1] %>; |
||||
uint256 constant betax1 = <%= vk_beta_2[0][1] %>; |
||||
uint256 constant betax2 = <%= vk_beta_2[0][0] %>; |
||||
uint256 constant betay1 = <%= vk_beta_2[1][1] %>; |
||||
uint256 constant betay2 = <%= vk_beta_2[1][0] %>; |
||||
uint256 constant gammax1 = <%= vk_gamma_2[0][1] %>; |
||||
uint256 constant gammax2 = <%= vk_gamma_2[0][0] %>; |
||||
uint256 constant gammay1 = <%= vk_gamma_2[1][1] %>; |
||||
uint256 constant gammay2 = <%= vk_gamma_2[1][0] %>; |
||||
uint256 constant deltax1 = <%= vk_delta_2[0][1] %>; |
||||
uint256 constant deltax2 = <%= vk_delta_2[0][0] %>; |
||||
uint256 constant deltay1 = <%= vk_delta_2[1][1] %>; |
||||
uint256 constant deltay2 = <%= vk_delta_2[1][0] %>; |
||||
|
||||
<% for (let i=0; i<IC.length; i++) { %> |
||||
uint256 constant IC<%=i%>x = <%=IC[i][0]%>; |
||||
uint256 constant IC<%=i%>y = <%=IC[i][1]%>; |
||||
<% } %> |
||||
|
||||
// Memory data |
||||
uint16 constant pVk = 0; |
||||
uint16 constant pPairing = 128; |
||||
|
||||
uint16 constant pLastMem = 896; |
||||
|
||||
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[<%=IC.length-1%>] calldata _pubSignals) public view returns (bool) { |
||||
assembly { |
||||
function checkField(v) { |
||||
if iszero(lt(v, q)) { |
||||
mstore(0, 0) |
||||
return(0, 0x20) |
||||
} |
||||
} |
||||
|
||||
// G1 function to multiply a G1 value(x,y) to value in an address |
||||
function g1_mulAccC(pR, x, y, s) { |
||||
let success |
||||
let mIn := mload(0x40) |
||||
mstore(mIn, x) |
||||
mstore(add(mIn, 32), y) |
||||
mstore(add(mIn, 64), s) |
||||
|
||||
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64) |
||||
|
||||
if iszero(success) { |
||||
mstore(0, 0) |
||||
return(0, 0x20) |
||||
} |
||||
|
||||
mstore(add(mIn, 64), mload(pR)) |
||||
mstore(add(mIn, 96), mload(add(pR, 32))) |
||||
|
||||
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64) |
||||
|
||||
if iszero(success) { |
||||
mstore(0, 0) |
||||
return(0, 0x20) |
||||
} |
||||
} |
||||
|
||||
function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk { |
||||
let _pPairing := add(pMem, pPairing) |
||||
let _pVk := add(pMem, pVk) |
||||
|
||||
mstore(_pVk, IC0x) |
||||
mstore(add(_pVk, 32), IC0y) |
||||
|
||||
// Compute the linear combination vk_x |
||||
<% for (let i = 1; i <= nPublic; i++) { %> |
||||
g1_mulAccC(_pVk, IC<%=i%>x, IC<%=i%>y, calldataload(add(pubSignals, <%=(i-1)*32%>))) |
||||
<% } %> |
||||
|
||||
// -A |
||||
mstore(_pPairing, calldataload(pA)) |
||||
mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q)) |
||||
|
||||
// B |
||||
mstore(add(_pPairing, 64), calldataload(pB)) |
||||
mstore(add(_pPairing, 96), calldataload(add(pB, 32))) |
||||
mstore(add(_pPairing, 128), calldataload(add(pB, 64))) |
||||
mstore(add(_pPairing, 160), calldataload(add(pB, 96))) |
||||
|
||||
// alpha1 |
||||
mstore(add(_pPairing, 192), alphax) |
||||
mstore(add(_pPairing, 224), alphay) |
||||
|
||||
// beta2 |
||||
mstore(add(_pPairing, 256), betax1) |
||||
mstore(add(_pPairing, 288), betax2) |
||||
mstore(add(_pPairing, 320), betay1) |
||||
mstore(add(_pPairing, 352), betay2) |
||||
|
||||
// vk_x |
||||
mstore(add(_pPairing, 384), mload(add(pMem, pVk))) |
||||
mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32)))) |
||||
|
||||
|
||||
// gamma2 |
||||
mstore(add(_pPairing, 448), gammax1) |
||||
mstore(add(_pPairing, 480), gammax2) |
||||
mstore(add(_pPairing, 512), gammay1) |
||||
mstore(add(_pPairing, 544), gammay2) |
||||
|
||||
// C |
||||
mstore(add(_pPairing, 576), calldataload(pC)) |
||||
mstore(add(_pPairing, 608), calldataload(add(pC, 32))) |
||||
|
||||
// delta2 |
||||
mstore(add(_pPairing, 640), deltax1) |
||||
mstore(add(_pPairing, 672), deltax2) |
||||
mstore(add(_pPairing, 704), deltay1) |
||||
mstore(add(_pPairing, 736), deltay2) |
||||
|
||||
|
||||
let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20) |
||||
|
||||
isOk := and(success, mload(_pPairing)) |
||||
} |
||||
|
||||
let pMem := mload(0x40) |
||||
mstore(0x40, add(pMem, pLastMem)) |
||||
|
||||
// Validate that all evaluations ∈ F |
||||
<% for (let i=0; i<IC.length; i++) { %> |
||||
checkField(calldataload(add(_pubSignals, <%=i*32%>))) |
||||
<% } %> |
||||
|
||||
// Validate all evaluations |
||||
let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) |
||||
|
||||
mstore(0, isValid) |
||||
return(0, 0x20) |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue