@@ -10,118 +10,6 @@ function integerToBytes(i, len) {
10
10
return bytes ;
11
11
} ;
12
12
13
- /**
14
- * Find a quadratic residue (mod p) of this number. p must be an odd prime.
15
- *
16
- * For a given number a, this function solves the congruence of the form
17
- *
18
- * x^2 = a (mod p)
19
- *
20
- * And returns x. Note that p - x is also a root.
21
- *
22
- * 0 is returned if no square root exists for these a and p.
23
- *
24
- * The Tonelli-Shanks algorithm is used (except for some simple cases
25
- * in which the solution is known from an identity). This algorithm
26
- * runs in polynomial time (unless the generalized Riemann hypothesis
27
- * is false).
28
- *
29
- * Originally implemented in Python by Eli Bendersky:
30
- * http://eli.thegreenplace.net/2009/03/07/computing-modular-square-roots-in-python/
31
- *
32
- * Ported to JavaScript by Stefan Thomas.
33
- */
34
- BigInteger . prototype . modSqrt = function ( p ) {
35
- var ONE = BigInteger . ONE ,
36
- TWO = BigInteger . valueOf ( 2 ) ;
37
-
38
- // Simple cases
39
- if ( this . legendre ( p ) != 1 ) {
40
- return BigInteger . ZERO ;
41
- } else if ( this . equals ( BigInteger . ZERO ) ) {
42
- return BigInteger . ZERO ;
43
- } else if ( p . equals ( TWO ) ) {
44
- return p ;
45
- } else if ( p . mod ( BigInteger . valueOf ( 4 ) ) . equals ( BigInteger . valueOf ( 3 ) ) ) {
46
- return this . modPow ( p . add ( ONE ) . divide ( BigInteger . valueOf ( 4 ) ) , p ) ;
47
- }
48
-
49
- // Partition p-1 to s * 2^e for an odd s (i.e. reduce all the powers
50
- // of 2 from p-1)
51
- var s = p . subtract ( ONE ) ;
52
- var e = 0 ;
53
- while ( s . isEven ( ) ) {
54
- s = s . divide ( TWO ) ;
55
- ++ e ;
56
- }
57
-
58
- // Find some 'n' with a legendre symbol n|p = -1.
59
- // Shouldn't take long.
60
- var n = TWO ;
61
- while ( n . legendre ( p ) != - 1 ) {
62
- n = n . add ( ONE ) ;
63
- }
64
-
65
- // Here be dragons!
66
- // Read the paper "Square roots from 1; 24, 51, 10 to Dan Shanks" by
67
- // Ezra Brown for more information
68
-
69
- // x is a guess of the square root that gets better with each
70
- // iteration.
71
- //
72
- // b is the "fudge factor" - by how much we're off with the guess.
73
- // The invariant x^2 = ab (mod p) is maintained throughout the loop.
74
- //
75
- // g is used for successive powers of n to update both a and b
76
- //
77
- // r is the exponent - decreases with each update
78
-
79
- var x = this . modPow ( s . add ( ONE ) . divide ( TWO ) , p ) ;
80
- var b = this . modPow ( s , p ) ;
81
- var g = n . modPow ( s , p ) ;
82
- var r = e ;
83
-
84
- for ( ; ; ) {
85
- var t = b ;
86
-
87
- var m ;
88
- for ( m = 0 ; m < r ; m ++ ) {
89
- if ( t . equals ( ONE ) ) break ;
90
-
91
- t = t . modPowInt ( 2 , p ) ;
92
- }
93
-
94
- if ( m == 0 ) {
95
- return x ;
96
- }
97
-
98
- var gs = g . modPow ( TWO . pow ( BigInteger . valueOf ( r - m - 1 ) ) , p ) ;
99
- g = gs . multiply ( gs ) . mod ( p ) ;
100
- x = x . multiply ( gs ) . mod ( p ) ;
101
- b = b . multiply ( g ) . mod ( p ) ;
102
- r = m ;
103
- }
104
- } ;
105
-
106
- /**
107
- * Compute the Legendre symbol a|p using Euler's criterion.
108
- *
109
- * p is a prime, a is relatively prime to p
110
- * (if p divides a, then a | p = 0)
111
- *
112
- * Returns 1 if a has a square root modulo p, -1 otherwise.
113
- */
114
- BigInteger . prototype . legendre = function ( p ) {
115
- var ls = this . modPow ( p . subtract ( BigInteger . ONE ) . shiftRight ( 1 ) , p ) ;
116
- if ( ls . equals ( p . subtract ( BigInteger . ONE ) ) ) {
117
- return - 1 ;
118
- } else if ( ls . equals ( BigInteger . ZERO ) ) {
119
- return 0 ;
120
- } else {
121
- return 1 ;
122
- }
123
- } ;
124
-
125
13
ECFieldElementFp . prototype . getByteLength = function ( ) {
126
14
return Math . floor ( ( this . toBigInteger ( ) . bitLength ( ) + 7 ) / 8 ) ;
127
15
} ;
@@ -304,6 +192,8 @@ Bitcoin.ECDSA = (function () {
304
192
var ecparams = getSECCurveByName ( "secp256k1" ) ;
305
193
var rng = new SecureRandom ( ) ;
306
194
195
+ var P_OVER_FOUR = null ;
196
+
307
197
function implShamirsTrick ( P , k , Q , l )
308
198
{
309
199
var m = Math . max ( k . bitLength ( ) , l . bitLength ( ) ) ;
@@ -515,12 +405,17 @@ Bitcoin.ECDSA = (function () {
515
405
var a = curve . getA ( ) . toBigInteger ( ) ;
516
406
var b = curve . getB ( ) . toBigInteger ( ) ;
517
407
408
+ // We precalculate (p + 1) / 4 where p is if the field order
409
+ if ( ! P_OVER_FOUR ) {
410
+ P_OVER_FOUR = p . add ( BigInteger . ONE ) . divide ( BigInteger . valueOf ( 4 ) ) ;
411
+ }
412
+
518
413
// 1.1 Compute x
519
414
var x = isSecondKey ? r . add ( n ) : r ;
520
415
521
416
// 1.3 Convert x to point
522
417
var alpha = x . multiply ( x ) . multiply ( x ) . add ( a . multiply ( x ) ) . add ( b ) . mod ( p ) ;
523
- var beta = alpha . modSqrt ( p ) ;
418
+ var beta = alpha . modPow ( P_OVER_FOUR , p ) ;
524
419
525
420
var xorOdd = beta . isEven ( ) ? ( i % 2 ) : ( ( i + 1 ) % 2 ) ;
526
421
// If beta is even, but y isn't or vice versa, then convert it,
0 commit comments