mirror of
https://github.com/tornadocash/tornado-nova
synced 2024-02-02 14:53:56 +01:00
documentation
This commit is contained in:
parent
f606016994
commit
922457d12b
@ -34,6 +34,11 @@ function unpackEncryptedMessage(encryptedMessage) {
|
||||
}
|
||||
|
||||
class Keypair {
|
||||
/**
|
||||
* Initialize a new keypair. Generates a random private key if not defined
|
||||
*
|
||||
* @param {string} privkey
|
||||
*/
|
||||
constructor(privkey = ethers.Wallet.createRandom().privateKey) {
|
||||
this.privkey = privkey
|
||||
this.pubkey = poseidonHash([this.privkey])
|
||||
@ -44,10 +49,21 @@ class Keypair {
|
||||
return toFixedHex(this.pubkey) + Buffer.from(this.encryptionKey, 'base64').toString('hex')
|
||||
}
|
||||
|
||||
/**
|
||||
* Key address for this keypair, alias to {@link toString}
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
address() {
|
||||
return this.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize new keypair from address string
|
||||
*
|
||||
* @param str
|
||||
* @returns {Keypair}
|
||||
*/
|
||||
static fromString(str) {
|
||||
if (str.length === 130) {
|
||||
str = str.slice(2)
|
||||
@ -62,10 +78,22 @@ class Keypair {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt data using keypair encryption key
|
||||
*
|
||||
* @param {Buffer} bytes
|
||||
* @returns {string} a hex string with encrypted data
|
||||
*/
|
||||
encrypt(bytes) {
|
||||
return packEncryptedMessage(encrypt(this.encryptionKey, { data: bytes.toString('base64') }, 'x25519-xsalsa20-poly1305'))
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt data using keypair private key
|
||||
*
|
||||
* @param {string} data a hex string with data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
decrypt(data) {
|
||||
return Buffer.from(decrypt(unpackEncryptedMessage(data), this.privkey.slice(2)), 'base64')
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ const poseidonHash2 = (a, b) => poseidonHash([a, b])
|
||||
const FIELD_SIZE = BigNumber.from(
|
||||
'21888242871839275222246405745257275088548364400416034343698204186575808495617',
|
||||
)
|
||||
|
||||
/** Generate random number of specified byte length */
|
||||
const randomBN = (nbytes = 31) => BigNumber.from(crypto.randomBytes(nbytes))
|
||||
|
||||
@ -38,6 +39,7 @@ const toFixedHex = (number, length = 32) =>
|
||||
: BigNumber.from(number).toHexString().slice(2)
|
||||
).padStart(length * 2, '0')
|
||||
|
||||
/** Convert value into buffer of specified byte length */
|
||||
const toBuffer = (value, length) =>
|
||||
Buffer.from(
|
||||
BigNumber.from(value)
|
||||
|
43
src/utxo.js
43
src/utxo.js
@ -1,16 +1,28 @@
|
||||
const { ethers } = require('hardhat')
|
||||
const { BigNumber } = ethers
|
||||
const { randomBN, poseidonHash } = require('./utils')
|
||||
const { randomBN, poseidonHash, toBuffer } = require('./utils')
|
||||
const Keypair = require('./keypair')
|
||||
|
||||
class Utxo {
|
||||
constructor({ amount = 0, keypair = new Keypair(), blinding = randomBN(), index } = {}) {
|
||||
/**
|
||||
*
|
||||
* @param {BigNumber | BigInt | number | string} amount UTXO amount
|
||||
* @param {BigNumber | BigInt | number | string} blinding Blinding factor
|
||||
* @param {Keypair} keypair
|
||||
* @param {number|null} index UTXO index in the merkle tree
|
||||
*/
|
||||
constructor({ amount = 0, keypair = new Keypair(), blinding = randomBN(), index = null} = {}) {
|
||||
this.amount = BigNumber.from(amount)
|
||||
this.blinding = BigNumber.from(blinding)
|
||||
this.keypair = keypair
|
||||
this.index = index
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns commitment for this UTXO
|
||||
*
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
getCommitment() {
|
||||
if (!this._commitment) {
|
||||
this._commitment = poseidonHash([this.amount, this.blinding, this.keypair.pubkey])
|
||||
@ -18,6 +30,11 @@ class Utxo {
|
||||
return this._commitment
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns nullifier for this UTXO
|
||||
*
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
getNullifier() {
|
||||
if (!this._nullifier) {
|
||||
if (this.amount > 0 && (this.index === undefined || this.keypair.privkey === undefined || this.keypair.privkey === null)) {
|
||||
@ -28,18 +45,24 @@ class Utxo {
|
||||
return this._nullifier
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt UTXO data using the current keypair
|
||||
*
|
||||
* @returns {string} `0x`-prefixed hex string with data
|
||||
*/
|
||||
encrypt() {
|
||||
const blindingBuf = Buffer.from(this.blinding.toHexString().slice(2), 'hex')
|
||||
const amountBuf = Buffer.from(this.amount.toHexString().slice(2), 'hex')
|
||||
const bytes = Buffer.concat([
|
||||
Buffer.alloc(31 - blindingBuf.length),
|
||||
blindingBuf,
|
||||
Buffer.alloc(31 - amountBuf.length),
|
||||
amountBuf,
|
||||
])
|
||||
const bytes = Buffer.concat([toBuffer(this.blinding, 31), toBuffer(this.amount, 31)])
|
||||
return this.keypair.encrypt(bytes)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt a UTXO
|
||||
*
|
||||
* @param {Keypair} keypair keypair used to decrypt
|
||||
* @param {string} data hex string with data
|
||||
* @param {number} index UTXO index in merkle tree
|
||||
* @returns {Utxo}
|
||||
*/
|
||||
static decrypt(keypair, data, index) {
|
||||
const buf = keypair.decrypt(data)
|
||||
return new Utxo({
|
||||
|
@ -8,8 +8,6 @@ const {
|
||||
toFixedHex,
|
||||
takeSnapshot,
|
||||
revertSnapshot,
|
||||
packEncryptedMessage,
|
||||
unpackEncryptedMessage,
|
||||
} = require('../src/utils')
|
||||
const Utxo = require('../src/utxo')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user