PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-lib-mpc/src/curves
Просмотр файла: ed25519Bip32HdTree.ts
import { createHmac } from 'crypto';
import { bigIntFromBufferBE, bigIntFromBufferLE, bigIntToBufferBE, bigIntToBufferLE } from '../util';
import { Ed25519Curve } from './ed25519';
import { PrivateKeychain, PublicKeychain } from './types';
import { pathToIndices } from './util';
import { chaincodeBase } from './constant';
export class Ed25519Bip32HdTree {
static curve: Ed25519Curve = new Ed25519Curve();
static initialized = false;
static async initialize(): Promise<Ed25519Bip32HdTree> {
if (!Ed25519Bip32HdTree.initialized) {
await Ed25519Curve.initialize();
Ed25519Bip32HdTree.initialized = true;
}
return new Ed25519Bip32HdTree();
}
publicDerive(keychain: PublicKeychain, path: string): PublicKeychain {
const indices = pathToIndices(path);
function deriveIndex(acc: bigint[], index: number | undefined): bigint[] {
const [pk, chaincode] = acc;
const [zout, iout] = deriveEd25519Helper(index, chaincode, pk);
const zl = zout.slice(0, 32);
// left = kl + 8 * trunc28(zl)
const t = BigInt(8) * bigIntFromBufferLE(zl.slice(0, 28));
const left = Ed25519Bip32HdTree.curve.pointAdd(pk, Ed25519Bip32HdTree.curve.basePointMult(t));
return [left, bigIntFromBufferBE(iout.slice(32))];
}
const subkey = indices.reduce(deriveIndex, deriveIndex([keychain.pk, keychain.chaincode], indices.shift()));
return { pk: subkey[0], chaincode: subkey[1] };
}
privateDerive(keychain: PrivateKeychain, path: string): PrivateKeychain {
const indices = pathToIndices(path);
function deriveIndex(acc: bigint[], index: number | undefined): bigint[] {
const [pk, sk, prefix, chaincode] = acc;
const [zout, iout] = deriveEd25519Helper(index, chaincode, pk, sk);
const zl = zout.slice(0, 32);
const zr = zout.slice(32);
// left = kl + 8 * trunc28(zl)
const t = BigInt(8) * bigIntFromBufferLE(zl.slice(0, 28));
const left_pk = Ed25519Bip32HdTree.curve.pointAdd(pk, Ed25519Bip32HdTree.curve.basePointMult(t));
const left_sk = Ed25519Bip32HdTree.curve.scalarAdd(sk, t);
// right = zr + kr
const right = (prefix + bigIntFromBufferBE(zr)) % chaincodeBase;
return [left_pk, left_sk, right, bigIntFromBufferBE(iout.slice(32))];
}
const [pk, sk, prefix, chaincode] = indices.reduce(
deriveIndex,
deriveIndex([keychain.pk, keychain.sk, keychain.prefix!, keychain.chaincode], indices.shift())
);
return { pk, sk, prefix, chaincode };
}
}
function deriveEd25519Helper(index: number | undefined = 0, chaincode: bigint, pk: bigint, sk?: bigint): Buffer[] {
const zmac = createHmac('sha512', bigIntToBufferBE(chaincode, 32));
const imac = createHmac('sha512', bigIntToBufferBE(chaincode, 32));
const seri = Buffer.alloc(4);
seri.writeUInt32LE(index, 0);
if (((index >>> 0) & 0x80000000) === 0) {
// Normal derivation:
// Z = HMAC-SHA512(Key = cpar, Data = 0x02 || serP(point(kpar)) || ser32(i)).
// I = HMAC-SHA512(Key = cpar, Data = 0x03 || serP(point(kpar)) || ser32(i)).
zmac.update('\x02');
zmac.update(bigIntToBufferLE(pk, 32));
zmac.update(seri);
imac.update('\x03');
imac.update(bigIntToBufferLE(pk, 32));
imac.update(seri);
} else {
if (sk === undefined) {
throw new Error("Can't performed hardened derivation without private key");
}
// Hardened derivation:
// Z = HMAC-SHA512(Key = cpar, Data = 0x00 || ser256(left(kpar)) || ser32(i)).
// I = HMAC-SHA512(Key = cpar, Data = 0x01 || ser256(left(kpar)) || ser32(i)).
zmac.update('\x00');
zmac.update(bigIntToBufferLE(sk, 32));
zmac.update(seri);
imac.update('\x01');
imac.update(bigIntToBufferLE(sk, 32));
imac.update(seri);
}
return [zmac.digest(), imac.digest()];
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!