-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
Copy pathtaproot.utils.ts
40 lines (35 loc) · 1.06 KB
/
taproot.utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import * as ecc from 'tiny-secp256k1';
import ECPairFactory from 'ecpair';
import { toXOnly } from '../../src/psbt/bip371';
import * as bitcoin from '../..';
const ECPair = ECPairFactory(ecc);
// This logic will be extracted to ecpair
export function tweakSigner(
signer: bitcoin.Signer,
opts: any = {},
): bitcoin.Signer {
// @ts-ignore
let privateKey: Uint8Array | undefined = signer.privateKey!;
if (!privateKey) {
throw new Error('Private key is required for tweaking signer!');
}
if (signer.publicKey[0] === 3) {
privateKey = ecc.privateNegate(privateKey);
}
const tweakedPrivateKey = ecc.privateAdd(
privateKey,
tapTweakHash(toXOnly(signer.publicKey), opts.tweakHash),
);
if (!tweakedPrivateKey) {
throw new Error('Invalid tweaked private key!');
}
return ECPair.fromPrivateKey(Buffer.from(tweakedPrivateKey), {
network: opts.network,
});
}
function tapTweakHash(pubKey: Buffer, h: Buffer | undefined): Buffer {
return bitcoin.crypto.taggedHash(
'TapTweak',
Buffer.concat(h ? [pubKey, h] : [pubKey]),
);
}