mirror of
https://github.com/tornadocash/tornado-nova
synced 2024-02-02 14:53:56 +01:00
reorder blinding, pubkey, amount
This commit is contained in:
parent
9d4f8801ea
commit
397942f94d
@ -6,12 +6,12 @@ include "./keypair.circom"
|
|||||||
Utxo structure:
|
Utxo structure:
|
||||||
{
|
{
|
||||||
amount,
|
amount,
|
||||||
blinding, // random number
|
|
||||||
pubkey,
|
pubkey,
|
||||||
|
blinding, // random number
|
||||||
}
|
}
|
||||||
|
|
||||||
commitment = hash(amount, blinding, pubKey)
|
commitment = hash(amount, pubKey, blinding)
|
||||||
nullifier = hash(commitment, privKey, merklePath)
|
nullifier = hash(commitment, merklePath, privKey)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Universal JoinSplit transaction with nIns inputs and 2 outputs
|
// Universal JoinSplit transaction with nIns inputs and 2 outputs
|
||||||
@ -26,16 +26,16 @@ template Transaction(levels, nIns, nOuts, zeroLeaf) {
|
|||||||
// data for transaction inputs
|
// data for transaction inputs
|
||||||
signal input inputNullifier[nIns];
|
signal input inputNullifier[nIns];
|
||||||
signal private input inAmount[nIns];
|
signal private input inAmount[nIns];
|
||||||
signal private input inBlinding[nIns];
|
|
||||||
signal private input inPrivateKey[nIns];
|
signal private input inPrivateKey[nIns];
|
||||||
|
signal private input inBlinding[nIns];
|
||||||
signal private input inPathIndices[nIns];
|
signal private input inPathIndices[nIns];
|
||||||
signal private input inPathElements[nIns][levels];
|
signal private input inPathElements[nIns][levels];
|
||||||
|
|
||||||
// data for transaction outputs
|
// data for transaction outputs
|
||||||
signal input outputCommitment[nOuts];
|
signal input outputCommitment[nOuts];
|
||||||
signal private input outAmount[nOuts];
|
signal private input outAmount[nOuts];
|
||||||
signal private input outBlinding[nOuts];
|
|
||||||
signal private input outPubkey[nOuts];
|
signal private input outPubkey[nOuts];
|
||||||
|
signal private input outBlinding[nOuts];
|
||||||
|
|
||||||
component inKeypair[nIns];
|
component inKeypair[nIns];
|
||||||
component inUtxoHasher[nIns];
|
component inUtxoHasher[nIns];
|
||||||
@ -51,8 +51,8 @@ template Transaction(levels, nIns, nOuts, zeroLeaf) {
|
|||||||
|
|
||||||
inUtxoHasher[tx] = Poseidon(3);
|
inUtxoHasher[tx] = Poseidon(3);
|
||||||
inUtxoHasher[tx].inputs[0] <== inAmount[tx];
|
inUtxoHasher[tx].inputs[0] <== inAmount[tx];
|
||||||
inUtxoHasher[tx].inputs[1] <== inBlinding[tx];
|
inUtxoHasher[tx].inputs[1] <== inKeypair[tx].publicKey;
|
||||||
inUtxoHasher[tx].inputs[2] <== inKeypair[tx].publicKey;
|
inUtxoHasher[tx].inputs[2] <== inBlinding[tx];
|
||||||
|
|
||||||
nullifierHasher[tx] = Poseidon(3);
|
nullifierHasher[tx] = Poseidon(3);
|
||||||
nullifierHasher[tx].inputs[0] <== inUtxoHasher[tx].out;
|
nullifierHasher[tx].inputs[0] <== inUtxoHasher[tx].out;
|
||||||
@ -73,8 +73,8 @@ template Transaction(levels, nIns, nOuts, zeroLeaf) {
|
|||||||
checkRoot[tx].in[1] <== tree[tx].root;
|
checkRoot[tx].in[1] <== tree[tx].root;
|
||||||
checkRoot[tx].enabled <== inAmount[tx];
|
checkRoot[tx].enabled <== inAmount[tx];
|
||||||
|
|
||||||
// We don't need to range check input amounts, since all inputs are valid UTXOs that
|
// We don't need to range check input amounts, since all inputs are valid UTXOs that
|
||||||
// were already checked as outputs in the previous transaction (or zero amount UTXOs that don't
|
// were already checked as outputs in the previous transaction (or zero amount UTXOs that don't
|
||||||
// need to be checked either).
|
// need to be checked either).
|
||||||
|
|
||||||
sumIns += inAmount[tx];
|
sumIns += inAmount[tx];
|
||||||
@ -88,8 +88,8 @@ template Transaction(levels, nIns, nOuts, zeroLeaf) {
|
|||||||
for (var tx = 0; tx < nOuts; tx++) {
|
for (var tx = 0; tx < nOuts; tx++) {
|
||||||
outUtxoHasher[tx] = Poseidon(3);
|
outUtxoHasher[tx] = Poseidon(3);
|
||||||
outUtxoHasher[tx].inputs[0] <== outAmount[tx];
|
outUtxoHasher[tx].inputs[0] <== outAmount[tx];
|
||||||
outUtxoHasher[tx].inputs[1] <== outBlinding[tx];
|
outUtxoHasher[tx].inputs[1] <== outPubkey[tx];
|
||||||
outUtxoHasher[tx].inputs[2] <== outPubkey[tx];
|
outUtxoHasher[tx].inputs[2] <== outBlinding[tx];
|
||||||
outUtxoHasher[tx].out === outputCommitment[tx];
|
outUtxoHasher[tx].out === outputCommitment[tx];
|
||||||
|
|
||||||
// Check that amount fits into 248 bits to prevent overflow
|
// Check that amount fits into 248 bits to prevent overflow
|
||||||
|
@ -25,7 +25,7 @@ class Utxo {
|
|||||||
*/
|
*/
|
||||||
getCommitment() {
|
getCommitment() {
|
||||||
if (!this._commitment) {
|
if (!this._commitment) {
|
||||||
this._commitment = poseidonHash([this.amount, this.blinding, this.keypair.pubkey])
|
this._commitment = poseidonHash([this.amount, this.keypair.pubkey, this.blinding])
|
||||||
}
|
}
|
||||||
return this._commitment
|
return this._commitment
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ class Utxo {
|
|||||||
* @returns {string} `0x`-prefixed hex string with data
|
* @returns {string} `0x`-prefixed hex string with data
|
||||||
*/
|
*/
|
||||||
encrypt() {
|
encrypt() {
|
||||||
const bytes = Buffer.concat([toBuffer(this.blinding, 31), toBuffer(this.amount, 31)])
|
const bytes = Buffer.concat([toBuffer(this.amount, 31), toBuffer(this.blinding, 31)])
|
||||||
return this.keypair.encrypt(bytes)
|
return this.keypair.encrypt(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,8 +72,8 @@ class Utxo {
|
|||||||
static decrypt(keypair, data, index) {
|
static decrypt(keypair, data, index) {
|
||||||
const buf = keypair.decrypt(data)
|
const buf = keypair.decrypt(data)
|
||||||
return new Utxo({
|
return new Utxo({
|
||||||
blinding: BigNumber.from('0x' + buf.slice(0, 31).toString('hex')),
|
amount: BigNumber.from('0x' + buf.slice(0, 31).toString('hex')),
|
||||||
amount: BigNumber.from('0x' + buf.slice(31, 62).toString('hex')),
|
blinding: BigNumber.from('0x' + buf.slice(31, 62).toString('hex')),
|
||||||
keypair,
|
keypair,
|
||||||
index,
|
index,
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user