1
// Copyright 2007,2008,2010 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
6
// Modified for Kirk engine by setting single curve and internal function
7
// to support Kirk elliptic curve options.- July 2011
12
// Include definitions from kirk header
13
#include "kirk_engine.h"
19
// Simplified for use by Kirk Engine since it has only 1 curve
25
struct point ec_G; // mon
26
struct point ec_Q; // mon
31
void hex_dump(char *str, u8 *buf, int size)
38
for(i=0; i<size; i++){
42
printf(" %02X", buf[i]);
47
static void elt_copy(u8 *d, u8 *a)
52
static void elt_zero(u8 *d)
57
static int elt_is_zero(u8 *d)
61
for (i = 0; i < 20; i++)
68
static void elt_add(u8 *d, u8 *a, u8 *b)
70
bn_add(d, a, b, ec_p, 20);
73
static void elt_sub(u8 *d, u8 *a, u8 *b)
75
bn_sub(d, a, b, ec_p, 20);
78
static void elt_mul(u8 *d, u8 *a, u8 *b)
80
bn_mon_mul(d, a, b, ec_p, 20);
83
static void elt_square(u8 *d, u8 *a)
88
static void elt_inv(u8 *d, u8 *a)
92
bn_mon_inv(d, s, ec_p, 20);
95
static void point_to_mon(struct point *p)
97
bn_to_mon(p->x, ec_p, 20);
98
bn_to_mon(p->y, ec_p, 20);
101
static void point_from_mon(struct point *p)
103
bn_from_mon(p->x, ec_p, 20);
104
bn_from_mon(p->y, ec_p, 20);
108
static int point_is_on_curve(u8 *p)
127
return elt_is_zero(s);
131
static void point_zero(struct point *p)
137
static int point_is_zero(struct point *p)
139
return elt_is_zero(p->x) && elt_is_zero(p->y);
142
static void point_double(struct point *r, struct point *p)
146
u8 *px, *py, *rx, *ry;
155
if (elt_is_zero(py)) {
160
elt_square(t, px); // t = px*px
161
elt_add(s, t, t); // s = 2*px*px
162
elt_add(s, s, t); // s = 3*px*px
163
elt_add(s, s, ec_a); // s = 3*px*px + a
164
elt_add(t, py, py); // t = 2*py
165
elt_inv(t, t); // t = 1/(2*py)
166
elt_mul(s, s, t); // s = (3*px*px+a)/(2*py)
168
elt_square(rx, s); // rx = s*s
169
elt_add(t, px, px); // t = 2*px
170
elt_sub(rx, rx, t); // rx = s*s - 2*px
172
elt_sub(t, px, rx); // t = -(rx-px)
173
elt_mul(ry, s, t); // ry = -s*(rx-px)
174
elt_sub(ry, ry, py); // ry = -s*(rx-px) - py
177
static void point_add(struct point *r, struct point *p, struct point *q)
179
u8 s[20], t[20], u[20];
180
u8 *px, *py, *qx, *qy, *rx, *ry;
193
if (point_is_zero(&pp)) {
199
if (point_is_zero(&qq)) {
207
if (elt_is_zero(u)) {
210
point_double(r, &pp);
217
elt_inv(t, u); // t = 1/(qx-px)
218
elt_sub(u, qy, py); // u = qy-py
219
elt_mul(s, t, u); // s = (qy-py)/(qx-px)
221
elt_square(rx, s); // rx = s*s
222
elt_add(t, px, qx); // t = px+qx
223
elt_sub(rx, rx, t); // rx = s*s - (px+qx)
225
elt_sub(t, px, rx); // t = -(rx-px)
226
elt_mul(ry, s, t); // ry = -s*(rx-px)
227
elt_sub(ry, ry, py); // ry = -s*(rx-px) - py
230
static void point_mul(struct point *d, u8 *a, struct point *b) // a is bignum
237
for (i = 0; i < 21; i++)
238
for (mask = 0x80; mask != 0; mask >>= 1) {
240
if ((a[i] & mask) != 0)
244
// Modified from original to support kirk engine use - July 2011
245
// Added call to Kirk Random number generator rather than /dev/random
247
static void generate_ecdsa(u8 *outR, u8 *outS, u8 *k, u8 *hash)
257
e[0] = 0;R[0] = 0;S[0] = 0;
258
memcpy(e + 1, hash, 20);
259
bn_reduce(e, ec_N, 21);
261
// Original removed for portability
263
//fp = fopen("/dev/random", "rb");
264
//if (fread(m, sizeof m, 1, fp) != 1)
265
//fail("reading random");
268
//if (bn_compare(m, ec_N, 21) >= 0)
273
// Added call back to kirk PRNG - July 2011
277
point_mul(&mG, m, &ec_G);
282
// S = m**-1*(e + Rk) (mod N)
285
bn_reduce(kk, ec_N, 21);
286
bn_to_mon(m, ec_N, 21);
287
bn_to_mon(e, ec_N, 21);
288
bn_to_mon(R, ec_N, 21);
289
bn_to_mon(kk, ec_N, 21);
291
bn_mon_mul(S, R, kk, ec_N, 21);
292
bn_add(kk, S, e, ec_N, 21);
293
bn_mon_inv(minv, m, ec_N, 21);
294
bn_mon_mul(S, minv, kk, ec_N, 21);
296
bn_from_mon(R, ec_N, 21);
297
bn_from_mon(S, ec_N, 21);
298
memcpy(outR,R+1,0x20);
299
memcpy(outS,S+1,0x20);
309
// Slightly modified to support kirk compatible signature input - July 2011
310
static int check_ecdsa(struct point *Q, u8 *inR, u8 *inS, u8 *hash)
313
u8 e[21], R[21], S[21];
319
memcpy(e + 1, hash, 20);
320
bn_reduce(e, ec_N, 21);
322
memcpy(R + 1, inR, 20);
323
bn_reduce(R, ec_N, 21);
325
memcpy(S + 1, inS, 20);
326
bn_reduce(S, ec_N, 21);
328
bn_to_mon(R, ec_N, 21);
329
bn_to_mon(S, ec_N, 21);
330
bn_to_mon(e, ec_N, 21);
332
bn_mon_inv(Sinv, S, ec_N, 21);
334
bn_mon_mul(w1, e, Sinv, ec_N, 21);
336
bn_mon_mul(w2, R, Sinv, ec_N, 21);
339
bn_from_mon(w1, ec_N, 21);
340
bn_from_mon(w2, ec_N, 21);
343
point_mul(&r1, w1, &ec_G);
345
point_mul(&r2, w2, Q);
348
point_add(&r1, &r1, &r2);
353
memcpy(rr + 1, r1.x, 20);
354
bn_reduce(rr, ec_N, 21);
356
bn_from_mon(R, ec_N, 21);
357
bn_from_mon(S, ec_N, 21);
359
return (bn_compare(rr, R, 21) == 0);
363
// Modified from original to support kirk engine use - July 2011
364
void ec_priv_to_pub(u8 *k, u8 *Q)
366
struct point ec_temp;
367
bn_to_mon(k, ec_N, 21);
368
point_mul(&ec_temp, k, &ec_G);
369
point_from_mon(&ec_temp);
370
//bn_from_mon(k, ec_N, 21);
371
memcpy(Q,ec_temp.x,20);
372
memcpy(Q+20,ec_temp.y,20);
375
// Modified from original to support kirk engine use - July 2011
376
void ec_pub_mult(u8 *k, u8 *Q)
378
struct point ec_temp;
379
//bn_to_mon(k, ec_N, 21);
380
point_mul(&ec_temp, k, &ec_Q);
381
point_from_mon(&ec_temp);
382
//bn_from_mon(k, ec_N, 21);
383
memcpy(Q,ec_temp.x,20);
384
memcpy(Q+20,ec_temp.y,20);
388
// Simplified for use by Kirk Engine - NO LONGER COMPATIABLE WITH ORIGINAL VERSION - July 2011
389
int ecdsa_set_curve(u8* p,u8* a,u8* b,u8* N,u8* Gx,u8* Gy)
396
bn_to_mon(ec_a, ec_p, 20);
397
bn_to_mon(ec_b, ec_p, 20);
399
memcpy(ec_G.x, Gx, 20);
400
memcpy(ec_G.y, Gy, 20);
406
void ecdsa_set_pub(u8 *Q)
408
memcpy(ec_Q.x, Q, 20);
409
memcpy(ec_Q.y, Q+20, 20);
413
void ecdsa_set_priv(u8 *ink)
418
bn_reduce(k, ec_N, 21);
420
memcpy(ec_k, k, sizeof ec_k);
423
int ecdsa_verify(u8 *hash, u8 *R, u8 *S)
425
return check_ecdsa(&ec_Q, R, S, hash);
428
void ecdsa_sign(u8 *hash, u8 *R, u8 *S)
430
generate_ecdsa(R, S, ec_k, hash);
433
int point_is_on_curve(u8 *p)
442
elt_mul(s, t, x);// s = x^3
445
elt_add(s, s, t); //s = x^3 + a *x
447
elt_add(s, s, ec_b);//s = x^3 + a *x + b
449
elt_square(t, y); //t = y^2
450
elt_sub(s, s, t); // is s - t = 0?
451
hex_dump("S", s, 20);
453
return elt_is_zero(s);
456
void dump_ecc(void) {
457
hex_dump("P", ec_p, 20);
458
hex_dump("a", ec_a, 20);
459
hex_dump("b", ec_b, 20);
460
hex_dump("N", ec_N, 21);
461
hex_dump("Gx", ec_G.x, 20);
462
hex_dump("Gy", ec_G.y, 20);