Skip to content

Commit

Permalink
merge with main
Browse files Browse the repository at this point in the history
Signed-off-by: Chengxuan Xing <[email protected]>
  • Loading branch information
Chengxuan committed Dec 29, 2024
1 parent 93e568c commit f01f5a6
Show file tree
Hide file tree
Showing 15 changed files with 361 additions and 196 deletions.
32 changes: 31 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,35 @@
"yaml.format.singleQuote": false,
"prettier.enable": true,
"prettier.jsxSingleQuote": false,
"yaml.format.enable": true
"yaml.format.enable": true,
"cSpell.words": [
"babyjub",
"Babyjubjub",
"circom",
"circomlib",
"circomlibjs",
"Commonlib",
"ECDH",
"fflonk",
"Groth",
"iden",
"izeto",
"Jubjub",
"keypair",
"maci",
"merkletree",
"ptau",
"ptaus",
"rapidsnark",
"snarkjs",
"solidityverifier",
"tokenid",
"UTXO",
"UTXOs",
"UUPS",
"verificationkey",
"vkey",
"WTNS",
"zeto"
]
}
2 changes: 1 addition & 1 deletion zkp/circuits/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ When using the groth16 proving system, per-circuit set up ceremony must be condu

### Export the verification key

The verification key is used by verifier code (either offchain with a JS library or onchain with Solidity). This can be derived from the proving key above.
The verification key is used by verifier code (either off-chain with a JS library or onchain with Solidity). This can be derived from the proving key above.

```console
snarkjs zkey export verificationkey ~/proving-keys/CIRCUIT_FILE_NAME.zkey ~/proving-keys/CIRCUIT_FILE_NAME-vkey.json
Expand Down
1 change: 0 additions & 1 deletion zkp/circuits/check_hashes_value.circom
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
// limitations under the License.
pragma circom 2.2.1;

include "./lib/check-positive.circom";
include "./lib/check-hashes.circom";

template checkHashesValue(nOutputs) {
Expand Down
34 changes: 17 additions & 17 deletions zkp/circuits/gen-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,81 +4,81 @@
"anon": {
"ptau": "powersOfTau28_hez_final_13",
"batchPtau": "powersOfTau28_hez_final_15",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"anon_enc": {
"ptau": "powersOfTau28_hez_final_15",
"batchPtau": "powersOfTau28_hez_final_17",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"anon_nullifier": {
"ptau": "powersOfTau28_hez_final_17",
"batchPtau": "powersOfTau28_hez_final_19",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"anon_nullifier_kyc": {
"ptau": "powersOfTau28_hez_final_17",
"batchPtau": "powersOfTau28_hez_final_19",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"anon_enc_nullifier_non_repudiation": {
"ptau": "powersOfTau28_hez_final_17",
"batchPtau": "powersOfTau28_hez_final_19",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"anon_enc_nullifier": {
"ptau": "powersOfTau28_hez_final_17",
"batchPtau": "powersOfTau28_hez_final_19",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"anon_enc_nullifier_kyc": {
"ptau": "powersOfTau28_hez_final_17",
"batchPtau": "powersOfTau28_hez_final_20",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"nf_anon": {
"ptau": "powersOfTau28_hez_final_13",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"nf_anon_nullifier": {
"ptau": "powersOfTau28_hez_final_16",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"check_hashes_value": {
"ptau": "powersOfTau28_hez_final_11",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"check_inputs_outputs_value": {
"ptau": "powersOfTau28_hez_final_13",
"batchPtau": "powersOfTau28_hez_final_14",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"check_nullifiers_value": {
"ptau": "powersOfTau28_hez_final_17",
"batchPtau": "powersOfTau28_hez_final_19",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"check_utxos_owner": {
"ptau": "powersOfTau28_hez_final_13",
"batchPtau": "powersOfTau28_hez_final_14",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"check_utxos_nf_owner": {
"ptau": "powersOfTau28_hez_final_13",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"check_nullifiers_owner": {
"ptau": "powersOfTau28_hez_final_11",
"batchPtau": "powersOfTau28_hez_final_13",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"check_nullifiers_nf_owner": {
"ptau": "powersOfTau28_hez_final_11",
"skipSolidityGenaration": false
"skipSolidityGeneration": false
},
"check_nullifiers": {
"ptau": "powersOfTau28_hez_final_13",
"skipSolidityGenaration": true
"skipSolidityGeneration": true
}
}
}
18 changes: 9 additions & 9 deletions zkp/circuits/gen.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const ptauDownload = process.env.PTAU_DOWNLOAD_PATH || argv.ptauDownloadPath;
const specificCircuits = argv.c;
const verbose = argv.v;
const compileOnly = argv.compileOnly;
const parallelLimit = parseInt(process.env.GEN_CONCURRENCY, 10) || 4; // Default to compile 4 circuits in parallel
const parallelLimit = parseInt(process.env.GEN_CONCURRENCY, 10) || 4; // Default to compile 4 circuits in parallel

// check env vars
if (!circuitsRoot) {
Expand Down Expand Up @@ -105,7 +105,7 @@ const log = (circuit, message) => {
};

// main circuit process logic
const processCircuit = async (circuit, ptau, skipSolidityGenaration) => {
const processCircuit = async (circuit, ptau, skipSolidityGeneration) => {
const circomInput = path.join("./", `${circuit}.circom`);
const ptauFile = path.join(ptauDownload, `${ptau}.ptau`);
const zkeyOutput = path.join(provingKeysRoot, `${circuit}.zkey`);
Expand Down Expand Up @@ -184,7 +184,7 @@ const processCircuit = async (circuit, ptau, skipSolidityGenaration) => {
}
log(circuit, `Exporting verification key`);
const { stdout: vkOut, stderr: vkErr } = await execAsync(
`npx snarkjs zkey export verificationkey ${zkeyOutput} ${path.join(
`npx snarkjs zkey export verification key ${zkeyOutput} ${path.join(
provingKeysRoot,
`${circuit}-vkey.json`,
)}`,
Expand All @@ -197,7 +197,7 @@ const processCircuit = async (circuit, ptau, skipSolidityGenaration) => {
log(circuit, "verification key export error:\n" + vkErr);
}
}
if (skipSolidityGenaration) {
if (skipSolidityGeneration) {
log(circuit, `Skipping solidity verifier generation`);
return;
}
Expand All @@ -212,7 +212,7 @@ const processCircuit = async (circuit, ptau, skipSolidityGenaration) => {
`verifier_${circuit}.sol`,
);
const { stdout: svOut, stderr: svErr } = await execAsync(
`npx snarkjs zkey export solidityverifier ${zkeyOutput} ${solidityFile}`,
`npx snarkjs zkey export solidity verifier ${zkeyOutput} ${solidityFile}`,
);
if (verbose) {
if (svOut) {
Expand Down Expand Up @@ -257,14 +257,14 @@ const run = async () => {

for (const [
circuit,
{ ptau, skipSolidityGenaration, batchPtau },
{ ptau, skipSolidityGeneration, batchPtau },
] of circuitsArray) {
if (onlyCircuits && !onlyCircuits.includes(circuit)) {
continue;
}

let snarkjsVersion;
// first check cirom version and snarkjs version matches the one in the package.json
// first check circom version and snarkjs version matches the one in the package.json
try {
const { stdout: circomVersion } = await execAsync("circom --version");
// Trigger error to get snarkjs version
Expand Down Expand Up @@ -316,7 +316,7 @@ const run = async () => {
process.exit(1);
}

const pcPromise = processCircuit(circuit, ptau, skipSolidityGenaration);
const pcPromise = processCircuit(circuit, ptau, skipSolidityGeneration);
activePromises.add(pcPromise);

if (activePromises.size >= parallelLimit) {
Expand All @@ -327,7 +327,7 @@ const run = async () => {
const pcBatchPromise = processCircuit(
circuit + "_batch",
batchPtau,
skipSolidityGenaration,
skipSolidityGeneration,
);
activePromises.add(pcBatchPromise);

Expand Down
63 changes: 45 additions & 18 deletions zkp/js/integration-test/check_nullifiers_owner.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,33 @@
// See the License for the specific language governing permissions and
// limitations under the License.

const { expect } = require('chai');
const { groth16 } = require('snarkjs');
const { genKeypair, formatPrivKeyForBabyJub } = require('maci-crypto');
const { Poseidon, newSalt, loadCircuit } = require('../index.js');
const { loadProvingKeys } = require('./utils.js');
const { expect } = require("chai");
const { groth16 } = require("snarkjs");
const { genKeypair, formatPrivKeyForBabyJub } = require("maci-crypto");
const { Poseidon, newSalt, loadCircuit } = require("../index.js");
const { loadProvingKeys } = require("./utils.js");

const poseidonHash3 = Poseidon.poseidon3;

describe('check_nullifiers_owner circuit tests', () => {
describe("check_nullifiers_owner circuit tests", () => {
let circuit, provingKeyFile, verificationKey;

const Alice = {};
let senderPrivateKey;

before(async () => {
circuit = await loadCircuit('check_nullifiers_owner');
({ provingKeyFile, verificationKey } = loadProvingKeys('check_nullifiers_owner'));
circuit = await loadCircuit("check_nullifiers_owner");
({ provingKeyFile, verificationKey } = loadProvingKeys(
"check_nullifiers_owner",
));

let keypair = genKeypair();
Alice.privKey = keypair.privKey;
Alice.pubKey = keypair.pubKey;
senderPrivateKey = formatPrivKeyForBabyJub(Alice.privKey);
});

it('should generate a valid proof that can be verified successfully and fail when public signals are tampered', async () => {
it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => {
const values = [15, 100];

// create two input UTXOs, each has their own salt, but same owner
Expand All @@ -47,8 +49,16 @@ describe('check_nullifiers_owner circuit tests', () => {
const salt2 = newSalt();

// create the nullifiers for the input UTXOs
const nullifier1 = poseidonHash3([BigInt(values[0]), salt1, senderPrivateKey]);
const nullifier2 = poseidonHash3([BigInt(values[1]), salt2, senderPrivateKey]);
const nullifier1 = poseidonHash3([
BigInt(values[0]),
salt1,
senderPrivateKey,
]);
const nullifier2 = poseidonHash3([
BigInt(values[1]),
salt2,
senderPrivateKey,
]);
const nullifiers = [nullifier1, nullifier2];

const startTime = Date.now();
Expand All @@ -59,18 +69,35 @@ describe('check_nullifiers_owner circuit tests', () => {
salts: [salt1, salt2],
ownerPrivateKey: senderPrivateKey,
},
true
true,
);

const { proof, publicSignals } = await groth16.prove(provingKeyFile, witness);
console.log('Proving time: ', (Date.now() - startTime) / 1000, 's');
const { proof, publicSignals } = await groth16.prove(
provingKeyFile,
witness,
);
console.log("Proving time: ", (Date.now() - startTime) / 1000, "s");

let verifyResult = await groth16.verify(verificationKey, publicSignals, proof);
let verifyResult = await groth16.verify(
verificationKey,
publicSignals,
proof,
);
expect(verifyResult).to.be.true;
const tamperedNullifier = poseidonHash3([BigInt(values[0] + 1), salt1, senderPrivateKey]);
let tamperedPublicSignals = publicSignals.map((ps) => (ps.toString() === nullifiers[0].toString() ? tamperedNullifier : ps));
const tamperedNullifier = poseidonHash3([
BigInt(values[0] + 1),
salt1,
senderPrivateKey,
]);
let tamperedPublicSignals = publicSignals.map((ps) =>
ps.toString() === nullifiers[0].toString() ? tamperedNullifier : ps,
);

verifyResult = await groth16.verify(verificationKey, tamperedPublicSignals, proof);
verifyResult = await groth16.verify(
verificationKey,
tamperedPublicSignals,
proof,
);
expect(verifyResult).to.be.false;
}).timeout(600000);
});
23 changes: 5 additions & 18 deletions zkp/js/integration-test/check_utxos_owner.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ const { Poseidon, newSalt, loadCircuit } = require("../index.js");
const { loadProvingKeys } = require("./utils.js");

const poseidonHash = Poseidon.poseidon4;
const poseidonHash3 = Poseidon.poseidon3;

describe("check_utxos_owner circuit tests", () => {
let circuit, provingKeyFile, verificationKey, smtAlice;

Expand All @@ -31,9 +29,8 @@ describe("check_utxos_owner circuit tests", () => {

before(async () => {
circuit = await loadCircuit("check_utxos_owner");
({ provingKeyFile, verificationKey } = loadProvingKeys(
"check_utxos_owner",
));
({ provingKeyFile, verificationKey } =
loadProvingKeys("check_utxos_owner"));

let keypair = genKeypair();
Alice.privKey = keypair.privKey;
Expand All @@ -47,17 +44,9 @@ describe("check_utxos_owner circuit tests", () => {
// create two input UTXOs, each has their own salt, but same owner
const senderPrivateKey = formatPrivKeyForBabyJub(Alice.privKey);
const salt1 = newSalt();
const input1 = poseidonHash([
BigInt(values[0]),
salt1,
...Alice.pubKey,
]);
const input1 = poseidonHash([BigInt(values[0]), salt1, ...Alice.pubKey]);
const salt2 = newSalt();
const input2 = poseidonHash([
BigInt(values[1]),
salt2,
...Alice.pubKey,
]);
const input2 = poseidonHash([BigInt(values[1]), salt2, ...Alice.pubKey]);
const commitments = [input1, input2];

const startTime = Date.now();
Expand Down Expand Up @@ -94,9 +83,7 @@ describe("check_utxos_owner circuit tests", () => {
...Alice.pubKey,
]);
let tamperedPublicSignals = publicSignals.map((ps) =>
ps.toString() === commitments[0].toString()
? tamperedCommitment
: ps,
ps.toString() === commitments[0].toString() ? tamperedCommitment : ps,
);

verifyResult = await groth16.verify(
Expand Down
Loading

0 comments on commit f01f5a6

Please sign in to comment.