@alephium/web3-wallet
Version:
Simple wallets for Alephium
191 lines (187 loc) • 7 kB
JavaScript
;
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.bip32 = exports.ecc = void 0;
/*
* This file is copied from: https://github.com/BitGo/BitGoJS/blob/bitcoinjs_lib_6_sync/modules/utxo-lib/src/noble_ecc.ts
*/
const necc = __importStar(require("@noble/secp256k1"));
const bip32_1 = require("bip32");
const crypto_1 = require("crypto");
necc.utils.sha256Sync = (...messages) => {
const sha256 = (0, crypto_1.createHash)('sha256');
for (const message of messages)
sha256.update(message);
return sha256.digest();
};
necc.utils.hmacSha256Sync = (key, ...messages) => {
const hash = (0, crypto_1.createHmac)('sha256', key);
messages.forEach((m) => hash.update(m));
return Uint8Array.from(hash.digest());
};
const normalizePrivateKey = necc.utils._normalizePrivateKey;
const defaultTrue = (param) => param !== false;
function throwToNull(fn) {
try {
return fn();
}
catch (e) {
return null;
}
}
function isPoint(p, xOnly) {
if ((p.length === 32) !== xOnly)
return false;
try {
return !!necc.Point.fromHex(p);
}
catch (e) {
return false;
}
}
function hexToNumber(hex) {
if (typeof hex !== 'string') {
throw new TypeError('hexToNumber: expected string, got ' + typeof hex);
}
return BigInt(`0x${hex}`);
}
function bytesToNumber(bytes) {
return hexToNumber(necc.utils.bytesToHex(bytes));
}
function normalizeScalar(scalar) {
let num;
if (typeof scalar === 'bigint') {
num = scalar;
}
else if (typeof scalar === 'number' && Number.isSafeInteger(scalar) && scalar >= 0) {
num = BigInt(scalar);
}
else if (typeof scalar === 'string') {
if (scalar.length !== 64)
throw new Error('Expected 32 bytes of private scalar');
num = hexToNumber(scalar);
}
else if (scalar instanceof Uint8Array) {
if (scalar.length !== 32)
throw new Error('Expected 32 bytes of private scalar');
num = bytesToNumber(scalar);
}
else {
throw new TypeError('Expected valid private scalar');
}
if (num < 0)
throw new Error('Expected private scalar >= 0');
return num;
}
function pointAddScalar(p, tweak, isCompressed) {
const P = necc.Point.fromHex(p);
const t = normalizeScalar(tweak);
const Q = necc.Point.BASE.multiplyAndAddUnsafe(P, t, BigInt(1));
if (!Q)
throw new Error('Tweaked point at infinity');
return Q.toRawBytes(isCompressed);
}
function pointMultiply(p, tweak, isCompressed) {
const P = necc.Point.fromHex(p);
const h = typeof tweak === 'string' ? tweak : necc.utils.bytesToHex(tweak);
const t = BigInt(`0x${h}`);
return P.multiply(t).toRawBytes(isCompressed);
}
function privateAdd(privateKey, tweak) {
const p = normalizePrivateKey(privateKey);
const t = normalizeScalar(tweak);
const add = necc.utils._bigintTo32Bytes(necc.utils.mod(p + t, necc.CURVE.n));
if (necc.utils.isValidPrivateKey(add))
return add;
else
return null;
}
function privateNegate(privateKey) {
const p = normalizePrivateKey(privateKey);
const not = necc.utils._bigintTo32Bytes(necc.CURVE.n - p);
if (necc.utils.isValidPrivateKey(not))
return not;
else
return null;
}
const ecc = {
isPoint: (p) => isPoint(p, false),
isPrivate: (d) => necc.utils.isValidPrivateKey(d),
isXOnlyPoint: (p) => isPoint(p, true),
xOnlyPointAddTweak: (p, tweak) => throwToNull(() => {
const P = pointAddScalar(p, tweak, true);
const parity = P[0] % 2 === 1 ? 1 : 0;
return { parity, xOnlyPubkey: P.slice(1) };
}),
pointFromScalar: (sk, compressed) => throwToNull(() => necc.getPublicKey(sk, defaultTrue(compressed))),
pointCompress: (p, compressed) => {
return necc.Point.fromHex(p).toRawBytes(defaultTrue(compressed));
},
pointMultiply: (a, tweak, compressed) => throwToNull(() => pointMultiply(a, tweak, defaultTrue(compressed))),
pointAdd: (a, b, compressed) => throwToNull(() => {
const A = necc.Point.fromHex(a);
const B = necc.Point.fromHex(b);
return A.add(B).toRawBytes(defaultTrue(compressed));
}),
pointAddScalar: (p, tweak, compressed) => throwToNull(() => pointAddScalar(p, tweak, defaultTrue(compressed))),
privateAdd: (d, tweak) => throwToNull(() => {
const res = privateAdd(d, tweak);
// tiny-secp256k1 returns null rather than allowing a 0 private key to be returned
// ECPair.testEcc() requires that behavior.
if (res?.every((i) => i === 0))
return null;
return res;
}),
privateNegate: (d) => privateNegate(d),
sign: (h, d, e) => {
return necc.signSync(h, d, { der: false, extraEntropy: e });
},
signSchnorr: (h, d, e = new Uint8Array(32).fill(0x00)) => {
return necc.schnorr.signSync(h, d, e);
},
verify: (h, Q, signature, strict) => {
return necc.verify(signature, h, Q, { strict });
},
verifySchnorr: (h, Q, signature) => {
return necc.schnorr.verifySync(signature, h, Q);
}
};
exports.ecc = ecc;
const bip32 = (0, bip32_1.BIP32Factory)(ecc);
exports.bip32 = bip32;