@okxweb3/crypto-lib
Version:
A base package for @okxweb3/coin-*
177 lines • 6.98 kB
JavaScript
;
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