@pgchain/blockchain-libs
Version:
PGWallet Blockchain Libs
142 lines • 5.03 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ED25519Bip32KeyDeriver = exports.BaseBip32KeyDeriver = exports.parse256 = exports.ser256 = void 0;
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const hash_1 = require("./hash");
const BigInt_0 = new bignumber_js_1.default(0);
function serNum(p, bits) {
if (p.lt(BigInt_0) || p.gte(new bignumber_js_1.default(2).pow(bits))) {
throw Error('Overflowed.');
}
const size = bits / 8;
return Buffer.from(p.toString(16).padStart(size * 2, '0'), 'hex');
}
function ser32(index) {
if (!Number.isInteger(index)) {
throw Error('Invalid index.');
}
return serNum(new bignumber_js_1.default(index), 32);
}
function ser256(p) {
return serNum(p, 256);
}
exports.ser256 = ser256;
function parse256(seq) {
if (seq.length != 32) {
throw Error('Invalid sequence');
}
return new bignumber_js_1.default('0x' + seq.toString('hex'));
}
exports.parse256 = parse256;
function isHardenedIndex(index) {
if (!Number.isInteger(index) || index < 0 || index >= 2 ** 32) {
throw Error('Invalid index.');
}
return index >= 2 ** 31;
}
function N(curve, privateKey) {
const msgHash = Buffer.from('Hello OneKey');
const publicKey = curve.publicFromPrivate(privateKey);
if (!curve.verify(publicKey, msgHash, curve.sign(privateKey, msgHash))) {
throw Error('Failed to generate public key from private.');
}
return publicKey;
}
class BaseBip32KeyDeriver {
/* NOTE: The retrying in key generation (in both master key generation
* and CKD functions) doesn't follow BIP-0032 but SLIP-0010. */
constructor(key, curve) {
this.key = key;
this.curve = curve;
}
generateMasterKeyFromSeed(seed) {
const I = (0, hash_1.hmacSHA512)(this.key, seed);
const IL = I.slice(0, 32);
const chainCode = I.slice(32, 64);
const parsedIL = parse256(IL);
if (parsedIL.lt(this.curve.groupOrder) && !parsedIL.eq(BigInt_0)) {
return { key: IL, chainCode: chainCode };
}
return this.generateMasterKeyFromSeed(I);
}
N(extPriv) {
return {
key: N(this.curve, extPriv.key),
chainCode: extPriv.chainCode,
};
}
CKDPriv(parent, index) {
const data = Buffer.alloc(37);
data.fill(ser32(index), 33, 37);
if (isHardenedIndex(index)) {
data.fill(parent.key, 1, 33);
}
else {
data.fill(this.curve.publicFromPrivate(parent.key), 0, 33);
}
for (;;) {
const I = (0, hash_1.hmacSHA512)(parent.chainCode, data);
const IR = I.slice(32, 64);
const parsedIL = parse256(I.slice(0, 32));
const childKey = parsedIL
.plus(parse256(parent.key))
.mod(this.curve.groupOrder);
if (parsedIL.lt(this.curve.groupOrder) && !childKey.eq(BigInt_0)) {
return { key: ser256(childKey), chainCode: IR };
}
data[0] = 1;
data.fill(IR, 1, 33);
}
}
CKDPub(parent, index) {
if (isHardenedIndex(index)) {
throw Error(`Can't derive public key for index ${index}.`);
}
const data = Buffer.alloc(37);
data.fill(parent.key, 0, 33);
data.fill(ser32(index), 33, 37);
for (;;) {
const I = (0, hash_1.hmacSHA512)(parent.chainCode, data);
const IL = I.slice(0, 32);
const IR = I.slice(32, 64);
const childKey = this.curve.getChildPublicKey(IL, parent.key);
if (childKey !== null) {
return { key: childKey, chainCode: IR };
}
data[0] = 1;
data.fill(IR, 1, 33);
}
}
}
exports.BaseBip32KeyDeriver = BaseBip32KeyDeriver;
class ED25519Bip32KeyDeriver {
constructor(key, curve) {
this.key = key;
this.curve = curve;
}
generateMasterKeyFromSeed(seed) {
const I = (0, hash_1.hmacSHA512)(this.key, seed);
return { key: I.slice(0, 32), chainCode: I.slice(32, 64) };
}
N(extPriv) {
return { key: N(this.curve, extPriv.key), chainCode: extPriv.chainCode };
}
CKDPriv(parent, index) {
if (!isHardenedIndex(index)) {
throw Error('Only hardened CKDPriv is supported for ed25519.');
}
const data = Buffer.alloc(37);
data.fill(parent.key, 1, 33);
data.fill(ser32(index), 33, 37);
const I = (0, hash_1.hmacSHA512)(parent.chainCode, data);
return { key: I.slice(0, 32), chainCode: I.slice(32, 64) };
}
CKDPub(parent, index) {
throw Error('CKDPub is not supported for ed25519.');
}
}
exports.ED25519Bip32KeyDeriver = ED25519Bip32KeyDeriver;
//# sourceMappingURL=bip32.js.map