forked from tornadocash/classic-ui
102 lines
2.9 KiB
JavaScript
102 lines
2.9 KiB
JavaScript
import crypto from 'crypto'
|
|
import { BN, toBN } from 'web3-utils'
|
|
|
|
import { pedersen } from '@/services'
|
|
|
|
const CUT_LENGTH = 31
|
|
|
|
export function parseNote(note) {
|
|
const [, currency, amount, netId, hexNote] = note.split('-')
|
|
|
|
return {
|
|
...parseHexNote(hexNote),
|
|
netId,
|
|
amount,
|
|
currency
|
|
}
|
|
}
|
|
|
|
export function parseHexNote(hexNote) {
|
|
const buffNote = Buffer.from(hexNote.slice(2), 'hex')
|
|
|
|
const commitment = buffPedersenHash(buffNote)
|
|
|
|
const nullifierBuff = buffNote.slice(0, CUT_LENGTH)
|
|
const nullifierHash = BigInt(buffPedersenHash(nullifierBuff))
|
|
const nullifier = BigInt(leInt2Buff(buffNote.slice(0, CUT_LENGTH)))
|
|
|
|
const secret = BigInt(leInt2Buff(buffNote.slice(CUT_LENGTH, CUT_LENGTH * 2)))
|
|
|
|
return {
|
|
secret,
|
|
nullifier,
|
|
commitment,
|
|
nullifierBuff,
|
|
nullifierHash,
|
|
commitmentHex: toFixedHex(commitment),
|
|
nullifierHex: toFixedHex(nullifierHash)
|
|
}
|
|
}
|
|
|
|
export function leInt2Buff(value) {
|
|
return new BN(value, 16, 'le')
|
|
}
|
|
|
|
export function randomBN(nbytes = 31) {
|
|
return toBN(leInt2Buff(crypto.randomBytes(nbytes)).toString())
|
|
}
|
|
|
|
export function buffPedersenHash(buffer) {
|
|
const [hash] = pedersen.unpackPoint(buffer)
|
|
return pedersen.toStringBuffer(hash)
|
|
}
|
|
|
|
export function toFixedHex(value, length = 32) {
|
|
const isBuffer = value instanceof Buffer
|
|
|
|
const str = isBuffer ? value.toString('hex') : BigInt(value).toString(16)
|
|
return '0x' + str.padStart(length * 2, '0')
|
|
}
|
|
|
|
export const isEmptyArray = (arr) => !Array.isArray(arr) || !arr.length
|
|
|
|
export 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')
|
|
}
|
|
|
|
export 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')
|
|
}
|
|
}
|
|
|
|
export function checkCommitments(events = []) {
|
|
events.forEach(({ leafIndex }, i) => {
|
|
// TODO reload events, need for if infura provider missing events
|
|
if (leafIndex !== i) {
|
|
console.error(`Missing deposit event for deposit #${i}`)
|
|
throw new Error(window.$nuxt.$t('failedToFetchAllDepositEvents'))
|
|
}
|
|
})
|
|
}
|