Update unit test on contracts for encryptedNote

This commit is contained in:
Brian Li 2021-04-18 11:24:18 -07:00
parent 2abf02f818
commit abdca319ed
6 changed files with 336 additions and 130 deletions

173
package-lock.json generated
View File

@ -6590,95 +6590,14 @@
}
},
"circomlib": {
"version": "git+https://github.com/tornadocash/circomlib.git#c372f14d324d57339c88451834bf2824e73bbdbc",
"from": "git+https://github.com/tornadocash/circomlib.git#c372f14d324d57339c88451834bf2824e73bbdbc",
"version": "git+https://github.com/tornadocash/circomlib.git#3b492f9801573eebcfe1b6c584afe8a3beecf2b4",
"from": "git+https://github.com/tornadocash/circomlib.git#3b492f9801573eebcfe1b6c584afe8a3beecf2b4",
"requires": {
"blake-hash": "^1.1.0",
"blake2b": "^2.1.3",
"snarkjs": "git+https://github.com/peppersec/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
"typedarray-to-buffer": "^3.1.5",
"web3": "^1.0.0-beta.55"
},
"dependencies": {
"eslint": {
"version": "5.16.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
"integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
"requires": {
"@babel/code-frame": "^7.0.0",
"ajv": "^6.9.1",
"chalk": "^2.1.0",
"cross-spawn": "^6.0.5",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"eslint-scope": "^4.0.3",
"eslint-utils": "^1.3.1",
"eslint-visitor-keys": "^1.0.0",
"espree": "^5.0.1",
"esquery": "^1.0.1",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
"glob": "^7.1.2",
"globals": "^11.7.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^6.2.2",
"js-yaml": "^3.13.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.3.0",
"lodash": "^4.17.11",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.2",
"path-is-inside": "^1.0.2",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^5.5.1",
"strip-ansi": "^4.0.0",
"strip-json-comments": "^2.0.1",
"table": "^5.2.3",
"text-table": "^0.2.0"
}
},
"keccak": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/keccak/-/keccak-2.1.0.tgz",
"integrity": "sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==",
"requires": {
"bindings": "^1.5.0",
"inherits": "^2.0.4",
"nan": "^2.14.0",
"safe-buffer": "^5.2.0"
}
},
"mkdirp": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"requires": {
"minimist": "^1.2.5"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
"snarkjs": {
"version": "git+https://github.com/peppersec/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
"from": "git+https://github.com/peppersec/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
"requires": {
"big-integer": "^1.6.43",
"chai": "^4.2.0",
"escape-string-regexp": "^1.0.5",
"eslint": "^5.16.0",
"keccak": "^2.0.0",
"yargs": "^12.0.5"
}
}
"web3": "^1.2.11"
}
},
"class-is": {
@ -7230,6 +7149,11 @@
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
},
"decimal.js": {
"version": "10.2.1",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
"integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw=="
},
"decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
@ -8471,6 +8395,39 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
},
"eth-sig-util": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"requires": {
"ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"ethereumjs-util": "^5.1.1"
}
},
"ethereumjs-abi": {
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1a27c59c15ab1e95ee8e5c4ed6ad814c49cc439e",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"requires": {
"bn.js": "^4.11.8",
"ethereumjs-util": "^6.0.0"
},
"dependencies": {
"ethereumjs-util": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
"integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
"requires": {
"@types/bn.js": "^4.11.3",
"bn.js": "^4.11.0",
"create-hash": "^1.1.2",
"elliptic": "^6.5.2",
"ethereum-cryptography": "^0.1.3",
"ethjs-util": "0.1.6",
"rlp": "^2.2.3"
}
}
}
},
"ethereumjs-util": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
@ -8527,12 +8484,14 @@
}
},
"eth-sig-util": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"version": "2.5.4",
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.5.4.tgz",
"integrity": "sha512-aCMBwp8q/4wrW4QLsF/HYBOSA7TpLKmkVwP3pYQNkEEseW2Rr8Z5Uxc9/h6HX+OG3tuHo+2bINVSihIeBfym6A==",
"requires": {
"ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"ethereumjs-util": "^5.1.1"
"ethereumjs-abi": "0.6.8",
"ethereumjs-util": "^5.1.1",
"tweetnacl": "^1.0.3",
"tweetnacl-util": "^0.15.0"
},
"dependencies": {
"bn.js": {
@ -8540,30 +8499,6 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
},
"ethereumjs-abi": {
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1a27c59c15ab1e95ee8e5c4ed6ad814c49cc439e",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"requires": {
"bn.js": "^4.11.8",
"ethereumjs-util": "^6.0.0"
},
"dependencies": {
"ethereumjs-util": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
"integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
"requires": {
"@types/bn.js": "^4.11.3",
"bn.js": "^4.11.0",
"create-hash": "^1.1.2",
"elliptic": "^6.5.2",
"ethereum-cryptography": "^0.1.3",
"ethjs-util": "0.1.6",
"rlp": "^2.2.3"
}
}
}
},
"ethereumjs-util": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
@ -8577,6 +8512,11 @@
"rlp": "^2.0.0",
"safe-buffer": "^5.1.1"
}
},
"tweetnacl": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
"integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="
}
}
},
@ -17240,6 +17180,11 @@
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"tweetnacl-util": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
"integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw=="
},
"type": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",

View File

@ -37,17 +37,18 @@
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"circom": "^0.0.35",
"circomlib": "git+https://github.com/tornadocash/circomlib.git#c372f14d324d57339c88451834bf2824e73bbdbc",
"circomlib": "git+https://github.com/tornadocash/circomlib.git#3b492f9801573eebcfe1b6c584afe8a3beecf2b4",
"commander": "^4.1.1",
"decimal.js": "^10.2.0",
"dotenv": "^8.2.0",
"eslint": "^6.6.0",
"eth-json-rpc-filters": "^4.1.1",
"eth-sig-util": "^2.5.3",
"ganache-cli": "^6.7.0",
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
"truffle": "^5.0.44",
"truffle-flattener": "^1.4.2",
"web3": "^1.2.2",
"web3-utils": "^1.2.2",
"web3": "^1.2.11",
"websnark": "git+https://github.com/tornadocash/websnark.git#2041cfa5fa0b71cd5cca9022a4eeea4afe28c9f7"
},
"devDependencies": {

39
src/account.js Normal file
View File

@ -0,0 +1,39 @@
const {toBN} = require('web3-utils')
const {encrypt, decrypt} = require('eth-sig-util')
const {randomBN, poseidonHash} = require('./utils')
class Account {
constructor({amount, secret, nullifier} = {}) {
this.amount = amount ? toBN(amount) : toBN('0')
this.secret = secret ? toBN(secret) : randomBN(31)
this.nullifier = nullifier ? toBN(nullifier) : randomBN(31)
this.commitment = poseidonHash([this.amount, this.secret, this.nullifier])
this.nullifierHash = poseidonHash([this.nullifier])
if (this.amount.lt(toBN(0))) {
throw new Error('Cannot create an account with negative amount')
}
}
encrypt(pubkey) {
const bytes = Buffer.concat([
this.amount.toBuffer('be', 31),
this.secret.toBuffer('b', 31),
this.nullifier.toBuffer('be', 31),
])
return encrypt(pubkey, {data: bytes.toString('base64')}, 'x25519-xsalsa20-poly1305')
}
static decrypt(privkey, data) {
const decryptedMessage = decrypt(data, privkey)
const buf = Buffer.from(decryptedMessage, 'base64')
return new Account({
amount: toBN('0x' + buf.slice(0, 31).toString('hex')),
secret: toBN('0x' + buf.slice(31, 62).toString('hex')),
nullifier: toBN('0x' + buf.slice(62, 93).toString('hex')),
})
}
}
module.exports = Account

165
src/utils.js Normal file
View File

@ -0,0 +1,165 @@
const crypto = require('crypto')
const Decimal = require('decimal.js')
const {bigInt} = require('snarkjs')
const {toBN, soliditySha3} = require('web3-utils')
const Web3 = require('web3')
const web3 = new Web3()
const {babyJub, pedersenHash, mimcsponge, poseidon} = require('circomlib')
const RewardExtData = {
RewardExtData: {
relayer: 'address',
encryptedAccount: 'bytes',
},
}
const AccountUpdate = {
AccountUpdate: {
inputRoot: 'bytes32',
inputNullifierHash: 'bytes32',
outputRoot: 'bytes32',
outputPathIndices: 'uint256',
outputCommitment: 'bytes32',
},
}
const RewardArgs = {
RewardArgs: {
rate: 'uint256',
fee: 'uint256',
instance: 'address',
rewardNullifier: 'bytes32',
extDataHash: 'bytes32',
depositRoot: 'bytes32',
withdrawalRoot: 'bytes32',
extData: RewardExtData.RewardExtData,
account: AccountUpdate.AccountUpdate,
},
}
const WithdrawExtData = {
WithdrawExtData: {
fee: 'uint256',
recipient: 'address',
relayer: 'address',
encryptedAccount: 'bytes',
},
}
const pedersenHashBuffer = (buffer) => toBN(babyJub.unpackPoint(pedersenHash.hash(buffer))[0].toString())
const mimcHash = (items) => toBN(mimcsponge.multiHash(items.map((item) => bigInt(item))).toString())
const poseidonHash = (items) => toBN(poseidon(items).toString())
const poseidonHash2 = (a, b) => poseidonHash([a, b])
/** Generate random number of specified byte length */
const randomBN = (nbytes = 31) => toBN(bigInt.leBuff2int(crypto.randomBytes(nbytes)).toString())
/** BigNumber to hex string of specified length */
const toFixedHex = (number, length = 32) =>
'0x' +
(number instanceof Buffer ? number.toString('hex') : bigInt(number).toString(16)).padStart(length * 2, '0')
function getExtRewardArgsHash({relayer, encryptedAccount}) {
const encodedData = web3.eth.abi.encodeParameters(
[RewardExtData],
[{relayer: toFixedHex(relayer, 20), encryptedAccount}],
)
const hash = soliditySha3({t: 'bytes', v: encodedData})
return '0x00' + hash.slice(4) // cut last byte to make it 31 byte long to fit the snark field
}
function getExtWithdrawArgsHash({fee, recipient, relayer, encryptedAccount}) {
const encodedData = web3.eth.abi.encodeParameters(
[WithdrawExtData],
[
{
fee: toFixedHex(fee, 32),
recipient: toFixedHex(recipient, 20),
relayer: toFixedHex(relayer, 20),
encryptedAccount,
},
],
)
const hash = soliditySha3({t: 'bytes', v: encodedData})
return '0x00' + hash.slice(4) // cut first byte to make it 31 byte long to fit the snark field
}
function packEncryptedMessage(encryptedMessage) {
const nonceBuf = Buffer.from(encryptedMessage.nonce, 'base64')
const ephemPublicKeyBuf = Buffer.from(encryptedMessage.ephemPublicKey, 'base64')
const ciphertextBuf = Buffer.from(encryptedMessage.ciphertext, 'base64')
const messageBuff = Buffer.concat([
Buffer.alloc(24 - nonceBuf.length),
nonceBuf,
Buffer.alloc(32 - ephemPublicKeyBuf.length),
ephemPublicKeyBuf,
ciphertextBuf,
])
return '0x' + messageBuff.toString('hex')
}
function unpackEncryptedMessage(encryptedMessage) {
if (encryptedMessage.slice(0, 2) === '0x') {
encryptedMessage = encryptedMessage.slice(2)
}
const messageBuff = Buffer.from(encryptedMessage, 'hex')
const nonceBuf = messageBuff.slice(0, 24)
const ephemPublicKeyBuf = messageBuff.slice(24, 56)
const ciphertextBuf = messageBuff.slice(56)
return {
version: 'x25519-xsalsa20-poly1305',
nonce: nonceBuf.toString('base64'),
ephemPublicKey: ephemPublicKeyBuf.toString('base64'),
ciphertext: ciphertextBuf.toString('base64'),
}
}
function bitsToNumber(bits) {
let result = 0
for (const item of bits.slice().reverse()) {
result = (result << 1) + item
}
return result
}
// a = floor(10**18 * e^(-0.0000000001 * amount))
// yield = BalBefore - (BalBefore * a)/10**18
function tornadoFormula({balance, amount, poolWeight = 1e10}) {
const decimals = new Decimal(10 ** 18)
balance = new Decimal(balance.toString())
amount = new Decimal(amount.toString())
poolWeight = new Decimal(poolWeight.toString())
const power = amount.div(poolWeight).negated()
const exponent = Decimal.exp(power).mul(decimals)
const newBalance = balance.mul(exponent).div(decimals)
return toBN(balance.sub(newBalance).toFixed(0))
}
function reverseTornadoFormula({balance, tokens, poolWeight = 1e10}) {
balance = new Decimal(balance.toString())
tokens = new Decimal(tokens.toString())
poolWeight = new Decimal(poolWeight.toString())
return toBN(poolWeight.times(Decimal.ln(balance.div(balance.sub(tokens)))).toFixed(0))
}
module.exports = {
randomBN,
pedersenHashBuffer,
bitsToNumber,
getExtRewardArgsHash,
getExtWithdrawArgsHash,
packEncryptedMessage,
unpackEncryptedMessage,
toFixedHex,
mimcHash,
poseidonHash,
poseidonHash2,
tornadoFormula,
reverseTornadoFormula,
RewardArgs,
RewardExtData,
AccountUpdate,
}

View File

@ -5,7 +5,13 @@ require('chai')
.should()
const fs = require('fs')
const { toBN } = require('web3-utils')
const { getEncryptionPublicKey } = require('eth-sig-util')
const { hexToBytes, toBN } = require('web3-utils')
const {
packEncryptedMessage,
unpackEncryptedMessage,
} = require('../src/utils')
const Account = require('../src/account')
const { takeSnapshot, revertSnapshot } = require('../lib/ganacheHelper')
const Tornado = artifacts.require('./ERC20Tornado.sol')
@ -23,6 +29,7 @@ const bigInt = snarkjs.bigInt
const crypto = require('crypto')
const circomlib = require('circomlib')
const MerkleTree = require('../lib/MerkleTree')
const {randomBN} = require('../src/utils')
const rbigint = (nbytes) => snarkjs.bigInt.leBuff2int(crypto.randomBytes(nbytes))
const pedersenHash = (data) => circomlib.babyJub.unpackPoint(circomlib.pedersenHash.hash(data))[0]
@ -31,10 +38,10 @@ const getRandomRecipient = () => rbigint(20)
function generateDeposit() {
let deposit = {
secret: rbigint(31),
nullifier: rbigint(31),
secret: randomBN(31),
nullifier: randomBN(31),
}
const preimage = Buffer.concat([deposit.nullifier.leInt2Buff(31), deposit.secret.leInt2Buff(31)])
const preimage = Buffer.concat([deposit.nullifier.toBuffer('le', 31), deposit.secret.toBuffer('le', 31)])
deposit.commitment = pedersenHash(preimage)
return deposit
}
@ -60,6 +67,10 @@ contract('ERC20Tornado', accounts => {
let circuit
let proving_key
// Public / private key pair used for encrypting / decrypting the deposit note
const privateKey = web3.eth.accounts.create().privateKey.slice(2)
const publicKey = getEncryptionPublicKey(privateKey)
before(async () => {
tree = new MerkleTree(
levels,
@ -113,6 +124,12 @@ contract('ERC20Tornado', accounts => {
describe('#withdraw', () => {
it('should work', async () => {
const deposit = generateDeposit()
const account = new Account({
amount: tokenDenomination,
secret: deposit.secret,
nullifier: deposit.nullifier,
})
const encryptedMessage = packEncryptedMessage(account.encrypt(publicKey))
const user = accounts[4]
await tree.insert(deposit.commitment)
await token.mint(user, tokenDenomination)
@ -122,7 +139,18 @@ contract('ERC20Tornado', accounts => {
// Uncomment to measure gas usage
// let gas = await tornado.deposit.estimateGas(toBN(deposit.commitment.toString()), { from: user, gasPrice: '0' })
// console.log('deposit gas:', gas)
await tornado.deposit(toFixedHex(deposit.commitment), [], { from: user, gasPrice: '0' })
const {logs: depositLogs} = await tornado.deposit(
toFixedHex(deposit.commitment),
hexToBytes(encryptedMessage),
{ from: user, gasPrice: '0' },
)
const encryptedNoteLog = depositLogs[depositLogs.length - 1]
encryptedNoteLog.event.should.be.equal("EncryptedNote")
encryptedNoteLog.args.sender.should.be.equal(accounts[4])
encryptedNoteLog.args.encryptedNote.should.be.equal(encryptedMessage)
const unpackedMessage = unpackEncryptedMessage(encryptedMessage)
const decryptedAccount = Account.decrypt(privateKey, unpackedMessage)
const balanceUserAfter = await token.balanceOf(user)
balanceUserAfter.should.be.eq.BN(toBN(balanceUserBefore).sub(toBN(tokenDenomination)))
@ -132,15 +160,15 @@ contract('ERC20Tornado', accounts => {
const input = stringifyBigInts({
// public
root,
nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)),
nullifierHash: pedersenHash(decryptedAccount.nullifier.toBuffer('le', 31)),
relayer,
recipient,
fee,
refund,
// private
nullifier: deposit.nullifier,
secret: deposit.secret,
nullifier: decryptedAccount.nullifier,
secret: decryptedAccount.secret,
pathElements: path_elements,
pathIndices: path_index,
})
@ -224,7 +252,7 @@ contract('ERC20Tornado', accounts => {
const input = stringifyBigInts({
// public
root,
nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)),
nullifierHash: pedersenHash(deposit.nullifier.toBuffer('le', 31)),
relayer,
recipient,
fee,
@ -339,7 +367,7 @@ contract('ERC20Tornado', accounts => {
const input = stringifyBigInts({
// public
root,
nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)),
nullifierHash: pedersenHash(deposit.nullifier.toBuffer('le', 31)),
relayer,
recipient,
fee,
@ -413,7 +441,7 @@ contract('ERC20Tornado', accounts => {
const input = stringifyBigInts({
// public
root,
nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)),
nullifierHash: pedersenHash(deposit.nullifier.toBuffer('le', 31)),
relayer,
recipient,
fee,
@ -480,7 +508,7 @@ contract('ERC20Tornado', accounts => {
const input = stringifyBigInts({
// public
root,
nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)),
nullifierHash: pedersenHash(deposit.nullifier.toBuffer('le', 31)),
relayer: operator,
recipient,
fee,
@ -569,7 +597,7 @@ contract('ERC20Tornado', accounts => {
const input = stringifyBigInts({
// public
root,
nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)),
nullifierHash: pedersenHash(deposit.nullifier.toBuffer('le', 31)),
relayer: operator,
recipient,
fee,

28
test/encrypt.test.js Normal file
View File

@ -0,0 +1,28 @@
const { getEncryptionPublicKey } = require('eth-sig-util')
const { toBN } = require('web3-utils')
const Account = require('../src/account')
const {
packEncryptedMessage,
unpackEncryptedMessage,
} = require('../src/utils')
describe('#encrypt', () => {
// EncryptedNote
const privateKey = web3.eth.accounts.create().privateKey.slice(2)
const publicKey = getEncryptionPublicKey(privateKey)
it('should work', () => {
const account = new Account()
const encryptedAccount = account.encrypt(publicKey)
const encryptedMessage = packEncryptedMessage(encryptedAccount)
const unpackedMessage = unpackEncryptedMessage(encryptedMessage)
const account2 = Account.decrypt(privateKey, unpackedMessage)
assert(account.amount.toString() === toBN(account2.amount).toString())
assert(account.secret.toString() === toBN(account2.secret).toString())
assert(account.nullifier.toString() === toBN(account2.nullifier).toString())
assert(account.commitment.toString() === toBN(account2.commitment).toString())
})
})