bitcoinjs-lib
Version:
Client-side Bitcoin JavaScript library
157 lines (156 loc) • 4.86 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;
};
Object.defineProperty(exports, '__esModule', { value: true });
exports.initEccLib = initEccLib;
exports.getEccLib = getEccLib;
const tools = __importStar(require('uint8array-tools'));
const _ECCLIB_CACHE = {};
/**
* Initializes the ECC library with the provided instance.
* If `eccLib` is `undefined`, the library will be cleared.
* If `eccLib` is a new instance, it will be verified before setting it as the active library.
*
* @param eccLib The instance of the ECC library to initialize.
* @param opts Extra initialization options. Use {DANGER_DO_NOT_VERIFY_ECCLIB:true} if ecc verification should not be executed. Not recommended!
*/
function initEccLib(eccLib, opts) {
if (!eccLib) {
// allow clearing the library
_ECCLIB_CACHE.eccLib = eccLib;
} else if (eccLib !== _ECCLIB_CACHE.eccLib) {
if (!opts?.DANGER_DO_NOT_VERIFY_ECCLIB)
// new instance, verify it
verifyEcc(eccLib);
_ECCLIB_CACHE.eccLib = eccLib;
}
}
/**
* Retrieves the ECC Library instance.
* Throws an error if the ECC Library is not provided.
* You must call initEccLib() with a valid TinySecp256k1Interface instance before calling this function.
* @returns The ECC Library instance.
* @throws Error if the ECC Library is not provided.
*/
function getEccLib() {
if (!_ECCLIB_CACHE.eccLib)
throw new Error(
'No ECC Library provided. You must call initEccLib() with a valid TinySecp256k1Interface instance',
);
return _ECCLIB_CACHE.eccLib;
}
const h = hex => tools.fromHex(hex);
/**
* Verifies the ECC functionality.
*
* @param ecc - The TinySecp256k1Interface object.
*/
function verifyEcc(ecc) {
assert(typeof ecc.isXOnlyPoint === 'function');
assert(
ecc.isXOnlyPoint(
h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),
),
);
assert(
ecc.isXOnlyPoint(
h('fffffffffffffffffffffffffffffffffffffffffffffffffffffffeeffffc2e'),
),
);
assert(
ecc.isXOnlyPoint(
h('f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9'),
),
);
assert(
ecc.isXOnlyPoint(
h('0000000000000000000000000000000000000000000000000000000000000001'),
),
);
assert(
!ecc.isXOnlyPoint(
h('0000000000000000000000000000000000000000000000000000000000000000'),
),
);
assert(
!ecc.isXOnlyPoint(
h('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'),
),
);
assert(typeof ecc.xOnlyPointAddTweak === 'function');
tweakAddVectors.forEach(t => {
const r = ecc.xOnlyPointAddTweak(h(t.pubkey), h(t.tweak));
if (t.result === null) {
assert(r === null);
} else {
assert(r !== null);
assert(r.parity === t.parity);
assert(tools.compare(r.xOnlyPubkey, h(t.result)) === 0);
}
});
}
function assert(bool) {
if (!bool) throw new Error('ecc library invalid');
}
const tweakAddVectors = [
{
pubkey: '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
tweak: 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140',
parity: -1,
result: null,
},
{
pubkey: '1617d38ed8d8657da4d4761e8057bc396ea9e4b9d29776d4be096016dbd2509b',
tweak: 'a8397a935f0dfceba6ba9618f6451ef4d80637abf4e6af2669fbc9de6a8fd2ac',
parity: 1,
result: 'e478f99dab91052ab39a33ea35fd5e6e4933f4d28023cd597c9a1f6760346adf',
},
{
pubkey: '2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991',
tweak: '823c3cd2142744b075a87eade7e1b8678ba308d566226a0056ca2b7a76f86b47',
parity: 0,
result: '9534f8dc8c6deda2dc007655981c78b49c5d96c778fbf363462a11ec9dfd948c',
},
];