UNPKG

navio-blsct

Version:

TypeScript bindings for the `libblsct` library used by the [Navio](https://nav.io/) blockchain to construct confidential transactions based on the BLS12-381 curve.

262 lines (234 loc) 7.79 kB
import { addToRangeProofVec, addToAmountRecoveryReqVec, addToUint64Vec, buildRangeProof, createAmountRecoveryReqVec, castToRangeProof, createRangeProofVec, createUint64Vec, deserializeRangeProof, deleteAmountRecoveryReqVec, deleteAmountsRetVal, deleteRangeProofVec, deleteUint64Vec, freeObj, genAmountRecoveryReq, getAmountRecoveryResultAmount, getAmountRecoveryResultIsSucc, getAmountRecoveryResultMsg, getAmountRecoveryResultSize, getRangeProof_A, getRangeProof_alpha_hat, getRangeProof_A_wip, getRangeProof_B, getRangeProof_delta_prime, getRangeProof_r_prime, getRangeProof_s_prime, getRangeProof_tau_x, recoverAmount, serializeRangeProof, verifyRangeProofs, } from './blsct' import { AmountRecoveryReq } from './amountRecoveryReq' import { AmountRecoveryRes } from './amountRecoveryRes' import { ManagedObj } from './managedObj' import { Point } from './point' import { Scalar } from './scalar' import { TokenId } from './tokenId' /** Represents a (possibly aggregated) range proof for one or more confidential transaction amounts. * * Examples: * ```ts * const { RangeProof, AmountRecoveryReq, AmountRecoveryRes, Point, TokenId } = require('navio-blsct') * const nonce = Point.random() * const tokenId = TokenId.default() * const rp = RangeProof.generate([456], nonce, 'navio', tokenId) * RangeProof.verifyProofs([rp]) // true * const req = new AmountRecoveryReq(rp, nonce) * const res = RangeProof.recoverAmounts([req1]) * res[0].isSucc // true * res[0].amount // 456 * res[0].message // 'navio' * rp.get_A() // Point object representing A * rp.get_A_wip() // Point object representing A_wip * rp.get_B() // Point object representing B * rp.get_r_prime() // Scalar object representing r' * rp.get_s_prime() // Scalar object representing s' * rp.get_delta_prime() // Scalar object representing delta' * rp.get_alpha_hat() // Scalar object representing alpha_hat * rp.get_tau_x() // Scalar object representing tau_x * const ser = rp.serialize() * const deser = RangeProof.deserialize(ser) * ser === deser.serialize() // true * ``` */ export class RangeProof extends ManagedObj { constructor(obj: any) { super(obj) } /** Generates a range proof for the given amounts, nonce, and message. * @param amounts - An array of amounts to be included in the range proof. * @param nonce - A nonce used to generate the range proof. * @param msg - A message associated with the range proof. * @param tokenId - An optional token ID. If not provided, a default token ID is used. * @returns A new `RangeProof` instance containing the generated range proof. */ static generate( amounts: number[], nonce: Point, msg: string, tokenId?: TokenId, ): RangeProof { tokenId = tokenId ?? TokenId.default() const vec = createUint64Vec() for (const amount of amounts) { addToUint64Vec(vec, amount) } const rv = buildRangeProof( vec, nonce.value(), msg, tokenId.value(), ) deleteUint64Vec(vec) if (rv.result !== 0) { const msg = `Building range proof failed. Error code = ${rv.result}` freeObj(rv) throw new Error(msg) } const x = RangeProof.fromObjAndSize( rv.value, rv.value_size, ) freeObj(rv) return x } /** Verifies a list of range proofs. * @param proofs - An array of `RangeProof` instances to be verified. * @returns `true` if all proofs are valid, `false` otherwise. */ static verifyProofs(proofs: RangeProof[]): boolean { const vec = createRangeProofVec() for (const proof of proofs) { addToRangeProofVec(vec, proof.value(), proof.size()) } const rv = verifyRangeProofs(vec) if (rv.result !== 0) { const msg = `Verifying range proofs failed. Error code = ${rv.result}` freeObj(rv) throw new Error(msg) } deleteRangeProofVec(vec) return rv.value } /** Recovers amounts from a list of `AmountRecoveryReq` instances. * @param reqs - An array of `AmountRecoveryReq` instances containing range proofs and nonces. * @returns An array of `AmountRecoveryRes` instances containing the recovery results. */ recoverAmounts(reqs: AmountRecoveryReq[]): AmountRecoveryRes[] { const reqVec = createAmountRecoveryReqVec() for (const req of reqs) { const blsctReq = genAmountRecoveryReq( req.rangeProof.value(), req.rangeProof.size(), req.nonce.value(), ) addToAmountRecoveryReqVec(reqVec, blsctReq) } const rv = recoverAmount(reqVec) deleteAmountRecoveryReqVec(reqVec) if (rv.result !== 0) { const msg = `Recovering amount failed. Error code = ${rv.result}` deleteAmountsRetVal(rv) throw new Error(msg) } let results: AmountRecoveryRes[] = [] const size = getAmountRecoveryResultSize(rv.value) for (let i=0; i<size; ++i) { const isSucc = getAmountRecoveryResultIsSucc(rv.value, i) const amount = getAmountRecoveryResultAmount(rv.value, i) const msg = getAmountRecoveryResultMsg(rv.value, i) const x = new AmountRecoveryRes( isSucc, amount, msg, ) results.push(x) } deleteAmountsRetVal(rv) return results } override value(): any { return castToRangeProof(this.obj) } override serialize(): string { return serializeRangeProof(this.value(), this.size()) } /** Deserializes a hexadecimal string into a `RangeProof` instance. * @param hex - A hexadecimal string representing the serialized range proof. * @returns A new `RangeProof` instance containing the deserialized data. */ static deserialize( this: new (obj: any) => RangeProof, hex: string ): RangeProof { return RangeProof._deserialize(hex, deserializeRangeProof) } /** Returns the A point of the range proof. * @returns A `Point` object representing the A point. */ get_A(): Point { const obj = getRangeProof_A(this.value(), this.size()) return Point.fromObj(obj) } /** Returns the A_wip point of the range proof. * @returns A `Point` object representing the A_wip point. */ get_A_wip(): Point { const obj = getRangeProof_A_wip(this.value(), this.size()) return Point.fromObj(obj) } /** Returns the B point of the range proof. * @returns A `Point` object representing the B point. */ get_B(): Point { const obj = getRangeProof_B(this.value(), this.size()) return Point.fromObj(obj) } /** Returns the r' scalar of the range proof. * @returns A `Scalar` object representing the r' scalar. */ get_r_prime(): Scalar { const obj = getRangeProof_r_prime(this.value(), this.size()) return Scalar.fromObj(obj) } /** Returns the s' scalar of the range proof. * @returns A `Scalar` object representing the s' scalar. */ get_s_prime(): Scalar { const obj = getRangeProof_s_prime(this.value(), this.size()) return Scalar.fromObj(obj) } /** Returns the tau_x scalar of the range proof. * @returns A `Scalar` object representing the tau_x scalar. */ get_delta_prime(): Scalar { const obj = getRangeProof_delta_prime(this.value(), this.size()) return Scalar.fromObj(obj) } /** Returns the alpha_hat scalar of the range proof. * @returns A `Scalar` object representing the alpha_hat scalar. */ get_alpha_hat(): Scalar { const obj = getRangeProof_alpha_hat(this.value(), this.size()) return Scalar.fromObj(obj) } /** Returns the tau_x scalar of the range proof. * @returns A `Scalar` object representing the t_aux scalar. */ get_tau_x(): Scalar { const obj = getRangeProof_tau_x(this.value(), this.size()) return Scalar.fromObj(obj) } }