UNPKG

@taquito/signer

Version:

Software signer implementations and signing utilities for Taquito.

197 lines (196 loc) 8.17 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _ECKey_keyPair, _ECPublicKey_key; Object.defineProperty(exports, "__esModule", { value: true }); exports.ECPublicKey = exports.ECKey = void 0; const blake2_js_1 = require("@noble/hashes/blake2.js"); const utils_1 = require("@taquito/utils"); const secp256k1_1 = require("@noble/curves/secp256k1"); const nist_js_1 = require("@noble/curves/nist.js"); const errors_1 = require("./errors"); const pref = { p256: { pk: utils_1.PrefixV2.P256PublicKey, sk: utils_1.PrefixV2.P256SecretKey, pkh: utils_1.PrefixV2.P256PublicKeyHash, sig: utils_1.PrefixV2.P256Signature, tag: 2, }, secp256k1: { pk: utils_1.PrefixV2.Secp256k1PublicKey, sk: utils_1.PrefixV2.Secp256k1SecretKey, pkh: utils_1.PrefixV2.Secp256k1PublicKeyHash, sig: utils_1.PrefixV2.Secp256k1Signature, tag: 1, }, }; /** * Provide signing logic for elliptic curve based key (tz2, tz3) */ class ECKey { /** * * @param key Encoded private key * @param decrypt Decrypt function * @throws InvalidKeyError */ constructor(key, decrypt) { _ECKey_keyPair.set(this, void 0); const [keyData, prefix] = (0, utils_1.b58DecodeAndCheckPrefix)(key, [ utils_1.PrefixV2.Secp256k1EncryptedSecretKey, utils_1.PrefixV2.P256EncryptedSecretKey, utils_1.PrefixV2.Secp256k1SecretKey, utils_1.PrefixV2.P256SecretKey, ]); const [decKey, curve] = (() => { switch (prefix) { case utils_1.PrefixV2.Secp256k1EncryptedSecretKey: case utils_1.PrefixV2.P256EncryptedSecretKey: if (decrypt === undefined) { throw new Error('decryption function is not provided'); } else { return [ decrypt(keyData), prefix === utils_1.PrefixV2.Secp256k1EncryptedSecretKey ? 'secp256k1' : 'p256', ]; } case utils_1.PrefixV2.Secp256k1SecretKey: return [keyData, 'secp256k1']; default: return [keyData, 'p256']; } })(); __classPrivateFieldSet(this, _ECKey_keyPair, { curve, secretKey: decKey, publicKey: curve === 'secp256k1' ? secp256k1_1.secp256k1.getPublicKey(decKey, true) : nist_js_1.p256.getPublicKey(decKey, true), }, "f"); } /** * * @param bytes Bytes to sign * @param bytesHash Blake2b hash of the bytes to sign */ sign(bytes) { const hash = (0, blake2_js_1.blake2b)(bytes, { dkLen: 32 }); let signature; if (__classPrivateFieldGet(this, _ECKey_keyPair, "f").curve === 'secp256k1') { signature = secp256k1_1.secp256k1 .sign(hash, __classPrivateFieldGet(this, _ECKey_keyPair, "f").secretKey, { lowS: true, // Use canonical signatures (prevents malleability) }) .toBytes('compact'); } else { signature = nist_js_1.p256 .sign(hash, __classPrivateFieldGet(this, _ECKey_keyPair, "f").secretKey, { lowS: true, // Use canonical signatures (prevents malleability) }) .toBytes('compact'); } return { rawSignature: signature, sig: (0, utils_1.b58Encode)(signature, utils_1.PrefixV2.GenericSignature), prefixSig: (0, utils_1.b58Encode)(signature, pref[__classPrivateFieldGet(this, _ECKey_keyPair, "f").curve].sig), }; } /** * @returns Encoded public key */ publicKey() { return new ECPublicKey(__classPrivateFieldGet(this, _ECKey_keyPair, "f").publicKey, __classPrivateFieldGet(this, _ECKey_keyPair, "f").curve); } /** * @returns Encoded private key */ secretKey() { return (0, utils_1.b58Encode)(__classPrivateFieldGet(this, _ECKey_keyPair, "f").secretKey, pref[__classPrivateFieldGet(this, _ECKey_keyPair, "f").curve].sk); } } exports.ECKey = ECKey; _ECKey_keyPair = new WeakMap(); class ECPublicKey { constructor(src, curve) { _ECPublicKey_key.set(this, void 0); const [key, crv] = (() => { if (typeof src === 'string') { const [key, pre] = (0, utils_1.b58DecodeAndCheckPrefix)(src, [ utils_1.PrefixV2.Secp256k1PublicKey, utils_1.PrefixV2.P256PublicKey, ]); return [key, pre === utils_1.PrefixV2.Secp256k1PublicKey ? 'secp256k1' : 'p256']; } else if (curve !== undefined) { return [src, curve]; } else { throw new errors_1.InvalidCurveError('missing curve type'); } })(); // For ECPublicKey, we don't need the private key, so we pass an empty array // The public key is stored separately __classPrivateFieldSet(this, _ECPublicKey_key, key, "f"); this.curve = crv; } compare(other) { if (other instanceof ECPublicKey) { if (this.curve === other.curve) { const compress = this.curve === 'secp256k1'; return (0, utils_1.compareArrays)(this.bytes(compress), other.bytes(compress)); } else if (this.curve === 'secp256k1') { return -1; } else { return 1; } } else { throw new utils_1.InvalidPublicKeyError('ECDSA key expected'); } } hash() { const key = this.bytes(); return (0, utils_1.b58Encode)((0, blake2_js_1.blake2b)(key, { dkLen: 20 }), pref[this.curve].pkh); } bytes(compress = true) { // @noble/curves supports both compressed and uncompressed formats // We need to convert the stored public key to the requested format if (this.curve === 'secp256k1') { // For secp256k1, we need to get the public key from the stored bytes and convert format const point = secp256k1_1.secp256k1.Point.fromHex(__classPrivateFieldGet(this, _ECPublicKey_key, "f")); return point.toBytes(compress); } else { // For p256, we need to get the public key from the stored bytes and convert format const point = nist_js_1.p256.Point.fromHex(__classPrivateFieldGet(this, _ECPublicKey_key, "f")); return point.toBytes(compress); } } toProtocol() { const key = this.bytes(); const res = new Uint8Array(key.length + 1); res[0] = pref[this.curve].tag; res.set(key, 1); return res; } toString() { const key = this.bytes(); return (0, utils_1.b58Encode)(key, pref[this.curve].pk); } } exports.ECPublicKey = ECPublicKey; _ECPublicKey_key = new WeakMap();