From a19a22627721baf287d962bcb674166cc830198c Mon Sep 17 00:00:00 2001 From: poma Date: Wed, 9 Jun 2021 14:19:22 +0300 Subject: [PATCH] keypair --- src/index.js | 6 +++--- src/kaypair.js | 31 +++++++++++++++++++++++++++++++ src/utxo.js | 30 ++++++++---------------------- 3 files changed, 42 insertions(+), 25 deletions(-) create mode 100644 src/kaypair.js diff --git a/src/index.js b/src/index.js index 2c2345e..3a02403 100644 --- a/src/index.js +++ b/src/index.js @@ -66,7 +66,7 @@ async function getProof({ inputs, outputs, tree, extAmount, fee, recipient, rela // data for 2 transaction inputs inAmount: inputs.map((x) => x.amount), - inPrivateKey: inputs.map((x) => x.privkey), + inPrivateKey: inputs.map((x) => x.keypair.privkey), inBlinding: inputs.map((x) => x.blinding), inPathIndices: inputMerklePathIndices, inPathElements: inputMerklePathElements, @@ -74,7 +74,7 @@ async function getProof({ inputs, outputs, tree, extAmount, fee, recipient, rela // data for 2 transaction outputs outAmount: outputs.map((x) => x.amount), outBlinding: outputs.map((x) => x.blinding), - outPubkey: outputs.map((x) => x.pubkey), + outPubkey: outputs.map((x) => x.keypair.pubkey), outPathIndices: outputIndex >> Math.log2(outputs.length), outPathElements: outputPath.slice(Math.log2(outputs.length)), } @@ -130,7 +130,7 @@ async function transact({ tornadoPool, utxo }) { const inputs = [utxo, new Utxo()] const outputs = [ new Utxo({ amount: utxo.amount / 4 }), - new Utxo({ amount: (utxo.amount * 3) / 4, privkey: utxo.privkey }), + new Utxo({ amount: (utxo.amount * 3) / 4, keypair: utxo.keypair }), ] const { proof, args } = await getProof({ diff --git a/src/kaypair.js b/src/kaypair.js new file mode 100644 index 0000000..feefcd0 --- /dev/null +++ b/src/kaypair.js @@ -0,0 +1,31 @@ +const { ethers } = require('hardhat') +const { BigNumber } = ethers +const { randomBN, poseidonHash, toFixedHex } = require('./utils') + +class Keypair { + constructor(privkey = randomBN()) { + this.privkey = privkey + this.pubkey = poseidonHash([this.privkey]) + this.encryptionKey = 0 // todo + } + + toString() { + return toFixedHex(this.pubkey) + toFixedHex(this.encryptionKey).slice(2) + } + + static fromString(str) { + if (str.length === 130) { + str = str.slice(2) + } + if (str.length !== 128) { + throw new Error('Invalid key length') + } + return Object.assign(new Keypair(), { + privkey: null, + pubkey: BigNumber.from('0x' + str.slice(0, 64)), + encryptionKey: BigNumber.from('0x' + str.slice(64, 128)), + }) + } +} + +module.exports = Keypair diff --git a/src/utxo.js b/src/utxo.js index 47f2f45..6a60da1 100644 --- a/src/utxo.js +++ b/src/utxo.js @@ -1,43 +1,29 @@ const { ethers } = require('hardhat') const { BigNumber } = ethers const { randomBN, poseidonHash } = require('./utils') - -function fromPrivkey(privkey) { - return { - privkey, - pubkey: poseidonHash([privkey]), - } -} +const Keypair = require('./kaypair') class Utxo { - constructor({ amount, pubkey, privkey, blinding, index } = {}) { - if (!pubkey) { - if (privkey) { - pubkey = fromPrivkey(privkey).pubkey - } else { - ;({ pubkey, privkey } = fromPrivkey(randomBN())) - } - } - this.amount = BigNumber.from(amount || 0) - this.blinding = blinding || randomBN() - this.pubkey = pubkey - this.privkey = privkey + constructor({ amount = 0, keypair = new Keypair(), blinding = randomBN(), index } = {}) { + this.amount = BigNumber.from(amount) + this.blinding = BigNumber.from(blinding) + this.keypair = keypair this.index = index } getCommitment() { if (!this._commitment) { - this._commitment = poseidonHash([this.amount, this.blinding, this.pubkey]) + this._commitment = poseidonHash([this.amount, this.blinding, this.keypair.pubkey]) } return this._commitment } getNullifier() { if (!this._nullifier) { - if (this.amount > 0 && (this.index === undefined || !this.privkey === undefined)) { + if (this.amount > 0 && (this.index === undefined || this.keypair.privkey === undefined || this.keypair.privkey === null)) { throw new Error('Can not compute nullifier without utxo index or private key') } - this._nullifier = poseidonHash([this.getCommitment(), this.index || 0, this.privkey || 0]) + this._nullifier = poseidonHash([this.getCommitment(), this.index || 0, this.keypair.privkey || 0]) } return this._nullifier }