1 | import { _0n, BN, bnToU8a, hasBigInt, isU8a, nToU8a, u8aToBigInt } from '@polkadot/util';
|
2 | import { BigInt } from '@polkadot/x-bigint';
|
3 | import { BN_BE_256_OPTS, BN_BE_OPTS } from '../bn.js';
|
4 | const N = 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141'.replace(/ /g, '');
|
5 | const N_BI = BigInt(`0x${N}`);
|
6 | const N_BN = new BN(N, 'hex');
|
7 | function addBi(seckey, tweak) {
|
8 | let res = u8aToBigInt(tweak, BN_BE_OPTS);
|
9 | if (res >= N_BI) {
|
10 | throw new Error('Tweak parameter is out of range');
|
11 | }
|
12 | res += u8aToBigInt(seckey, BN_BE_OPTS);
|
13 | if (res >= N_BI) {
|
14 | res -= N_BI;
|
15 | }
|
16 | if (res === _0n) {
|
17 | throw new Error('Invalid resulting private key');
|
18 | }
|
19 | return nToU8a(res, BN_BE_256_OPTS);
|
20 | }
|
21 | function addBn(seckey, tweak) {
|
22 | const res = new BN(tweak);
|
23 | if (res.cmp(N_BN) >= 0) {
|
24 | throw new Error('Tweak parameter is out of range');
|
25 | }
|
26 | res.iadd(new BN(seckey));
|
27 | if (res.cmp(N_BN) >= 0) {
|
28 | res.isub(N_BN);
|
29 | }
|
30 | if (res.isZero()) {
|
31 | throw new Error('Invalid resulting private key');
|
32 | }
|
33 | return bnToU8a(res, BN_BE_256_OPTS);
|
34 | }
|
35 | export function secp256k1PrivateKeyTweakAdd(seckey, tweak, onlyBn) {
|
36 | if (!isU8a(seckey) || seckey.length !== 32) {
|
37 | throw new Error('Expected seckey to be an Uint8Array with length 32');
|
38 | }
|
39 | else if (!isU8a(tweak) || tweak.length !== 32) {
|
40 | throw new Error('Expected tweak to be an Uint8Array with length 32');
|
41 | }
|
42 | return !hasBigInt || onlyBn
|
43 | ? addBn(seckey, tweak)
|
44 | : addBi(seckey, tweak);
|
45 | }
|