"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Secp256k1 = void 0; const encoding_1 = require("@cosmjs/encoding"); const utils_1 = require("@cosmjs/utils"); const secp256k1_1 = require("@noble/curves/secp256k1"); const secp256k1signature_1 = require("./secp256k1signature"); function unsignedBigIntToBytes(a) { (0, utils_1.assert)(a >= 0n); let hex = a.toString(16); if (hex.length % 2) hex = "0" + hex; return (0, encoding_1.fromHex)(hex); } function bytesToUnsignedBigInt(a) { return BigInt("0x" + (0, encoding_1.toHex)(a)); } class Secp256k1 { /** * Takes a 32 byte private key and returns a privkey/pubkey pair. * * The resulting pubkey is uncompressed. For the use in Cosmos it should * be compressed first using `Secp256k1.compressPubkey`. */ static async makeKeypair(privkey) { if (privkey.length !== 32) { throw new Error("input data is not a valid secp256k1 private key"); } if (!secp256k1_1.secp256k1.utils.isValidPrivateKey(privkey)) { // not strictly smaller than N throw new Error("input data is not a valid secp256k1 private key"); } const out = { privkey: privkey, // encodes uncompressed as // - 1-byte prefix "04" // - 32-byte x coordinate // - 32-byte y coordinate pubkey: secp256k1_1.secp256k1.getPublicKey(privkey, false), }; return out; } /** * Creates a signature that is * - deterministic (RFC 6979) * - lowS signature * - DER encoded */ static async createSignature(messageHash, privkey) { if (messageHash.length === 0) { throw new Error("Message hash must not be empty"); } if (messageHash.length > 32) { throw new Error("Message hash length must not exceed 32 bytes"); } const { recovery, r, s } = secp256k1_1.secp256k1.sign(messageHash, privkey, { lowS: true, }); if (typeof recovery !== "number") throw new Error("Recovery param missing"); return new secp256k1signature_1.ExtendedSecp256k1Signature(unsignedBigIntToBytes(r), unsignedBigIntToBytes(s), recovery); } static async verifySignature(signature, messageHash, pubkey) { if (messageHash.length === 0) { throw new Error("Message hash must not be empty"); } if (messageHash.length > 32) { throw new Error("Message hash length must not exceed 32 bytes"); } const encodedSig = secp256k1_1.secp256k1.Signature.fromDER(signature.toDer()); return secp256k1_1.secp256k1.verify(encodedSig, messageHash, pubkey, { lowS: false }); } static recoverPubkey(signature, messageHash) { const pk = new secp256k1_1.secp256k1.Signature(bytesToUnsignedBigInt(signature.r()), bytesToUnsignedBigInt(signature.s()), signature.recovery).recoverPublicKey(messageHash); return pk.toBytes(false); } /** * Takes a compressed or uncompressed pubkey and return a compressed one. * * This function is idempotent. */ static compressPubkey(pubkey) { switch (pubkey.length) { case 33: return pubkey; case 65: return secp256k1_1.secp256k1.Point.fromBytes(pubkey).toBytes(true); default: throw new Error("Invalid pubkey length"); } } /** * Takes a compressed or uncompressed pubkey and returns an uncompressed one. * * This function is idempotent. */ static uncompressPubkey(pubkey) { switch (pubkey.length) { case 33: return secp256k1_1.secp256k1.Point.fromBytes(pubkey).toBytes(false); case 65: return pubkey; default: throw new Error("Invalid pubkey length"); } } static trimRecoveryByte(signature) { switch (signature.length) { case 64: return signature; case 65: return signature.slice(0, 64); default: throw new Error("Invalid signature length"); } } } exports.Secp256k1 = Secp256k1; //# sourceMappingURL=secp256k1.js.map