UNPKG

@hiero-ledger/cryptography

Version:

Cryptographic utilities and primitives for the Hiero SDK

205 lines (186 loc) 6.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _EcdsaPublicKey = _interopRequireDefault(require("./EcdsaPublicKey.cjs")); var hex = _interopRequireWildcard(require("./encoding/hex.cjs")); var ecdsa = _interopRequireWildcard(require("./primitive/ecdsa.cjs")); var bip32 = _interopRequireWildcard(require("./primitive/bip32.cjs")); var _array = require("./util/array.cjs"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const derPrefix = "3030020100300706052b8104000a04220420"; const derPrefixBytes = hex.decode(derPrefix); const derPrefix2 = "30540201010420"; const derPrefixBytes2 = hex.decode(derPrefix2); /** * @typedef {object} KeyPair * @property {Uint8Array} publicKey * @property {Uint8Array} privateKey */ class EcdsaPrivateKey { /** * @hideconstructor * @internal * @param {KeyPair} keyPair * @param {(Uint8Array)=} chainCode */ constructor(keyPair, chainCode) { /** * @type {KeyPair} * @readonly * @private */ this._keyPair = keyPair; /** * @type {?Uint8Array} * @readonly */ this._chainCode = chainCode != null ? chainCode : null; } /** * @returns {string} */ get _type() { return "secp256k1"; } /** * Generate a random ECDSA private key. * @returns {EcdsaPrivateKey} */ static generate() { return new EcdsaPrivateKey(ecdsa.generate()); } /** * Generate a random Ed25519 private key. * @returns {Promise<EcdsaPrivateKey>} */ static async generateAsync() { return new EcdsaPrivateKey(await ecdsa.generateAsync()); } /** * Construct a private key from bytes. * @param {Uint8Array} data * @returns {EcdsaPrivateKey} */ static fromBytes(data) { switch (data.length) { case 32: return EcdsaPrivateKey.fromBytesRaw(data); default: return EcdsaPrivateKey.fromBytesDer(data); } } /** * Construct a private key from bytes. * @param {Uint8Array} data * @returns {EcdsaPrivateKey} */ static fromBytesDer(data) { /** @type {Uint8Array} */ let ecdsaPrivateKeyBytes = new Uint8Array(); if ((0, _array.arrayStartsWith)(data, derPrefixBytes)) { ecdsaPrivateKeyBytes = data.subarray(derPrefixBytes.length); } else { // For now, we assume that if we get to the `else` statement // the lengths of all other bytePrefixes is equal, so we treat them equally ecdsaPrivateKeyBytes = data.subarray(derPrefixBytes2.length, derPrefixBytes2.length + 32); } return new EcdsaPrivateKey(ecdsa.fromBytes(ecdsaPrivateKeyBytes)); } /** * Construct a private key from bytes. * @param {Uint8Array} data * @returns {EcdsaPrivateKey} */ static fromBytesRaw(data) { return new EcdsaPrivateKey(ecdsa.fromBytes(data)); } /** * Construct a private key from a hex-encoded string. * @param {string} text * @returns {EcdsaPrivateKey} */ static fromString(text) { return EcdsaPrivateKey.fromBytes(hex.decode(text)); } /** * Construct a private key from a hex-encoded string. * @param {string} text * @returns {EcdsaPrivateKey} */ static fromStringDer(text) { return EcdsaPrivateKey.fromBytesDer(hex.decode(text)); } /** * Construct a private key from a hex-encoded string. * @param {string} text * @returns {EcdsaPrivateKey} */ static fromStringRaw(text) { return EcdsaPrivateKey.fromBytesRaw(hex.decode(text)); } /** * Construct a ECDSA private key from a Uint8Array seed. * @param {Uint8Array} seed * @returns {Promise<EcdsaPrivateKey>} */ static async fromSeed(seed) { const { keyData, chainCode } = await bip32.fromSeed(seed); return new EcdsaPrivateKey(ecdsa.fromBytes(keyData), chainCode); } /** * Get the public key associated with this private key. * * The public key can be freely given and used by other parties to verify * the signatures generated by this private key. * @returns {EcdsaPublicKey} */ get publicKey() { return new _EcdsaPublicKey.default(this._keyPair.publicKey); } /** * Sign a message with this private key. * @param {Uint8Array} bytes * @returns {Uint8Array} - The signature bytes without the message */ sign(bytes) { return ecdsa.sign(this._keyPair.privateKey, bytes); } /** * @returns {Uint8Array} */ toBytesDer() { const bytes = new Uint8Array(derPrefixBytes.length + 32); const privateKey = this._keyPair.privateKey.subarray(0, 32); const leadingZeroes = 32 - privateKey.length; const privateKeyOffset = derPrefixBytes.length + leadingZeroes; bytes.set(derPrefixBytes, 0); bytes.set(privateKey, privateKeyOffset); return bytes; } /** * @returns {Uint8Array} */ toBytesRaw() { const privateKey = this._keyPair.privateKey.subarray(-32); // Takes the last 32 bytes (or fewer if shorter) const leadingZeroes = 32 - privateKey.length; const bytes = new Uint8Array(32); bytes.set(privateKey, leadingZeroes); return bytes; } /** * Recover the recovery ID used in the signature for the given message. * @param {Uint8Array} signature - 64-byte compact signature (r || s) * @param {Uint8Array} message - The original (unhashed) message * @returns {number} Recovery ID (0–3), or -1 if not found */ getRecoveryId(signature, message) { return ecdsa.getRecoveryId(this._keyPair.privateKey, signature, message); } } exports.default = EcdsaPrivateKey;