UNPKG

@okxweb3/crypto-lib

Version:

A base package for @okxweb3/coin-*

177 lines 6.98 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ed25519_getDerivedPrivateKey = exports.isValidPath = exports.ed25519_getRandomPrivateKey = exports.ed25519SignTest = exports.fromSecret = exports.fromSeed = exports.privateKeyVerify = exports.publicKeyVerify = exports.publicKeyCreate = exports.verify = exports.sign = exports.ed25519MulBase = void 0; const elliptic = __importStar(require("../elliptic")); const base_1 = require("../base"); const bn_js_1 = __importDefault(require("bn.js")); const bip39_1 = require("../bip39"); const ed25519 = new elliptic.eddsa('ed25519'); const curve = ed25519.curve; function ed25519MulBase(scalar) { const G = ed25519.curve.g; return ed25519.encodePoint(G.mul(elliptic.utils.intFromLE(scalar))); } exports.ed25519MulBase = ed25519MulBase; function sign(message, secretKey) { let pk = secretKey; if (pk.length == 64) { pk = pk.slice(0, 32); } const key = ed25519.keyFromSecret(Array.from(pk)); const signature = key.sign(Array.from(message)).toBytes(); return Uint8Array.from(signature); } exports.sign = sign; function verify(message, signature, publicKey) { const key = ed25519.keyFromPublic(Array.from(publicKey)); return key.verify(Array.from(message), Array.from(signature)); } exports.verify = verify; function publicKeyCreate(secretKey) { let pk = secretKey; if (pk.length == 64) { pk = pk.slice(0, 32); } const key = ed25519.keyFromSecret(Array.from(pk)); let pubKey = key.getPublic(); if (secretKey.length == 64 && !areUint8ArraysEqual(secretKey.slice(32, 64), pubKey)) { throw new Error("invalid public key"); } return Uint8Array.from(pubKey); } exports.publicKeyCreate = publicKeyCreate; function areUint8ArraysEqual(arr1, arr2) { if (arr1.length !== arr2.length) { return false; } for (let i = 0; i < arr1.length; i++) { if (arr1[i] !== arr2[i]) { return false; } } return true; } function publicKeyVerify(pubkey) { const point = ed25519.decodePoint(Array.from(pubkey)); return curve.validate(point); } exports.publicKeyVerify = publicKeyVerify; function privateKeyVerify(seckey) { const bn = new bn_js_1.default(Array.from(seckey)); return bn.cmp(curve.n) < 0 && !bn.isZero(); } exports.privateKeyVerify = privateKeyVerify; function fromSeed(seed) { const key = ed25519.keyFromSecret(Array.from(seed)); const pk = Uint8Array.from(key.getPublic()); return { publicKey: pk, secretKey: (0, base_1.concatBytes)(seed, pk) }; } exports.fromSeed = fromSeed; function fromSecret(secretKey) { const privateKey = secretKey.slice(0, 32); const key = ed25519.keyFromSecret(Array.from(privateKey)); return { publicKey: Uint8Array.from(key.getPublic()), secretKey: Uint8Array.from(privateKey) }; } exports.fromSecret = fromSecret; function ed25519SignTest(privateKey) { const msgHash = (0, base_1.sha256)("ed25519-test"); const publicKey = publicKeyCreate(privateKey); const signature = sign(msgHash, privateKey); return verify(msgHash, signature, publicKey); } exports.ed25519SignTest = ed25519SignTest; function ed25519_getRandomPrivateKey(concatPub, encode) { while (true) { const randBytes = (0, base_1.randomBytes)(32); if (privateKeyVerify(randBytes)) { if (ed25519SignTest(randBytes)) { const publicKey = publicKeyCreate(randBytes); const privateKey = concatPub ? (0, base_1.concatBytes)(randBytes, publicKey) : randBytes; return encode === "base58" ? (0, base_1.toBase58)(privateKey) : (0, base_1.toHex)(privateKey); } } } } exports.ed25519_getRandomPrivateKey = ed25519_getRandomPrivateKey; const pathRegex = new RegExp("^m(\\/[0-9]+')+$"); const replaceDerive = (val) => val.replace("'", ''); const HARDENED_OFFSET = 0x80000000; function getMasterKeyFromSeed(seed) { const I = (0, base_1.hmacSHA512)("ed25519 seed", seed); const IL = I.slice(0, 32); const IR = I.slice(32); return { key: IL, chainCode: IR, }; } function CKDPriv({ key, chainCode }, index) { const indexBuffer = Buffer.allocUnsafe(4); indexBuffer.writeUInt32BE(index, 0); const data = Buffer.concat([Buffer.alloc(1, 0), key, indexBuffer]); const I = (0, base_1.hmacSHA512)(chainCode, data); const IL = I.slice(0, 32); const IR = I.slice(32); return { key: IL, chainCode: IR, }; } const isValidPath = (path) => { if (!pathRegex.test(path)) { return false; } return !path .split('/') .slice(1) .map(replaceDerive) .some(isNaN); }; exports.isValidPath = isValidPath; function derivePath(path, seed, offset = HARDENED_OFFSET) { if (!(0, exports.isValidPath)(path)) { throw new Error('Invalid derivation path'); } const { key, chainCode } = getMasterKeyFromSeed(seed); const segments = path .split('/') .slice(1) .map(replaceDerive) .map(el => parseInt(el, 10)); return segments.reduce((parentKeys, segment) => CKDPriv(parentKeys, segment + offset), { key, chainCode }); } async function ed25519_getDerivedPrivateKey(mnemonic, hdPath, concatPub, encode) { const seed = await (0, bip39_1.mnemonicToSeed)(mnemonic); const derivedSeed = derivePath(hdPath, seed).key; const publicKey = publicKeyCreate(derivedSeed); const privateKey = concatPub ? (0, base_1.concatBytes)(derivedSeed, publicKey) : derivedSeed; return encode === 'base58' ? Promise.resolve((0, base_1.toBase58)(privateKey)) : Promise.resolve((0, base_1.toHex)(privateKey)); } exports.ed25519_getDerivedPrivateKey = ed25519_getDerivedPrivateKey; //# sourceMappingURL=ed25519.js.map