documentation

This commit is contained in:
poma 2021-06-16 03:07:32 +03:00
parent f606016994
commit 922457d12b
No known key found for this signature in database
GPG Key ID: BA20CB01FE165657
4 changed files with 63 additions and 12 deletions

View File

@ -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')
}

View File

@ -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)

View File

@ -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({

View File

@ -8,8 +8,6 @@ const {
toFixedHex,
takeSnapshot,
revertSnapshot,
packEncryptedMessage,
unpackEncryptedMessage,
} = require('../src/utils')
const Utxo = require('../src/utxo')