UNPKG

codechain-primitives

Version:
91 lines 3.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const _ = require("lodash"); /** * @hidden */ const EC = require("elliptic").ec; /** * @hidden */ const secp256k1 = new EC("secp256k1"); /** * Gets ECDSA signature for message from private key. * @param message 32 byte hexademical string * @param priv 32 byte hexadecimal string of private key * @returns 65 byte hexadecimal string of ECDSA signature */ exports.signEcdsa = (message, priv) => { if (!/^[0-9a-fA-F]{64}$/.test(message)) { throw new Error(`invalid message: ${message}`); } if (!/^[0-9a-fA-F]{64}$/.test(priv)) { throw new Error(`invalid private key: ${priv}`); } const key = secp256k1.keyFromPrivate(priv); const { r, s, recoveryParam: v } = key.sign(message, { canonical: true }); const paddedR = _.padStart(r.toString(16), 64, "0"); const paddedS = _.padStart(s.toString(16), 64, "0"); const paddedV = _.padStart(v.toString(16), 2, "0"); return `${paddedR}${paddedS}${paddedV}`; }; /** * Checks if the signature from signEcdsa is correct. * @param message 32 byte hexademical string * @param signature 65 byte hexadecimal string of ECDSA signature * @param pub 64 byte hexadecimal string of public key * @returns if signature is valid, true. Else false. */ exports.verifyEcdsa = (message, signature, pub) => { if (!/^[0-9a-fA-F]{64}$/.test(message)) { throw new Error(`invalid message: ${message}`); } if (!/^(0x)?[0-9a-fA-F]{130}$/.test(signature)) { throw new Error(`invalid signature: ${signature}`); } if (signature.startsWith("0x")) { signature = signature.substr(2); } const r = `${signature.substr(0, 64)}`; const s = `${signature.substr(64, 64)}`; const v = Number.parseInt(signature.substr(128, 2), 16); if (v < 0 || v > 3) { throw new Error(`invalid recoveryParam v: ${v}`); } if (!/^[0-9a-fA-F]{128}$/.test(pub)) { throw new Error(`invalid public key: ${pub}`); } const key = secp256k1.keyFromPublic("04" + pub, "hex"); return key.verify(message, { r, s, v }); }; /** * Gets public key from the message and ECDSA signature. * @param message 32 byte hexademical string * @param signature 65 byte hexadecimal string of ECDSA signature * @returns 64 byte hexadecimal string public key */ exports.recoverEcdsa = (message, signature) => { if (!/^[0-9a-fA-F]{64}$/.test(message)) { throw new Error(`invalid message: ${message}`); } if (!/^(0x)?[0-9a-fA-F]{130}$/.test(signature)) { throw new Error(`invalid signature: ${signature}`); } if (signature.startsWith("0x")) { signature = signature.substr(2); } const r = `${signature.substr(0, 64)}`; const s = `${signature.substr(64, 64)}`; const v = Number.parseInt(signature.substr(128, 2), 16); if (v < 0 || v > 3) { throw new Error(`invalid recoveryParam v: ${v}`); } return secp256k1 .recoverPubKey(secp256k1 .keyFromPrivate(message, "hex") .getPrivate() .toString(10), { r, s, v }, v) .encode("hex") .slice(2); }; //# sourceMappingURL=ecdsa.js.map