Skip to content

Commit d671d30

Browse files
committed
Increase the size of the deposit output to 2 for better tracking-resistance
Signed-off-by: Jim Zhang <jim.zhang@kaleido.io>
1 parent 9855999 commit d671d30

19 files changed

+170
-141
lines changed

solidity/contracts/lib/zeto_fungible.sol

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,16 @@ abstract contract ZetoFungible is OwnableUpgradeable {
4545

4646
function _deposit(
4747
uint256 amount,
48-
uint256 utxo,
48+
uint256[] memory outputs,
4949
Commonlib.Proof calldata proof
5050
) public virtual {
5151
// verifies that the output UTXOs match the claimed value
5252
// to be deposited
5353
// construct the public inputs
54-
uint256[2] memory publicInputs;
54+
uint256[3] memory publicInputs;
5555
publicInputs[0] = amount;
56-
publicInputs[1] = utxo;
56+
publicInputs[1] = outputs[0];
57+
publicInputs[2] = outputs[1];
5758

5859
// Check the proof
5960
require(

solidity/contracts/zeto_anon.sol

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,12 @@ contract Zeto_Anon is IZeto, ZetoBase, ZetoFungibleWithdraw, UUPSUpgradeable {
170170

171171
function deposit(
172172
uint256 amount,
173-
uint256 utxo,
173+
uint256[] memory outputs,
174174
Commonlib.Proof calldata proof,
175175
bytes calldata data
176176
) public {
177-
_deposit(amount, utxo, proof);
178-
uint256[] memory utxos = new uint256[](1);
179-
utxos[0] = utxo;
180-
_mint(utxos, data);
177+
_deposit(amount, outputs, proof);
178+
_mint(outputs, data);
181179
}
182180

183181
function withdraw(

solidity/contracts/zeto_anon_enc.sol

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,14 +208,12 @@ contract Zeto_AnonEnc is
208208

209209
function deposit(
210210
uint256 amount,
211-
uint256 utxo,
211+
uint256[] memory outputs,
212212
Commonlib.Proof calldata proof,
213213
bytes calldata data
214214
) public {
215-
_deposit(amount, utxo, proof);
216-
uint256[] memory utxos = new uint256[](1);
217-
utxos[0] = utxo;
218-
_mint(utxos, data);
215+
_deposit(amount, outputs, proof);
216+
_mint(outputs, data);
219217
}
220218

221219
function withdraw(

solidity/contracts/zeto_anon_enc_nullifier.sol

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,12 @@ contract Zeto_AnonEncNullifier is
223223

224224
function deposit(
225225
uint256 amount,
226-
uint256 utxo,
226+
uint256[] memory outputs,
227227
Commonlib.Proof calldata proof,
228228
bytes calldata data
229229
) public {
230-
_deposit(amount, utxo, proof);
231-
uint256[] memory utxos = new uint256[](1);
232-
utxos[0] = utxo;
233-
_mint(utxos, data);
230+
_deposit(amount, outputs, proof);
231+
_mint(outputs, data);
234232
}
235233

236234
function withdraw(

solidity/contracts/zeto_anon_enc_nullifier_kyc.sol

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,14 +238,12 @@ contract Zeto_AnonEncNullifierKyc is
238238
// Therefore, token circulation from & to parties that are not in the KYC list is prevented
239239
function deposit(
240240
uint256 amount,
241-
uint256 utxo,
241+
uint256[] memory outputs,
242242
Commonlib.Proof calldata proof,
243243
bytes calldata data
244244
) public {
245-
_deposit(amount, utxo, proof);
246-
uint256[] memory utxos = new uint256[](1);
247-
utxos[0] = utxo;
248-
_mint(utxos, data);
245+
_deposit(amount, outputs, proof);
246+
_mint(outputs, data);
249247
}
250248

251249
function withdraw(

solidity/contracts/zeto_anon_enc_nullifier_non_repudiation.sol

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,14 +274,12 @@ contract Zeto_AnonEncNullifierNonRepudiation is
274274

275275
function deposit(
276276
uint256 amount,
277-
uint256 utxo,
277+
uint256[] memory outputs,
278278
Commonlib.Proof calldata proof,
279279
bytes calldata data
280280
) public {
281-
_deposit(amount, utxo, proof);
282-
uint256[] memory utxos = new uint256[](1);
283-
utxos[0] = utxo;
284-
_mint(utxos, data);
281+
_deposit(amount, outputs, proof);
282+
_mint(outputs, data);
285283
}
286284

287285
function withdraw(

solidity/contracts/zeto_anon_nullifier.sol

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,12 @@ contract Zeto_AnonNullifier is
192192

193193
function deposit(
194194
uint256 amount,
195-
uint256 utxo,
195+
uint256[] memory outputs,
196196
Commonlib.Proof calldata proof,
197197
bytes calldata data
198198
) public {
199-
_deposit(amount, utxo, proof);
200-
uint256[] memory utxos = new uint256[](1);
201-
utxos[0] = utxo;
202-
_mint(utxos, data);
199+
_deposit(amount, outputs, proof);
200+
_mint(outputs, data);
203201
}
204202

205203
function withdraw(

solidity/contracts/zeto_anon_nullifier_kyc.sol

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,12 @@ contract Zeto_AnonNullifierKyc is
202202

203203
function deposit(
204204
uint256 amount,
205-
uint256 utxo,
205+
uint256[] memory outputs,
206206
Commonlib.Proof calldata proof,
207207
bytes calldata data
208208
) public {
209-
_deposit(amount, utxo, proof);
210-
uint256[] memory utxos = new uint256[](1);
211-
utxos[0] = utxo;
212-
_mint(utxos, data);
209+
_deposit(amount, outputs, proof);
210+
_mint(outputs, data);
213211
}
214212

215213
function withdraw(

solidity/test/utils.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,27 @@ export function loadProvingKeys(type: string) {
4242
};
4343
}
4444

45-
export async function prepareDepositProof(signer: User, output: UTXO) {
46-
const outputCommitments: [BigNumberish] = [output.hash] as [BigNumberish];
47-
const outputValues = [BigInt(output.value || 0n)];
48-
const outputOwnerPublicKeys: [[BigNumberish, BigNumberish]] = [
49-
signer.babyJubPublicKey,
50-
] as [[BigNumberish, BigNumberish]];
45+
export async function prepareDepositProof(signer: User, outputs: [UTXO, UTXO]) {
46+
const outputCommitments: [BigNumberish, BigNumberish] = [
47+
outputs[0].hash,
48+
outputs[1].hash,
49+
] as [BigNumberish, BigNumberish];
50+
const outputValues = [
51+
BigInt(outputs[0].value || 0n),
52+
BigInt(outputs[1].value || 0n),
53+
];
54+
const outputOwnerPublicKeys: [
55+
[BigNumberish, BigNumberish],
56+
[BigNumberish, BigNumberish],
57+
] = [signer.babyJubPublicKey, signer.babyJubPublicKey] as [
58+
[BigNumberish, BigNumberish],
59+
[BigNumberish, BigNumberish],
60+
];
5161

5262
const inputObj = {
5363
outputCommitments,
5464
outputValues,
55-
outputSalts: [output.salt],
65+
outputSalts: [outputs[0].salt, outputs[1].salt],
5666
outputOwnerPublicKeys,
5767
};
5868

solidity/test/zeto_anon.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,13 +170,14 @@ describe("Zeto based fungible token with anonymity without encryption or nullifi
170170
await tx1.wait();
171171

172172
utxo100 = newUTXO(100, Alice);
173+
const utxo0 = newUTXO(0, Alice);
173174
const { outputCommitments, encodedProof } = await prepareDepositProof(
174175
Alice,
175-
utxo100,
176+
[utxo100, utxo0],
176177
);
177178
const tx2 = await zeto
178179
.connect(Alice.signer)
179-
.deposit(100, outputCommitments[0], encodedProof, "0x");
180+
.deposit(100, outputCommitments, encodedProof, "0x");
180181
await tx2.wait();
181182
});
182183

solidity/test/zeto_anon_enc.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,14 @@ describe("Zeto based fungible token with anonymity and encryption", function ()
191191
await tx1.wait();
192192

193193
utxo100 = newUTXO(100, Alice);
194+
const utxo0 = newUTXO(0, Alice);
194195
const { outputCommitments, encodedProof } = await prepareDepositProof(
195196
Alice,
196-
utxo100,
197+
[utxo100, utxo0],
197198
);
198199
const tx2 = await zeto
199200
.connect(Alice.signer)
200-
.deposit(100, outputCommitments[0], encodedProof, "0x");
201+
.deposit(100, outputCommitments, encodedProof, "0x");
201202
await tx2.wait();
202203
});
203204

solidity/test/zeto_anon_enc_nullifier.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,17 +275,20 @@ describe("Zeto based fungible token with anonymity using nullifiers and encrypti
275275
await tx1.wait();
276276

277277
utxo100 = newUTXO(100, Alice);
278+
const utxo0 = newUTXO(0, Alice);
278279
const { outputCommitments, encodedProof } = await prepareDepositProof(
279280
Alice,
280-
utxo100,
281+
[utxo100, utxo0],
281282
);
282283
const tx2 = await zeto
283284
.connect(Alice.signer)
284-
.deposit(100, outputCommitments[0], encodedProof, "0x");
285+
.deposit(100, outputCommitments, encodedProof, "0x");
285286
await tx2.wait();
286287

287288
await smtAlice.add(utxo100.hash, utxo100.hash);
289+
await smtAlice.add(utxo0.hash, utxo0.hash);
288290
await smtBob.add(utxo100.hash, utxo100.hash);
291+
await smtBob.add(utxo0.hash, utxo0.hash);
289292
});
290293

291294
it("mint to Alice and transfer UTXOs honestly to Bob should succeed", async function () {

solidity/test/zeto_anon_enc_nullifier_kyc.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ describe("Zeto based fungible token with anonymity using nullifiers and encrypti
6161
let erc20: any;
6262
let zeto: any;
6363
let utxo100: UTXO;
64+
let utxo0: UTXO;
6465
let utxo1: UTXO;
6566
let utxo2: UTXO;
6667
let utxo3: UTXO;
@@ -336,17 +337,20 @@ describe("Zeto based fungible token with anonymity using nullifiers and encrypti
336337
await tx1.wait();
337338

338339
utxo100 = newUTXO(100, Alice);
340+
utxo0 = newUTXO(0, Alice);
339341
const { outputCommitments, encodedProof } = await prepareDepositProof(
340342
Alice,
341-
utxo100,
343+
[utxo100, utxo0],
342344
);
343345
const tx2 = await zeto
344346
.connect(Alice.signer)
345-
.deposit(100, outputCommitments[0], encodedProof, "0x");
347+
.deposit(100, outputCommitments, encodedProof, "0x");
346348
await tx2.wait();
347349

348350
await smtAlice.add(utxo100.hash, utxo100.hash);
351+
await smtAlice.add(utxo0.hash, utxo0.hash);
349352
await smtBob.add(utxo100.hash, utxo100.hash);
353+
await smtBob.add(utxo0.hash, utxo0.hash);
350354
});
351355

352356
it("mint to Alice and transfer UTXOs honestly to Bob should succeed", async function () {
@@ -576,6 +580,7 @@ describe("Zeto based fungible token with anonymity using nullifiers and encrypti
576580

577581
describe("unregistered user cases", function () {
578582
let unregisteredUtxo100: UTXO;
583+
let unregisteredUtxo0: UTXO;
579584

580585
it("deposit by an unregistered user should succeed", async function () {
581586
const tx = await erc20
@@ -588,24 +593,28 @@ describe("Zeto based fungible token with anonymity using nullifiers and encrypti
588593
await tx1.wait();
589594

590595
unregisteredUtxo100 = newUTXO(100, unregistered);
596+
unregisteredUtxo0 = newUTXO(0, unregistered);
591597
const { outputCommitments, encodedProof } = await prepareDepositProof(
592598
unregistered,
593-
unregisteredUtxo100,
599+
[unregisteredUtxo100, unregisteredUtxo0],
594600
);
595601
const tx2 = await zeto
596602
.connect(unregistered.signer)
597-
.deposit(100, outputCommitments[0], encodedProof, "0x");
603+
.deposit(100, outputCommitments, encodedProof, "0x");
598604
await tx2.wait();
599605

600606
// Alice tracks the UTXO inside the SMT
601607
await smtAlice.add(unregisteredUtxo100.hash, unregisteredUtxo100.hash);
608+
await smtAlice.add(unregisteredUtxo0.hash, unregisteredUtxo0.hash);
602609
// Bob also locally tracks the UTXOs inside the SMT
603610
await smtBob.add(unregisteredUtxo100.hash, unregisteredUtxo100.hash);
611+
await smtBob.add(unregisteredUtxo0.hash, unregisteredUtxo0.hash);
604612
});
605613

606614
it("transfer from an unregistered user should fail", async function () {
607615
// catch up the local SMT for the unregistered user
608616
await smtUnregistered.add(utxo100.hash, utxo100.hash);
617+
await smtUnregistered.add(utxo0.hash, utxo0.hash);
609618
await smtUnregistered.add(utxo1.hash, utxo1.hash);
610619
await smtUnregistered.add(utxo2.hash, utxo2.hash);
611620
await smtUnregistered.add(_utxo3.hash, _utxo3.hash);
@@ -620,6 +629,7 @@ describe("Zeto based fungible token with anonymity using nullifiers and encrypti
620629
unregisteredUtxo100.hash,
621630
unregisteredUtxo100.hash,
622631
);
632+
await smtUnregistered.add(unregisteredUtxo0.hash, unregisteredUtxo0.hash);
623633
const utxosRoot = await smtUnregistered.root();
624634

625635
const nullifier = newNullifier(unregisteredUtxo100, unregistered);

solidity/test/zeto_anon_enc_nullifier_non_repudiation.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ describe("Zeto based fungible token with anonymity using nullifiers and encrypti
5959
let erc20: any;
6060
let zeto: any;
6161
let utxo100: UTXO;
62+
let utxo0: UTXO;
6263
let utxo1: UTXO;
6364
let utxo2: UTXO;
6465
let utxo3: UTXO;
@@ -330,17 +331,20 @@ describe("Zeto based fungible token with anonymity using nullifiers and encrypti
330331
await tx1.wait();
331332

332333
utxo100 = newUTXO(100, Alice);
334+
utxo0 = newUTXO(0, Alice);
333335
const { outputCommitments, encodedProof } = await prepareDepositProof(
334336
Alice,
335-
utxo100,
337+
[utxo100, utxo0],
336338
);
337339
const tx2 = await zeto
338340
.connect(Alice.signer)
339-
.deposit(100, outputCommitments[0], encodedProof, "0x");
341+
.deposit(100, outputCommitments, encodedProof, "0x");
340342
await tx2.wait();
341343

342344
await smtAlice.add(utxo100.hash, utxo100.hash);
345+
await smtAlice.add(utxo0.hash, utxo0.hash);
343346
await smtBob.add(utxo100.hash, utxo100.hash);
347+
await smtBob.add(utxo0.hash, utxo0.hash);
344348
});
345349

346350
it("mint to Alice and transfer UTXOs honestly to Bob should succeed and verifiable by the regulator", async function () {

solidity/test/zeto_anon_nullifier.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,17 +247,20 @@ describe("Zeto based fungible token with anonymity using nullifiers without encr
247247
await tx1.wait();
248248

249249
utxo100 = newUTXO(100, Alice);
250+
const utxo0 = newUTXO(0, Alice);
250251
const { outputCommitments, encodedProof } = await prepareDepositProof(
251252
Alice,
252-
utxo100,
253+
[utxo0, utxo100],
253254
);
254255
const tx2 = await zeto
255256
.connect(Alice.signer)
256-
.deposit(100, outputCommitments[0], encodedProof, "0x");
257+
.deposit(100, outputCommitments, encodedProof, "0x");
257258
await tx2.wait();
258259

259260
await smtAlice.add(utxo100.hash, utxo100.hash);
261+
await smtAlice.add(utxo0.hash, utxo0.hash);
260262
await smtBob.add(utxo100.hash, utxo100.hash);
263+
await smtBob.add(utxo0.hash, utxo0.hash);
261264
});
262265

263266
it("mint to Alice and transfer UTXOs honestly to Bob should succeed", async function () {

0 commit comments

Comments
 (0)