@taquito/signer
Version:
Software signer implementations and signing utilities for Taquito.
197 lines (196 loc) • 8.17 kB
JavaScript
"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();