UNPKG

@bsv/sdk

Version:

BSV Blockchain Software Development Kit

98 lines 3.85 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const BigNumber_js_1 = __importDefault(require("./BigNumber.js")); const Curve_js_1 = __importDefault(require("./Curve.js")); const Hash_js_1 = require("./Hash.js"); const index_js_1 = require("./index.js"); /** * Class representing the Schnorr Zero-Knowledge Proof (ZKP) protocol. * * This class provides methods to generate and verify proofs that demonstrate knowledge of a secret without revealing it. * Specifically, it allows one party to prove to another that they know the private key corresponding to a public key * and have correctly computed a shared secret, without disclosing the private key itself. * * The protocol involves two main methods: * - `generateProof`: Generates a proof linking a public key `A` and a shared secret `S`, proving knowledge of the corresponding private key `a`. * - `verifyProof`: Verifies the provided proof, ensuring its validity without revealing any secret information. * * The class utilizes elliptic curve cryptography (ECC) and the SHA-256 hash function to compute challenges within the proof. * * @example * ```typescript * const schnorr = new Schnorr(); * const a = PrivateKey.fromRandom(); // Prover's private key * const A = a.toPublicKey(); // Prover's public key * const b = PrivateKey.fromRandom(); // Other party's private key * const B = b.toPublicKey(); // Other party's public key * const S = B.mul(a); // Shared secret * * // Prover generates the proof * const proof = schnorr.generateProof(a, A, B, S); * * // Verifier verifies the proof * const isValid = schnorr.verifyProof(A.point, B.point, S.point, proof); * console.log(`Proof is valid: ${isValid}`); * ``` */ class Schnorr { constructor() { this.curve = new Curve_js_1.default(); } /** * Generates a proof that demonstrates the link between public key A and shared secret S * @param a Private key corresponding to public key A * @param A Public key * @param B Other party's public key * @param S Shared secret * @returns Proof (R, S', z) */ generateProof(aArg, AArg, BArg, S) { const r = index_js_1.PrivateKey.fromRandom(); const R = r.toPublicKey(); const SPrime = BArg.mul(r); const e = this.computeChallenge(AArg, BArg, S, SPrime, R); const z = r.add(e.mul(aArg)).umod(this.curve.n); return { R, SPrime, z }; } /** * Verifies the proof of the link between public key A and shared secret S * @param A Public key * @param B Other party's public key * @param S Shared secret * @param proof Proof (R, S', z) * @returns True if the proof is valid, false otherwise */ verifyProof(A, B, S, proof) { const { R, SPrime, z } = proof; const e = this.computeChallenge(A, B, S, SPrime, R); // Check zG = R + eA const zG = this.curve.g.mul(z); const RpluseA = R.add(A.mul(e)); if (!zG.eq(RpluseA)) { return false; } // Check zB = S' + eS const zB = B.mul(z); const SprimeeS = SPrime.add(S.mul(e)); if (!zB.eq(SprimeeS)) { return false; } return true; } computeChallenge(A, B, S, SPrime, R) { const message = [ ...A.encode(true), ...B.encode(true), ...S.encode(true), ...SPrime.encode(true), ...R.encode(true) ]; const hash = (0, Hash_js_1.sha256)(message); return new BigNumber_js_1.default(hash).umod(this.curve.n); } } exports.default = Schnorr; //# sourceMappingURL=Schnorr.js.map