diff --git a/zkp/js/integration-test/anon.js b/zkp/js/integration-test/anon.js index d356ef6..76cf9a0 100644 --- a/zkp/js/integration-test/anon.js +++ b/zkp/js/integration-test/anon.js @@ -46,7 +46,7 @@ describe("main circuit tests for Zeto fungible tokens with anonymity without enc receiver.pubKey = keypair.pubKey; }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const inputValues = [15, 100]; const outputValues = [115, 0]; // create two input UTXOs, each has their own salt, but same owner @@ -98,12 +98,34 @@ describe("main circuit tests for Zeto fungible tokens with anonymity without enc ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('inputCommitments', inputCommitments); // console.log('outputCommitments', outputCommitments); // console.log('senderPublicKey', sender.pubKey); // console.log('receiverPublicKey', receiver.pubKey); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log("public signals", publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(100), + salt3, + ...receiver.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === outputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(60000); }); diff --git a/zkp/js/integration-test/anon_enc.js b/zkp/js/integration-test/anon_enc.js index af6c0d8..e879696 100644 --- a/zkp/js/integration-test/anon_enc.js +++ b/zkp/js/integration-test/anon_enc.js @@ -52,7 +52,7 @@ describe("main circuit tests for Zeto fungible tokens with anonymity with encryp receiver.pubKey = keypair.pubKey; }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const inputValues = [115, 0]; const outputValues = [115, 0]; // create two input UTXOs, each has their own salt, but same owner @@ -102,13 +102,35 @@ describe("main circuit tests for Zeto fungible tokens with anonymity with encryp ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('inputCommitments', inputCommitments); // console.log('outputCommitments', outputCommitments); // console.log('senderPublicKey', sender.pubKey); // console.log('receiverPublicKey', receiver.pubKey); // console.log('encryptionNonce', encryptionNonce); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log("publicSignals", publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(100), + salt3, + ...receiver.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === outputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(60000); }); diff --git a/zkp/js/integration-test/anon_enc_nullifier.js b/zkp/js/integration-test/anon_enc_nullifier.js index 521e372..9ff16b2 100644 --- a/zkp/js/integration-test/anon_enc_nullifier.js +++ b/zkp/js/integration-test/anon_enc_nullifier.js @@ -70,7 +70,7 @@ describe("main circuit tests for Zeto fungible tokens with encryption and anonym smtBob = new Merkletree(storage2, true, SMT_HEIGHT); }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const inputValues = [15, 100]; const outputValues = [80, 35]; // create two input UTXOs, each has their own salt, but same owner @@ -166,13 +166,34 @@ describe("main circuit tests for Zeto fungible tokens with encryption and anonym ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('nullifiers', nullifiers); // console.log('inputCommitments', inputCommitments); // console.log('outputCommitments', outputCommitments); // console.log('root', proof1.root.bigInt()); - // console.log('encryptionNonce', encryptionNonce); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log('public signals', publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(100), + salt3, + ...Bob.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === outputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(600000); }); diff --git a/zkp/js/integration-test/anon_enc_nullifier_kyc.js b/zkp/js/integration-test/anon_enc_nullifier_kyc.js index 0f4c210..81e294f 100644 --- a/zkp/js/integration-test/anon_enc_nullifier_kyc.js +++ b/zkp/js/integration-test/anon_enc_nullifier_kyc.js @@ -85,7 +85,7 @@ describe("main circuit tests for Zeto fungible tokens with encryption and anonym await smtKYC.add(identity2, identity2); }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const inputValues = [32, 40]; const outputValues = [20, 52]; @@ -201,14 +201,36 @@ describe("main circuit tests for Zeto fungible tokens with encryption and anonym ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('nullifiers', nullifiers); // console.log('inputCommitments', inputCommitments); // console.log('outputCommitments', outputCommitments); // console.log('utxo root', proof1.root.bigInt()); // console.log('identitiesRoot', proof3.root.bigInt()); // console.log('encryptionNonce', encryptionNonce); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log('public signals', publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(100), + salt3, + ...Bob.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === outputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(600000); }); diff --git a/zkp/js/integration-test/anon_enc_nullifier_non_repudiation.js b/zkp/js/integration-test/anon_enc_nullifier_non_repudiation.js index 21e4271..68438b3 100644 --- a/zkp/js/integration-test/anon_enc_nullifier_non_repudiation.js +++ b/zkp/js/integration-test/anon_enc_nullifier_non_repudiation.js @@ -76,7 +76,7 @@ describe("main circuit tests for Zeto fungible tokens with encryption fro non-re smtBob = new Merkletree(storage2, true, SMT_HEIGHT); }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const inputValues = [15, 100]; const outputValues = [80, 35]; // create two input UTXOs, each has their own salt, but same owner @@ -172,15 +172,36 @@ describe("main circuit tests for Zeto fungible tokens with encryption fro non-re witness, ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('nullifiers', nullifiers); // console.log('inputCommitments', inputCommitments); // console.log('outputCommitments', outputCommitments); // console.log('root', proof1.root.bigInt()); // console.log('encryptionNonce', encryptionNonce); // console.log('authorityPublicKey', Regulator.pubKey); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log('public signals', publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(100), + salt3, + ...Bob.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === outputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(600000); }); diff --git a/zkp/js/integration-test/anon_nullifier.js b/zkp/js/integration-test/anon_nullifier.js index b4782c2..2b6b5a2 100644 --- a/zkp/js/integration-test/anon_nullifier.js +++ b/zkp/js/integration-test/anon_nullifier.js @@ -59,7 +59,7 @@ describe("main circuit tests for Zeto fungible tokens with anonymity using nulli smtBob = new Merkletree(storage2, true, SMT_HEIGHT); }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const inputValues = [15, 100]; const outputValues = [80, 35]; // create two input UTXOs, each has their own salt, but same owner @@ -147,12 +147,34 @@ describe("main circuit tests for Zeto fungible tokens with anonymity using nulli ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('nullifiers', nullifiers); // console.log('inputCommitments', inputCommitments); // console.log('outputCommitments', outputCommitments); // console.log('root', proof1.root.bigInt()); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log('public signals', publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(100), + salt3, + ...Bob.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === outputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(600000); }); diff --git a/zkp/js/integration-test/anon_nullifier_kyc.js b/zkp/js/integration-test/anon_nullifier_kyc.js index 3268202..e7b641c 100644 --- a/zkp/js/integration-test/anon_nullifier_kyc.js +++ b/zkp/js/integration-test/anon_nullifier_kyc.js @@ -74,7 +74,7 @@ describe("main circuit tests for Zeto fungible tokens with anonymity, KYC, using await smtKYC.add(identity2, identity2); }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const inputValues = [32, 40]; const outputValues = [20, 52]; @@ -181,13 +181,35 @@ describe("main circuit tests for Zeto fungible tokens with anonymity, KYC, using ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('nullifiers', nullifiers); // console.log('inputCommitments', inputCommitments); // console.log('outputCommitments', outputCommitments); // console.log('utxo root', proof1.root.bigInt()); // console.log('identitiesRoot', proof3.root.bigInt()); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log('public signals', publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(100), + salt3, + ...Bob.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === outputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(600000); }); diff --git a/zkp/js/integration-test/check_hashes_value.js b/zkp/js/integration-test/check_hashes_value.js index 3a78f7c..cfb69b4 100644 --- a/zkp/js/integration-test/check_hashes_value.js +++ b/zkp/js/integration-test/check_hashes_value.js @@ -32,7 +32,7 @@ describe("check-hashes-value circuit tests", () => { sender.pubKey = keypair.pubKey; }); - it("should return true for valid witness", async () => { + it("should return true for valid witness and false when public signals are tampered", async () => { const outputValues = [200]; // create the output UTXO @@ -73,10 +73,32 @@ describe("check-hashes-value circuit tests", () => { witness, ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); - expect(success, true); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('output commitments', outputCommitments); // console.log('output values', outputValues); - // console.log('public signals', publicSignals); + // console.log("public signals", publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(100), + salt1, + ...sender.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === outputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(20000); }); diff --git a/zkp/js/integration-test/check_inputs_outputs_value.js b/zkp/js/integration-test/check_inputs_outputs_value.js index 6932f75..ff174f2 100644 --- a/zkp/js/integration-test/check_inputs_outputs_value.js +++ b/zkp/js/integration-test/check_inputs_outputs_value.js @@ -46,7 +46,7 @@ describe("check_inputs_outputs_value circuit tests", () => { smtAlice = new Merkletree(storage1, true, SMT_HEIGHT); }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const inputValues = [15, 100]; const outputValues = [35]; @@ -96,12 +96,34 @@ describe("check_inputs_outputs_value circuit tests", () => { ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('nullifiers', nullifiers); // console.log('inputCommitments', inputCommitments); // console.log('outputCommitments', outputCommitments); // console.log('root', proof1.root.bigInt()); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log("public signals", publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(100), + salt3, + ...Alice.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === outputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(600000); }); diff --git a/zkp/js/integration-test/check_nullifier_value.js b/zkp/js/integration-test/check_nullifier_value.js index 3716d01..cf36a79 100644 --- a/zkp/js/integration-test/check_nullifier_value.js +++ b/zkp/js/integration-test/check_nullifier_value.js @@ -52,7 +52,7 @@ describe("check_nullifier_value circuit tests", () => { smtAlice = new Merkletree(storage1, true, SMT_HEIGHT); }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const inputValues = [15, 100]; const outputValues = [35]; @@ -136,12 +136,34 @@ describe("check_nullifier_value circuit tests", () => { ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('nullifiers', nullifiers); // console.log('inputCommitments', inputCommitments); // console.log('outputCommitments', outputCommitments); // console.log('root', proof1.root.bigInt()); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log("public signals", publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(100), + salt3, + ...Alice.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === outputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(600000); }); diff --git a/zkp/js/integration-test/check_nullifiers.js b/zkp/js/integration-test/check_nullifiers.js index 324ee63..1bfb194 100644 --- a/zkp/js/integration-test/check_nullifiers.js +++ b/zkp/js/integration-test/check_nullifiers.js @@ -43,7 +43,7 @@ describe("check-nullifiers circuit tests", () => { receiver.pubKey = keypair.pubKey; }); - it("should generate a valid proof using groth16 that can be verified successfully", async () => { + it("should generate a valid proof using groth16 that can be verified successfully and fail when public signals are tampered", async () => { const inputValues = [15, 100]; // create two input UTXOs, each has their own salt, but same owner @@ -91,7 +91,32 @@ describe("check-nullifiers circuit tests", () => { witness, ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); - expect(success, true); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; + // console.log('nullifiers', nullifiers); + // console.log('inputCommitments', inputCommitments); + // console.log("public signals", publicSignals); + const tamperedOutputHash = poseidonHash4([ + BigInt(100), + salt2, + ...sender.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === inputCommitments[0].toString() + ? tamperedOutputHash + : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(20000); }); diff --git a/zkp/js/integration-test/nf_anon.js b/zkp/js/integration-test/nf_anon.js index 709ad24..f26d735 100644 --- a/zkp/js/integration-test/nf_anon.js +++ b/zkp/js/integration-test/nf_anon.js @@ -45,7 +45,7 @@ describe("main circuit tests for Zeto non-fungible tokens with anonymity without receiver.pubKey = keypair.pubKey; }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const tokenIds = [1001]; const tokenUris = [tokenUriHash("http://ipfs.io/some-file-hash")]; @@ -94,12 +94,33 @@ describe("main circuit tests for Zeto non-fungible tokens with anonymity without ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('inputCommitments', inputCommitments); // console.log('outputCommitments', outputCommitments); // console.log('senderPublicKey', sender.pubKey); // console.log('receiverPublicKey', receiver.pubKey); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log("public signals", publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(9831), + tokenUris[0], + salt3, + ...receiver.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === output1.toString() ? tamperedOutputHash : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(60000); }); diff --git a/zkp/js/integration-test/nf_anon_nullifier.js b/zkp/js/integration-test/nf_anon_nullifier.js index 465fd49..220dd45 100644 --- a/zkp/js/integration-test/nf_anon_nullifier.js +++ b/zkp/js/integration-test/nf_anon_nullifier.js @@ -60,7 +60,7 @@ describe("main circuit tests for Zeto non-fungible tokens with anonymity using n smtBob = new Merkletree(storage2, true, SMT_HEIGHT); }); - it("should generate a valid proof that can be verified successfully", async () => { + it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => { const tokenId = 1001; const tokenUri = tokenUriHash("http://ipfs.io/some-file-hash"); @@ -123,11 +123,32 @@ describe("main circuit tests for Zeto non-fungible tokens with anonymity using n ); console.log("Proving time: ", (Date.now() - startTime) / 1000, "s"); - const success = await groth16.verify(verificationKey, publicSignals, proof); + let verifyResult = await groth16.verify( + verificationKey, + publicSignals, + proof, + ); + expect(verifyResult).to.be.true; // console.log('nullifiers', nullifier1); // console.log('outputCommitments', output1); // console.log('root', proof1.root.bigInt()); - // console.log('publicSignals', publicSignals); - expect(success, true); + // console.log("public signals", publicSignals); + const tamperedOutputHash = poseidonHash([ + BigInt(9831), + tokenUri, + salt3, + ...Bob.pubKey, + ]); + let tamperedPublicSignals = publicSignals.map((ps) => + ps.toString() === output1.toString() ? tamperedOutputHash : ps, + ); + // console.log("tampered public signals", tamperedPublicSignals); + + verifyResult = await groth16.verify( + verificationKey, + tamperedPublicSignals, + proof, + ); + expect(verifyResult).to.be.false; }).timeout(600000); });