@taquito/signer
Version:
Software signer implementations and signing utilities for Taquito.
83 lines (82 loc) • 3.02 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrivateKey = void 0;
/* eslint-disable @typescript-eslint/no-this-alias */
const hmac_js_1 = require("@noble/hashes/hmac.js");
const sha2_js_1 = require("@noble/hashes/sha2.js");
const ed25519_1 = require("@noble/curves/ed25519");
const types_1 = require("./types");
const utils_1 = require("./utils");
const errors_1 = require("../errors");
const core_1 = require("@taquito/core");
function generateKeyPairFromSeed(seed) {
const publicKey = ed25519_1.ed25519.getPublicKey(seed);
const secretKey = new Uint8Array(64);
secretKey.set(seed);
secretKey.set(publicKey, 32);
return { secretKey, publicKey };
}
// MinSeedSize is the minimal allowed seed byte length
const minSeedSize = 16;
// MaxSeedSize is the maximal allowed seed byte length
const maxSeedSize = 64;
const ed25519Key = 'ed25519 seed';
class PrivateKey {
/**
*
* @param priv generated keypair 0->32 private key 32->n public key
* @param chainCode new HMAC hash with new key
*/
constructor(priv, chainCode) {
this.priv = priv;
this.chainCode = chainCode;
}
/**
*
* @param seedSrc result of Bip39.mnemonicToSeed
* @returns instance of PrivateKey
* @throws InvalidSeedLengthError
*/
static fromSeed(seedSrc) {
const seed = typeof seedSrc === 'string' ? (0, utils_1.parseHex)(seedSrc) : seedSrc;
if (seed.length < minSeedSize || seed.length > maxSeedSize) {
throw new errors_1.InvalidSeedLengthError(seed.length);
}
const key = new TextEncoder().encode(ed25519Key);
const sum = (0, hmac_js_1.hmac)(sha2_js_1.sha512, key, seed);
return new PrivateKey(generateKeyPairFromSeed(sum.subarray(0, 32)).secretKey, sum.subarray(32));
}
/**
*
* @returns slice(0, 32) of current priv for new seed for next derived priv
*/
seed() {
return this.priv.subarray(0, 32);
}
/**
\* @remarks index: current derivation path item ie: 1729'
* @returns derivation path child of original private key pair
*/
derive(index) {
if ((index & types_1.Hard) === 0) {
throw new core_1.InvalidDerivationPathError(index.toString(), ': Non-hardened derivation path.');
}
const data = new Uint8Array(37);
data.set(this.seed(), 1);
new DataView(data.buffer).setUint32(33, index);
const sum = (0, hmac_js_1.hmac)(sha2_js_1.sha512, this.chainCode, data);
return new PrivateKey(generateKeyPairFromSeed(sum.subarray(0, 32)).secretKey, sum.subarray(32));
}
/**
* @param path array of numbers pre adjusted for hardened paths ie: 44' -> 2^31 + 44
* @returns final child of full derivation path private key pair
*/
derivePath(path) {
let key = this;
for (const index of path) {
key = key.derive(index);
}
return key;
}
}
exports.PrivateKey = PrivateKey;