Skip to content

Commit edb7252

Browse files
authored
Merge pull request #96 from hyperledger-labs/pub-sig-tamper-test
adding tests for public signal tampering
2 parents e9ff695 + b11b05e commit edb7252

13 files changed

+338
-53
lines changed

zkp/js/integration-test/anon.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe("main circuit tests for Zeto fungible tokens with anonymity without enc
4646
receiver.pubKey = keypair.pubKey;
4747
});
4848

49-
it("should generate a valid proof that can be verified successfully", async () => {
49+
it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => {
5050
const inputValues = [15, 100];
5151
const outputValues = [115, 0];
5252
// 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
9898
);
9999
console.log("Proving time: ", (Date.now() - startTime) / 1000, "s");
100100

101-
const success = await groth16.verify(verificationKey, publicSignals, proof);
101+
let verifyResult = await groth16.verify(
102+
verificationKey,
103+
publicSignals,
104+
proof,
105+
);
106+
expect(verifyResult).to.be.true;
102107
// console.log('inputCommitments', inputCommitments);
103108
// console.log('outputCommitments', outputCommitments);
104109
// console.log('senderPublicKey', sender.pubKey);
105110
// console.log('receiverPublicKey', receiver.pubKey);
106-
// console.log('publicSignals', publicSignals);
107-
expect(success, true);
111+
// console.log("public signals", publicSignals);
112+
const tamperedOutputHash = poseidonHash([
113+
BigInt(100),
114+
salt3,
115+
...receiver.pubKey,
116+
]);
117+
let tamperedPublicSignals = publicSignals.map((ps) =>
118+
ps.toString() === outputCommitments[0].toString()
119+
? tamperedOutputHash
120+
: ps,
121+
);
122+
// console.log("tampered public signals", tamperedPublicSignals);
123+
124+
verifyResult = await groth16.verify(
125+
verificationKey,
126+
tamperedPublicSignals,
127+
proof,
128+
);
129+
expect(verifyResult).to.be.false;
108130
}).timeout(60000);
109131
});

zkp/js/integration-test/anon_enc.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ describe("main circuit tests for Zeto fungible tokens with anonymity with encryp
5252
receiver.pubKey = keypair.pubKey;
5353
});
5454

55-
it("should generate a valid proof that can be verified successfully", async () => {
55+
it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => {
5656
const inputValues = [115, 0];
5757
const outputValues = [115, 0];
5858
// 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
102102
);
103103
console.log("Proving time: ", (Date.now() - startTime) / 1000, "s");
104104

105-
const success = await groth16.verify(verificationKey, publicSignals, proof);
105+
let verifyResult = await groth16.verify(
106+
verificationKey,
107+
publicSignals,
108+
proof,
109+
);
110+
expect(verifyResult).to.be.true;
106111
// console.log('inputCommitments', inputCommitments);
107112
// console.log('outputCommitments', outputCommitments);
108113
// console.log('senderPublicKey', sender.pubKey);
109114
// console.log('receiverPublicKey', receiver.pubKey);
110115
// console.log('encryptionNonce', encryptionNonce);
111-
// console.log('publicSignals', publicSignals);
112-
expect(success, true);
116+
// console.log("publicSignals", publicSignals);
117+
const tamperedOutputHash = poseidonHash([
118+
BigInt(100),
119+
salt3,
120+
...receiver.pubKey,
121+
]);
122+
let tamperedPublicSignals = publicSignals.map((ps) =>
123+
ps.toString() === outputCommitments[0].toString()
124+
? tamperedOutputHash
125+
: ps,
126+
);
127+
// console.log("tampered public signals", tamperedPublicSignals);
128+
129+
verifyResult = await groth16.verify(
130+
verificationKey,
131+
tamperedPublicSignals,
132+
proof,
133+
);
134+
expect(verifyResult).to.be.false;
113135
}).timeout(60000);
114136
});

zkp/js/integration-test/anon_enc_nullifier.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ describe("main circuit tests for Zeto fungible tokens with encryption and anonym
7070
smtBob = new Merkletree(storage2, true, SMT_HEIGHT);
7171
});
7272

73-
it("should generate a valid proof that can be verified successfully", async () => {
73+
it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => {
7474
const inputValues = [15, 100];
7575
const outputValues = [80, 35];
7676
// 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
166166
);
167167
console.log("Proving time: ", (Date.now() - startTime) / 1000, "s");
168168

169-
const success = await groth16.verify(verificationKey, publicSignals, proof);
169+
let verifyResult = await groth16.verify(
170+
verificationKey,
171+
publicSignals,
172+
proof,
173+
);
174+
expect(verifyResult).to.be.true;
170175
// console.log('nullifiers', nullifiers);
171176
// console.log('inputCommitments', inputCommitments);
172177
// console.log('outputCommitments', outputCommitments);
173178
// console.log('root', proof1.root.bigInt());
174-
// console.log('encryptionNonce', encryptionNonce);
175-
// console.log('publicSignals', publicSignals);
176-
expect(success, true);
179+
// console.log('public signals', publicSignals);
180+
const tamperedOutputHash = poseidonHash([
181+
BigInt(100),
182+
salt3,
183+
...Bob.pubKey,
184+
]);
185+
let tamperedPublicSignals = publicSignals.map((ps) =>
186+
ps.toString() === outputCommitments[0].toString()
187+
? tamperedOutputHash
188+
: ps,
189+
);
190+
// console.log("tampered public signals", tamperedPublicSignals);
191+
192+
verifyResult = await groth16.verify(
193+
verificationKey,
194+
tamperedPublicSignals,
195+
proof,
196+
);
197+
expect(verifyResult).to.be.false;
177198
}).timeout(600000);
178199
});

zkp/js/integration-test/anon_enc_nullifier_kyc.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ describe("main circuit tests for Zeto fungible tokens with encryption and anonym
8585
await smtKYC.add(identity2, identity2);
8686
});
8787

88-
it("should generate a valid proof that can be verified successfully", async () => {
88+
it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => {
8989
const inputValues = [32, 40];
9090
const outputValues = [20, 52];
9191

@@ -201,14 +201,36 @@ describe("main circuit tests for Zeto fungible tokens with encryption and anonym
201201
);
202202
console.log("Proving time: ", (Date.now() - startTime) / 1000, "s");
203203

204-
const success = await groth16.verify(verificationKey, publicSignals, proof);
204+
let verifyResult = await groth16.verify(
205+
verificationKey,
206+
publicSignals,
207+
proof,
208+
);
209+
expect(verifyResult).to.be.true;
205210
// console.log('nullifiers', nullifiers);
206211
// console.log('inputCommitments', inputCommitments);
207212
// console.log('outputCommitments', outputCommitments);
208213
// console.log('utxo root', proof1.root.bigInt());
209214
// console.log('identitiesRoot', proof3.root.bigInt());
210215
// console.log('encryptionNonce', encryptionNonce);
211-
// console.log('publicSignals', publicSignals);
212-
expect(success, true);
216+
// console.log('public signals', publicSignals);
217+
const tamperedOutputHash = poseidonHash([
218+
BigInt(100),
219+
salt3,
220+
...Bob.pubKey,
221+
]);
222+
let tamperedPublicSignals = publicSignals.map((ps) =>
223+
ps.toString() === outputCommitments[0].toString()
224+
? tamperedOutputHash
225+
: ps,
226+
);
227+
// console.log("tampered public signals", tamperedPublicSignals);
228+
229+
verifyResult = await groth16.verify(
230+
verificationKey,
231+
tamperedPublicSignals,
232+
proof,
233+
);
234+
expect(verifyResult).to.be.false;
213235
}).timeout(600000);
214236
});

zkp/js/integration-test/anon_enc_nullifier_non_repudiation.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ describe("main circuit tests for Zeto fungible tokens with encryption fro non-re
7676
smtBob = new Merkletree(storage2, true, SMT_HEIGHT);
7777
});
7878

79-
it("should generate a valid proof that can be verified successfully", async () => {
79+
it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => {
8080
const inputValues = [15, 100];
8181
const outputValues = [80, 35];
8282
// 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
172172
witness,
173173
);
174174
console.log("Proving time: ", (Date.now() - startTime) / 1000, "s");
175-
176-
const success = await groth16.verify(verificationKey, publicSignals, proof);
175+
let verifyResult = await groth16.verify(
176+
verificationKey,
177+
publicSignals,
178+
proof,
179+
);
180+
expect(verifyResult).to.be.true;
177181
// console.log('nullifiers', nullifiers);
178182
// console.log('inputCommitments', inputCommitments);
179183
// console.log('outputCommitments', outputCommitments);
180184
// console.log('root', proof1.root.bigInt());
181185
// console.log('encryptionNonce', encryptionNonce);
182186
// console.log('authorityPublicKey', Regulator.pubKey);
183-
// console.log('publicSignals', publicSignals);
184-
expect(success, true);
187+
// console.log('public signals', publicSignals);
188+
const tamperedOutputHash = poseidonHash([
189+
BigInt(100),
190+
salt3,
191+
...Bob.pubKey,
192+
]);
193+
let tamperedPublicSignals = publicSignals.map((ps) =>
194+
ps.toString() === outputCommitments[0].toString()
195+
? tamperedOutputHash
196+
: ps,
197+
);
198+
// console.log("tampered public signals", tamperedPublicSignals);
199+
200+
verifyResult = await groth16.verify(
201+
verificationKey,
202+
tamperedPublicSignals,
203+
proof,
204+
);
205+
expect(verifyResult).to.be.false;
185206
}).timeout(600000);
186207
});

zkp/js/integration-test/anon_nullifier.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ describe("main circuit tests for Zeto fungible tokens with anonymity using nulli
5959
smtBob = new Merkletree(storage2, true, SMT_HEIGHT);
6060
});
6161

62-
it("should generate a valid proof that can be verified successfully", async () => {
62+
it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => {
6363
const inputValues = [15, 100];
6464
const outputValues = [80, 35];
6565
// 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
147147
);
148148
console.log("Proving time: ", (Date.now() - startTime) / 1000, "s");
149149

150-
const success = await groth16.verify(verificationKey, publicSignals, proof);
150+
let verifyResult = await groth16.verify(
151+
verificationKey,
152+
publicSignals,
153+
proof,
154+
);
155+
expect(verifyResult).to.be.true;
151156
// console.log('nullifiers', nullifiers);
152157
// console.log('inputCommitments', inputCommitments);
153158
// console.log('outputCommitments', outputCommitments);
154159
// console.log('root', proof1.root.bigInt());
155-
// console.log('publicSignals', publicSignals);
156-
expect(success, true);
160+
// console.log('public signals', publicSignals);
161+
const tamperedOutputHash = poseidonHash([
162+
BigInt(100),
163+
salt3,
164+
...Bob.pubKey,
165+
]);
166+
let tamperedPublicSignals = publicSignals.map((ps) =>
167+
ps.toString() === outputCommitments[0].toString()
168+
? tamperedOutputHash
169+
: ps,
170+
);
171+
// console.log("tampered public signals", tamperedPublicSignals);
172+
173+
verifyResult = await groth16.verify(
174+
verificationKey,
175+
tamperedPublicSignals,
176+
proof,
177+
);
178+
expect(verifyResult).to.be.false;
157179
}).timeout(600000);
158180
});

zkp/js/integration-test/anon_nullifier_kyc.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ describe("main circuit tests for Zeto fungible tokens with anonymity, KYC, using
7474
await smtKYC.add(identity2, identity2);
7575
});
7676

77-
it("should generate a valid proof that can be verified successfully", async () => {
77+
it("should generate a valid proof that can be verified successfully and fail when public signals are tampered", async () => {
7878
const inputValues = [32, 40];
7979
const outputValues = [20, 52];
8080

@@ -181,13 +181,35 @@ describe("main circuit tests for Zeto fungible tokens with anonymity, KYC, using
181181
);
182182
console.log("Proving time: ", (Date.now() - startTime) / 1000, "s");
183183

184-
const success = await groth16.verify(verificationKey, publicSignals, proof);
184+
let verifyResult = await groth16.verify(
185+
verificationKey,
186+
publicSignals,
187+
proof,
188+
);
189+
expect(verifyResult).to.be.true;
185190
// console.log('nullifiers', nullifiers);
186191
// console.log('inputCommitments', inputCommitments);
187192
// console.log('outputCommitments', outputCommitments);
188193
// console.log('utxo root', proof1.root.bigInt());
189194
// console.log('identitiesRoot', proof3.root.bigInt());
190-
// console.log('publicSignals', publicSignals);
191-
expect(success, true);
195+
// console.log('public signals', publicSignals);
196+
const tamperedOutputHash = poseidonHash([
197+
BigInt(100),
198+
salt3,
199+
...Bob.pubKey,
200+
]);
201+
let tamperedPublicSignals = publicSignals.map((ps) =>
202+
ps.toString() === outputCommitments[0].toString()
203+
? tamperedOutputHash
204+
: ps,
205+
);
206+
// console.log("tampered public signals", tamperedPublicSignals);
207+
208+
verifyResult = await groth16.verify(
209+
verificationKey,
210+
tamperedPublicSignals,
211+
proof,
212+
);
213+
expect(verifyResult).to.be.false;
192214
}).timeout(600000);
193215
});

zkp/js/integration-test/check_hashes_value.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe("check-hashes-value circuit tests", () => {
3232
sender.pubKey = keypair.pubKey;
3333
});
3434

35-
it("should return true for valid witness", async () => {
35+
it("should return true for valid witness and false when public signals are tampered", async () => {
3636
const outputValues = [200];
3737

3838
// create the output UTXO
@@ -73,10 +73,32 @@ describe("check-hashes-value circuit tests", () => {
7373
witness,
7474
);
7575
console.log("Proving time: ", (Date.now() - startTime) / 1000, "s");
76-
const success = await groth16.verify(verificationKey, publicSignals, proof);
77-
expect(success, true);
76+
let verifyResult = await groth16.verify(
77+
verificationKey,
78+
publicSignals,
79+
proof,
80+
);
81+
expect(verifyResult).to.be.true;
7882
// console.log('output commitments', outputCommitments);
7983
// console.log('output values', outputValues);
80-
// console.log('public signals', publicSignals);
84+
// console.log("public signals", publicSignals);
85+
const tamperedOutputHash = poseidonHash([
86+
BigInt(100),
87+
salt1,
88+
...sender.pubKey,
89+
]);
90+
let tamperedPublicSignals = publicSignals.map((ps) =>
91+
ps.toString() === outputCommitments[0].toString()
92+
? tamperedOutputHash
93+
: ps,
94+
);
95+
// console.log("tampered public signals", tamperedPublicSignals);
96+
97+
verifyResult = await groth16.verify(
98+
verificationKey,
99+
tamperedPublicSignals,
100+
proof,
101+
);
102+
expect(verifyResult).to.be.false;
81103
}).timeout(20000);
82104
});

0 commit comments

Comments
 (0)