From 07a4d600f4a28a94e984e9f7e9549816219bf2a0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 8 Nov 2021 18:05:57 +0300 Subject: [PATCH] add commitment to compliance signature --- circuits/keypair.circom | 6 ++++-- circuits/transaction.circom | 17 +++++++++-------- src/keypair.js | 4 ++-- src/utxo.js | 2 +- test/full.test.js | 3 ++- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/circuits/keypair.circom b/circuits/keypair.circom index 14e8e73..70dc53e 100644 --- a/circuits/keypair.circom +++ b/circuits/keypair.circom @@ -12,11 +12,13 @@ template Keypair() { template Signature() { signal input privateKey; + signal input commitment; signal input merklePath; signal output out; - component hasher = Poseidon(2); + component hasher = Poseidon(3); hasher.inputs[0] <== privateKey; - hasher.inputs[1] <== merklePath; + hasher.inputs[1] <== commitment; + hasher.inputs[2] <== merklePath; out <== hasher.out; } diff --git a/circuits/transaction.circom b/circuits/transaction.circom index 189e5dc..56f2a51 100644 --- a/circuits/transaction.circom +++ b/circuits/transaction.circom @@ -11,7 +11,7 @@ Utxo structure: } commitment = hash(amount, pubKey, blinding) -nullifier = hash(commitment, merklePath, sign(merklePath, privKey)) +nullifier = hash(commitment, merklePath, sign(privKey, commitment, merklePath)) */ // Universal JoinSplit transaction with nIns inputs and 2 outputs @@ -39,7 +39,7 @@ template Transaction(levels, nIns, nOuts, zeroLeaf) { component inKeypair[nIns]; component inSignature[nIns]; - component inUtxoHasher[nIns]; + component commitmentHasher[nIns]; component nullifierHasher[nIns]; component tree[nIns]; component checkRoot[nIns]; @@ -50,23 +50,24 @@ template Transaction(levels, nIns, nOuts, zeroLeaf) { inKeypair[tx] = Keypair(); inKeypair[tx].privateKey <== inPrivateKey[tx]; - inUtxoHasher[tx] = Poseidon(3); - inUtxoHasher[tx].inputs[0] <== inAmount[tx]; - inUtxoHasher[tx].inputs[1] <== inKeypair[tx].publicKey; - inUtxoHasher[tx].inputs[2] <== inBlinding[tx]; + commitmentHasher[tx] = Poseidon(3); + commitmentHasher[tx].inputs[0] <== inAmount[tx]; + commitmentHasher[tx].inputs[1] <== inKeypair[tx].publicKey; + commitmentHasher[tx].inputs[2] <== inBlinding[tx]; inSignature[tx] = Signature(); inSignature[tx].privateKey <== inPrivateKey[tx]; + inSignature[tx].commitment <== commitmentHasher[tx].out; inSignature[tx].merklePath <== inPathIndices[tx]; nullifierHasher[tx] = Poseidon(3); - nullifierHasher[tx].inputs[0] <== inUtxoHasher[tx].out; + nullifierHasher[tx].inputs[0] <== commitmentHasher[tx].out; nullifierHasher[tx].inputs[1] <== inPathIndices[tx]; nullifierHasher[tx].inputs[2] <== inSignature[tx].out; nullifierHasher[tx].out === inputNullifier[tx]; tree[tx] = MerkleProof(levels); - tree[tx].leaf <== inUtxoHasher[tx].out; + tree[tx].leaf <== commitmentHasher[tx].out; tree[tx].pathIndices <== inPathIndices[tx]; for (var i = 0; i < levels; i++) { tree[tx].pathElements[i] <== inPathElements[tx][i]; diff --git a/src/keypair.js b/src/keypair.js index 5315080..3cc1edc 100644 --- a/src/keypair.js +++ b/src/keypair.js @@ -85,8 +85,8 @@ class Keypair { * @param {string|number|BigNumber} merklePath a hex string with merkle path * @returns {BigNumber} a hex string with signature */ - sign(merklePath) { - return poseidonHash([this.privkey, merklePath]) + sign(commitment, merklePath) { + return poseidonHash([this.privkey, commitment, merklePath]) } /** diff --git a/src/utxo.js b/src/utxo.js index 0d0ce9a..98817d0 100644 --- a/src/utxo.js +++ b/src/utxo.js @@ -46,7 +46,7 @@ class Utxo { ) { throw new Error('Can not compute nullifier without utxo index or private key') } - const signature = this.keypair.privkey ? this.keypair.sign(this.index || 0) : 0 + const signature = this.keypair.privkey ? this.keypair.sign(this.getCommitment(), this.index || 0) : 0 this._nullifier = poseidonHash([this.getCommitment(), this.index || 0, signature]) } return this._nullifier diff --git a/test/full.test.js b/test/full.test.js index 2b4af3c..e476e82 100644 --- a/test/full.test.js +++ b/test/full.test.js @@ -377,8 +377,9 @@ describe('TornadoPool', function () { blinding: aliceDepositUtxo.blinding, }, nullifier: { + commitment, merklePath: index, - signature: aliceDepositUtxo.keypair.sign(index), + signature: aliceDepositUtxo.keypair.sign(commitment, index), }, }