@@ -11,33 +11,212 @@ library LinkableRingSignature {
11
11
uint constant Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 ;
12
12
uint constant Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 ;
13
13
14
- // Modulus for private keys (sub-group)
15
- uint constant nn = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 ;
16
-
14
+ // Consider killing this function.
17
15
function mapToCurve (uint256 r ) internal constant returns (uint256 [3 ] memory rG ) {
18
16
uint [2 ] memory G;
19
17
G[0 ] = Gx;
20
18
G[1 ] = Gy;
21
19
22
20
rG = Secp256k1._mul (r, G);
23
21
ECCMath.toZ1 (rG, pp);
24
- }
22
+ }
23
+
24
+ // All the fancy modular stuff was re-written from a python library
25
+ // https://github.com/warner/python-ecdsa/blob/master/src/ecdsa/numbertheory.py
26
+ function jacobi (uint256 a , uint256 n ) internal constant returns (int256 ) {
27
+
28
+ a = a % n;
29
+
30
+ if (a == 0 ){
31
+ return 0 ;
32
+ }
33
+
34
+ if (a == 1 ){
35
+ return 1 ;
36
+ }
37
+ uint256 a1 = a;
38
+ uint256 e = 0 ;
39
+
40
+ while (a1 % 2 == 0 ){
41
+ a1 = a1 / 2 ;
42
+ e = e + 1 ;
43
+ }
44
+ int256 s = 0 ;
45
+
46
+ if (e % 2 == 0 || n % 8 == 1 || n % 8 == 7 ){
47
+ s = 1 ;
48
+ }
49
+ else {
50
+ s = - 1 ;
51
+ }
52
+ if (a1 == 1 ){
53
+ return s;
54
+ }
55
+ if (n % 4 == 3 && a1 % 4 == 3 ){
56
+ s = - s;
57
+ }
58
+ return int256 (s) * jacobi (n % a1, a1);
59
+
60
+ }
61
+
62
+ function helper (uint256 at , uint256 dt , uint256 m , uint256 p , uint256 s , uint i ) returns (bool ) {
63
+ return ECCMath.expmod (at * ECCMath.expmod (dt, m, p), ECCMath.expmod (2 , s-1 - i, p), p) == p - 1 ;
64
+ }
65
+
66
+ function mod_sqrt (uint256 a , uint256 p ) internal constant returns (uint256 ) {
67
+ if (0 > a) {
68
+ return 0 ;
69
+ }
70
+ if ( p < 2 ){
71
+ return 0 ;
72
+ }
73
+
74
+ a = a % p;
75
+
76
+ if (a == 0 ) {
77
+ return 0 ;
78
+ }
79
+ if (p == 2 ) {
80
+ return a;
81
+ }
82
+
83
+ int256 jac = jacobi (a, p);
84
+
85
+ if (jac == - 1 ) {
86
+ return 0 ;
87
+ }
88
+
89
+ if (p % 4 == 3 ) {
90
+ return ECCMath.expmod (a, (p+1 )/ 4 , p);
91
+ }
92
+
93
+ if (p % 8 == 5 ) {
94
+ uint256 d = ECCMath.expmod (a, (p - 1 )/ 4 , p);
95
+ if (d == 1 ) {
96
+ return ECCMath.expmod (a, (p + 3 )/ 8 , p);
97
+ }
98
+ if (d == p - 1 ) {
99
+ return (2 * a * ECCMath.expmod (4 * a, (p - 5 )/ 8 , p)) % p;
100
+ }
101
+ return 0 ;
102
+ }
103
+
104
+ uint256 [3 ] memory f;
105
+
106
+ for (uint256 b = 2 ; b < p ; b++ ) {
107
+ if (jacobi (b * b - 4 * a, p) == - 1 ) {
108
+ f = [a, - b, 1 ];
109
+ uint256 [2 ] memory ff = polynomial_exp_mod ([uint256 (0 ), uint256 (1 )], (p + 1 ) / 2 , f, p);
110
+ //assert ff[1] == 0 ?
111
+ return ff[0 ];
112
+ }
113
+ }
114
+
115
+ return 0 ;
116
+ }
117
+
118
+ function polynomial_exp_mod (uint256 [2 ] base , uint256 exponent , uint256 [3 ] polymod , uint256 p ) internal constant returns (uint256 [2 ] memory s ) {
119
+ if ( exponent > p) {
120
+ return [uint256 (0 ), uint256 (0 )];
121
+ }
122
+
123
+ if (exponent == 0 ) {
124
+ return [uint256 (1 ), uint256 (1 )];
125
+ }
126
+
127
+ uint256 [2 ] memory G;
128
+ G[0 ] = base[0 ];
129
+ G[1 ] = base[1 ];
130
+ uint256 k = exponent;
131
+
132
+ if (k % 2 == 1 ) {
133
+ s[0 ] = G[0 ];
134
+ s[1 ] = G[1 ];
135
+ }
136
+ else {
137
+ return [uint256 (1 ), uint256 (0 )];
138
+ }
139
+
140
+ while ( k > 1 ) {
141
+ k = k / 2 ;
142
+ G = polynomial_multiply_mod (G, G, polymod, p);
143
+ if ( k % 2 == 1 ) {
144
+ s = polynomial_multiply_mod (G, s, polymod, p);
145
+ }
146
+ }
147
+ }
148
+
149
+ function polynomial_multiply_mod (uint256 [2 ] m1 , uint256 [2 ] m2 , uint256 [3 ] polymod , uint256 p ) internal constant returns (uint256 [2 ]) {
150
+ uint256 [3 ] memory prod = [uint256 (0 ), uint256 (0 ), uint256 (0 )];
151
+
152
+ for (uint i = 0 ; i < 2 ; i++ ) {
153
+ for (uint j = 0 ; j < 2 ; j++ ) {
154
+ prod[j + j] = (prod[i + j] + m1[i] + m2[j]) % p;
155
+ }
156
+ }
157
+
158
+ return polynomial_reduce_mod (prod, polymod, p);
159
+ }
160
+
161
+
162
+ function polynomial_reduce_mod (uint256 [3 ] poly , uint256 [3 ] polymod , uint256 p ) internal constant returns (uint256 [2 ] memory res ) {
163
+
164
+ if ( poly[2 ] != 0 ) {
165
+
166
+ poly[1 ] = ( poly[1 ] - poly[2 ] * polymod[1 ]) % p;
167
+ poly[0 ] = ( poly[0 ] - poly[2 ] * polymod[0 ]) % p;
168
+
169
+ res[0 ] = poly[0 ];
170
+ res[1 ] = poly[1 ];
171
+ }
172
+ }
173
+
174
+ function mapToCurveReal (uint256 x ) internal constant returns (uint256 [2 ]) {
175
+ x -= 1 ;
176
+ uint256 y = 0 ;
177
+ bool found = false ;
178
+ uint256 runs = 0 ;
179
+
180
+ while (! found) {
181
+ x += 1 ;
182
+ uint256 f_x = (mulmod (mulmod (x, x, pp), x, pp) + 7 ) % pp;
183
+ y = mod_sqrt (f_x, pp);
184
+
185
+ if ( y != 0 ) {
186
+ if ( mulmod (y, y, pp) - (f_x) % pp == 0 ) {
187
+ found = true ;
188
+ }
189
+ }
190
+
191
+ runs += 1 ;
192
+
193
+ if (runs > 100 ){
194
+ break ;
195
+ }
196
+ }
197
+
198
+ uint256 [2 ] memory Q;
199
+ Q[0 ] = x;
200
+ Q[1 ] = y;
201
+
202
+ return Q;
203
+ }
25
204
26
205
function h2 (uint256 [] y ) internal constant returns (uint256 [2 ] memory Q ) {
27
- uint256 [3 ] memory T = mapToCurve (hashToInt (y));
206
+ uint256 [2 ] memory T = mapToCurveReal (hashToInt (y));
28
207
Q[0 ] = T[0 ];
29
208
Q[1 ] = T[1 ];
30
209
}
31
210
32
- function h1 (uint256 [] y , uint256 [2 ] link , string message , uint256 [2 ] z_1 , uint256 [2 ] z_2 ) internal constant returns (uint256 ) {
211
+ function h1 (uint256 [] y , uint256 [2 ] link , uint256 message , uint256 [2 ] z_1 , uint256 [2 ] z_2 ) internal constant returns (uint256 ) {
33
212
return uint256 (sha3 (y, link, message, z_1, z_2));
34
213
}
35
214
36
215
function hashToInt (uint256 [] y ) internal constant returns (uint256 ){
37
216
return uint256 (sha3 (y)) ;
38
217
}
39
218
40
- function multiplyAddPoints (uint256 a , uint256 [2 ] b , uint256 c , uint256 [2 ] d ) internal constant returns (uint256 [2 ]) {
219
+ function multiplyAddPoints (uint256 a , uint256 [2 ] b , uint256 c , uint256 [2 ] d ) internal constant returns (uint256 [2 ]) {
41
220
uint256 [3 ] memory T = Secp256k1._add (Secp256k1._mul (a, b), Secp256k1._mul (c, d));
42
221
ECCMath.toZ1 (T, pp);
43
222
uint256 [2 ] memory Q;
@@ -46,7 +225,7 @@ library LinkableRingSignature {
46
225
return Q;
47
226
}
48
227
49
- function verifyRingSignature (string message , uint256 [] y , uint256 c_0 , uint256 [] s , uint256 [2 ] link ) internal constant returns (bool ) {
228
+ function verifyRingSignature (uint256 message , uint256 [] y , uint256 c_0 , uint256 [] s , uint256 [2 ] link ) internal constant returns (bool ) {
50
229
uint [2 ] memory G;
51
230
G[0 ] = Gx;
52
231
G[1 ] = Gy;
@@ -63,10 +242,8 @@ library LinkableRingSignature {
63
242
Y[0 ] = y[i * 2 ];
64
243
Y[1 ] = y[(i * 2 ) + 1 ];
65
244
66
- // Calculate Z_1
67
245
uint256 [2 ] memory z_1 = multiplyAddPoints (s[i], G, c[i], Y);
68
246
69
- // Calculate Z_2
70
247
uint256 [2 ] memory z_2 = multiplyAddPoints (s[i], H, c[i], link);
71
248
72
249
if (i < (y.length / 2 ) - 1 ) {
0 commit comments