11const BN = require ( 'bn.js' ) ; // TODO: remove? see changelog bn.js
2+ const ecpair = require ( '../src/ecpair' )
3+ const taggedHash = require ( '../src/crypto' ) . taggedHash ;
24
35const ANNEX_PREFIX = 0x50 ;
4- const EC_P = Buffer . from ( 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f' , 'hex' ) ;
5- const P = new BN ( EC_P ) ;
6- const P_REDUCTION = BN . red ( P ) ;
7- const P_QUADRATIC_RESIDUE = P . addn ( 1 ) . divn ( 4 ) ;
8- const BN_3 = new BN ( 3 ) ;
9- const BN_7 = new BN ( 7 ) ;
6+ const EC_N = Buffer . from ( '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141' , 'hex' ) ;
7+
8+ const TAP_LEAF_TAG = Buffer . from ( 'TapLeaf' , 'utf8' ) ;
9+ const TAP_BRANCH_TAG = Buffer . from ( 'TapBranch' , 'utf8' ) ;
10+ const TAP_TWEAK_TAG = Buffer . from ( 'TapTweak' , 'utf8' ) ;
1011
1112const witnessHex = [
1213 "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602" ,
@@ -42,48 +43,42 @@ if (controlBlock.length < 33) {
4243if ( ( controlBlock . length - 33 ) % 32 !== 0 ) {
4344 throw new Error ( 'The control-block length is incorrect!' ) ;
4445}
45- if ( ( controlBlock . length - 33 ) / 32 > 128 ) {
46+ const m = ( controlBlock . length - 33 ) / 32 ;
47+ if ( m > 128 ) {
4648 throw new Error ( `The control-block length is too large. Got ${ controlBlock . length } .` ) ;
4749}
4850const script = witness [ witness . length - 2 ] ;
4951
50- const pxxx = controlBlock . slice ( 1 , 33 ) ;
51-
52+ const p = controlBlock . slice ( 1 , 33 ) ;
53+ const v = controlBlock [ 0 ] & 0xfe ; // leaf version
5254
53- const leafVersion = controlBlock [ 0 ] & 0xfe ;
55+ const P = ecpair . liftX ( p ) // TODO: representation
5456
5557
58+ const k = [ ] ;
59+ const e = [ ] ;
60+ const xxx = Buffer . concat ( Buffer . from ( v ) , Buffer . from ( compactSize ( script . length ) ) , script ) ;
61+ k [ 0 ] = taggedHash ( TAP_LEAF_TAG , xxx ) ;
5662
57- function liftX ( b ) {
58- // check if x instance of buffer and length 32
59- const x = new BN ( b ) . toRed ( P_REDUCTION ) ;
60- if ( x . gte ( P ) ) return null ;
61- const ySq = x . redPow ( BN_3 ) . add ( BN_7 ) . mod ( P ) ;
62- const y = ySq . redPow ( P_QUADRATIC_RESIDUE ) . mod ( P ) ;
6363
64- console . log ( 'ySq' , ySq . toJSON ( ) ) ;
65- console . log ( 'y2' , y . redPow ( new BN ( 2 ) ) . mod ( P ) . toJSON ( ) ) ;
66- console . log ( 'y' , y . toJSON ( ) ) ;
67- return y ;
64+ for ( let j = 0 ; j < m - 1 ; j ++ ) {
65+ e [ j ] = controlBlock . slice ( 33 + 32 * j , 65 + 32 * j ) ;
66+ if ( k [ j ] . compare ( e [ j ] ) < 0 ) {
67+ k [ j + 1 ] = taggedHash ( TAP_BRANCH_TAG , k [ j ] || e [ j ] ) ;
68+ } else {
69+ k [ j + 1 ] = taggedHash ( TAP_BRANCH_TAG , e [ j ] || k [ j ] ) ;
70+ }
6871}
6972
73+ const t = taggedHash ( TAP_TWEAK_TAG , k [ m + 1 ] ) ;
74+ if ( t . compare ( EC_N ) >= 0 ) {
75+ throw new Error ( 'Over the order of secp256k1' )
76+ }
7077
71- // const p = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
72- // const q = (p + 1n) / 4n;
73-
74- // function liftX(hex) {
75- // console.log('liftX IN');
76-
77- // const x = BigInt(hex);
78-
79- // if (x >= p) return null;
80- // const yy = (x ** 3n + 7n) % p;
81- // // const y = (yy ** q) % p;
82-
83-
84- // console.log('liftX OUT');
85- // return yy;
86- // }
78+ //pointFromScalar
79+ const T = ecpair . pointFromScalar ( t ) ;
80+ const Q = ecpair . addPoints ( P , T ) ;
8781
88- const x = '0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798' ;
89- const y = liftX ( x ) ;
82+ if ( q !== x ( Q ) || ( c [ 0 ] & 1 ) !== ( y ( Q ) % 2 ) ) {
83+ throw new Error ( 'xxxxxx' )
84+ }
0 commit comments