1 // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
2 // Licensed under the terms of the GNU GPL, version 2
3 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
10 // y**2 + x*y = x**3 + x + b
12 "\x00\x66\x64\x7e\xde\x6c\x33\x2c\x7f\x8c\x09\x23\xbb\x58\x21"
13 "\x3b\x33\x3b\x20\xe9\xce\x42\x81\xfe\x11\x5f\x7d\x8f\x90\xad";
15 // order of the addition group of points
17 "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
18 "\x13\xe9\x74\xe7\x2f\x8a\x69\x22\x03\x1d\x26\x03\xcf\xe0\xd7";
22 "\x00\xfa\xc9\xdf\xcb\xac\x83\x13\xbb\x21\x39\xf1\xbb\x75\x5f"
23 "\xef\x65\xbc\x39\x1f\x8b\x36\xf8\xf8\xeb\x73\x71\xfd\x55\x8b"
24 "\x01\x00\x6a\x08\xa4\x19\x03\x35\x06\x78\xe5\x85\x28\xbe\xbf"
25 "\x8a\x0b\xef\xf8\x67\xa7\xca\x36\x71\x6f\x7e\x01\xf8\x10\x52";
27 static void elt_print(char *name
, u8
*a
)
31 printf("%s = ", name
);
33 for (i
= 0; i
< 30; i
++)
39 static void elt_copy(u8
*d
, u8
*a
)
44 static void elt_zero(u8
*d
)
49 static int elt_is_zero(u8
*d
)
53 for (i
= 0; i
< 30; i
++)
60 static void elt_add(u8
*d
, u8
*a
, u8
*b
)
64 for (i
= 0; i
< 30; i
++)
68 static void elt_mul_x(u8
*d
, u8
*a
)
76 for (i
= 0; i
< 29; i
++) {
86 static void elt_mul(u8
*d
, u8
*a
, u8
*b
)
95 for (n
= 0; n
< 233; n
++) {
98 if ((a
[i
] & mask
) != 0)
109 static const u8 square
[16] =
110 "\x00\x01\x04\x05\x10\x11\x14\x15\x40\x41\x44\x45\x50\x51\x54\x55";
112 static void elt_square_to_wide(u8
*d
, u8
*a
)
116 for (i
= 0; i
< 30; i
++) {
117 d
[2*i
] = square
[a
[i
] >> 4];
118 d
[2*i
+ 1] = square
[a
[i
] & 15];
122 static void wide_reduce(u8
*d
)
127 for (i
= 0; i
< 30; i
++) {
147 static void elt_square(u8
*d
, u8
*a
)
151 elt_square_to_wide(wide
, a
);
154 elt_copy(d
, wide
+ 30);
157 static void itoh_tsujii(u8
*d
, u8
*a
, u8
*b
, u32 j
)
170 static void elt_inv(u8
*d
, u8
*a
)
175 itoh_tsujii(t
, a
, a
, 1);
176 itoh_tsujii(s
, t
, a
, 1);
177 itoh_tsujii(t
, s
, s
, 3);
178 itoh_tsujii(s
, t
, a
, 1);
179 itoh_tsujii(t
, s
, s
, 7);
180 itoh_tsujii(s
, t
, t
, 14);
181 itoh_tsujii(t
, s
, a
, 1);
182 itoh_tsujii(s
, t
, t
, 29);
183 itoh_tsujii(t
, s
, s
, 58);
184 itoh_tsujii(s
, t
, t
, 116);
188 static int point_is_on_curve(u8
*p
)
209 return elt_is_zero(s
);
212 static int point_is_zero(u8
*p
)
214 return elt_is_zero(p
) && elt_is_zero(p
+ 30);
217 static void point_double(u8
*r
, u8
*p
)
220 u8
*px
, *py
, *rx
, *ry
;
227 if (elt_is_zero(px
)) {
249 static void point_add(u8
*r
, u8
*p
, u8
*q
)
251 u8 s
[30], t
[30], u
[30];
252 u8
*px
, *py
, *qx
, *qy
, *rx
, *ry
;
261 if (point_is_zero(p
)) {
267 if (point_is_zero(q
)) {
275 if (elt_is_zero(u
)) {
302 static void point_mul(u8
*d
, u8
*a
, u8
*b
) // a is bignum
310 for (i
= 0; i
< 30; i
++)
311 for (mask
= 0x80; mask
!= 0; mask
>>= 1) {
313 if ((a
[i
] & mask
) != 0)
318 void generate_ecdsa(u8
*R
, u8
*S
, u8
*k
, u8
*hash
)
324 memcpy(e
+ 10, hash
, 20);
326 // should take random m --> but we take 1
328 // S = m**-1*(e + Rk) (mod N)
331 // S = e + Rk (mod N)
334 if (bn_compare(R
, ec_N
, 30) >= 0)
335 bn_sub_modulus(R
, ec_N
, 30);
337 if (bn_compare(kk
, ec_N
, 30) >= 0)
338 bn_sub_modulus(kk
, ec_N
, 30);
339 bn_mul(S
, R
, kk
, ec_N
, 30);
340 bn_add(S
, S
, e
, ec_N
, 30);
343 int check_ecdsa(u8
*Q
, u8
*R
, u8
*S
, u8
*hash
)
350 bn_inv(Sinv
, S
, ec_N
, 30);
353 memcpy(e
+ 10, hash
, 20);
355 bn_mul(w1
, e
, Sinv
, ec_N
, 30);
356 bn_mul(w2
, R
, Sinv
, ec_N
, 30);
358 point_mul(r1
, w1
, ec_G
);
359 point_mul(r2
, w2
, Q
);
361 point_add(r1
, r1
, r2
);
363 if (bn_compare(r1
, ec_N
, 30) >= 0)
364 bn_sub_modulus(r1
, ec_N
, 30);
366 return (bn_compare(r1
, R
, 30) == 0);
369 static void ec_priv_to_pub(u8
*Q
, u8
*k
)
371 point_mul(Q
, k
, ec_G
);