static void point_add(struct point *r, struct point *p, struct point *q) { u8 s[20], t[20], u[20]; u8 *px, *py, *qx, *qy, *rx, *ry; struct point pp, qq; pp = *p; qq = *q; px = pp.x; py = pp.y; qx = qq.x; qy = qq.y; rx = r->x; ry = r->y; if (point_is_zero(&pp)) { elt_copy(rx, qx); elt_copy(ry, qy); return; } if (point_is_zero(&qq)) { elt_copy(rx, px); elt_copy(ry, py); return; } elt_sub(u, qx, px); if (elt_is_zero(u)) { elt_sub(u, qy, py); if (elt_is_zero(u)) point_double(r, &pp); else point_zero(r); return; } elt_inv(t, u); // t = 1/(qx-px) elt_sub(u, qy, py); // u = qy-py elt_mul(s, t, u); // s = (qy-py)/(qx-px) elt_square(rx, s); // rx = s*s elt_add(t, px, qx); // t = px+qx elt_sub(rx, rx, t); // rx = s*s - (px+qx) elt_sub(t, px, rx); // t = -(rx-px) elt_mul(ry, s, t); // ry = -s*(rx-px) elt_sub(ry, ry, py); // ry = -s*(rx-px) - py }
struct elt * instr_get_result(const struct instr * i) { struct elt *e; switch (i->optype) { case I_RAW: e = NULL; break; case I_CAST: e = elt_copy(i->res); break; case I_CAL: e = elt_copy(i->ret); break; default: e = elt_copy(i->er); } return e; }
void * instr_copy(void * instruction) { struct instr *copy; struct instr * i = (struct instr *)instruction; if (i->optype == I_RAW) { copy = malloc(sizeof *copy); copy->rawllvm = strdup(i->rawllvm); } else if (i->optype == I_CAST) { copy = malloc(sizeof *copy); copy->cast_func = i->cast_func; copy->tocast = elt_copy(i->tocast); copy->res = elt_copy(i->res); } else if (i->optype == I_CAL) { copy = malloc(sizeof *copy); copy->fn = strdup(i->fn); copy->args = stack_copy(i->args, elt_copy); copy->ret = elt_copy(i->ret); } else { copy = instr_new(i->optype, i->vr, elt_copy(i->er), elt_copy(i->e1), elt_copy(i->e2) ); } return copy; }
static void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash) { u8 e[21]; u8 kk[21]; u8 m[21]; u8 minv[21]; struct point mG; FILE *fp; e[0] = 0; memcpy(e + 1, hash, 20); bn_reduce(e, ec_N, 21); try_again: fp = fopen("/dev/random", "rb"); if (fread(m, sizeof m, 1, fp) != 1) fail("reading random"); fclose(fp); m[0] = 0; if (bn_compare(m, ec_N, 21) >= 0) goto try_again; // R = (mG).x point_mul(&mG, m, &ec_G); point_from_mon(&mG); R[0] = 0; elt_copy(R+1, mG.x); // S = m**-1*(e + Rk) (mod N) bn_copy(kk, k, 21); bn_reduce(kk, ec_N, 21); bn_to_mon(m, ec_N, 21); bn_to_mon(e, ec_N, 21); bn_to_mon(R, ec_N, 21); bn_to_mon(kk, ec_N, 21); bn_mon_mul(S, R, kk, ec_N, 21); bn_add(kk, S, e, ec_N, 21); bn_mon_inv(minv, m, ec_N, 21); bn_mon_mul(S, minv, kk, ec_N, 21); bn_from_mon(R, ec_N, 21); bn_from_mon(S, ec_N, 21); }
static void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash) { u8 e[21]; u8 kk[21]; u8 m[21]; u8 minv[21]; struct point mG; e[0] = 0; memcpy(e + 1, hash, 20); bn_reduce(e, ec_N, 21); try_again: get_rand(m, sizeof m); m[0] = 0; if (bn_compare(m, ec_N, 21) >= 0) goto try_again; // R = (mG).x point_mul(&mG, m, &ec_G); point_from_mon(&mG); R[0] = 0; elt_copy(R+1, mG.x); // S = m**-1*(e + Rk) (mod N) bn_copy(kk, k, 21); bn_reduce(kk, ec_N, 21); bn_to_mon(m, ec_N, 21); bn_to_mon(e, ec_N, 21); bn_to_mon(R, ec_N, 21); bn_to_mon(kk, ec_N, 21); bn_mon_mul(S, R, kk, ec_N, 21); bn_add(kk, S, e, ec_N, 21); bn_mon_inv(minv, m, ec_N, 21); bn_mon_mul(S, minv, kk, ec_N, 21); bn_from_mon(R, ec_N, 21); bn_from_mon(S, ec_N, 21); }
static void elt_inv(u8 *d, u8 *a) { u8 s[20]; elt_copy(s, a); bn_mon_inv(d, s, ec_p, 20); }