1
1
const BN = require ( 'bn.js' ) ; // TODO: remove? see changelog bn.js
2
+ const ecpair = require ( '../src/ecpair' )
3
+ const taggedHash = require ( '../src/crypto' ) . taggedHash ;
2
4
3
5
const 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' ) ;
10
11
11
12
const witnessHex = [
12
13
"9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602" ,
@@ -42,48 +43,42 @@ if (controlBlock.length < 33) {
42
43
if ( ( controlBlock . length - 33 ) % 32 !== 0 ) {
43
44
throw new Error ( 'The control-block length is incorrect!' ) ;
44
45
}
45
- if ( ( controlBlock . length - 33 ) / 32 > 128 ) {
46
+ const m = ( controlBlock . length - 33 ) / 32 ;
47
+ if ( m > 128 ) {
46
48
throw new Error ( `The control-block length is too large. Got ${ controlBlock . length } .` ) ;
47
49
}
48
50
const script = witness [ witness . length - 2 ] ;
49
51
50
- const pxxx = controlBlock . slice ( 1 , 33 ) ;
51
-
52
+ const p = controlBlock . slice ( 1 , 33 ) ;
53
+ const v = controlBlock [ 0 ] & 0xfe ; // leaf version
52
54
53
- const leafVersion = controlBlock [ 0 ] & 0xfe ;
55
+ const P = ecpair . liftX ( p ) // TODO: representation
54
56
55
57
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 ) ;
56
62
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 ) ;
63
63
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
+ }
68
71
}
69
72
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
+ }
70
77
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 ) ;
87
81
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