void ec_multiply (ec_point *p, const vl_point k) /* sets p := k*p */ { vl_point h; int z, hi, ki; word16 i; ec_point r; gf_copy (r.x, p->x); p->x[0] = 0; gf_copy (r.y, p->y); p->y[0] = 0; vl_shortmultiply (h, k, 3); z = vl_numbits (h) - 1; /* so vl_takebit (h, z) == 1 */ i = 1; for (;;) { hi = vl_takebit (h, i); ki = vl_takebit (k, i); if (hi == 1 && ki == 0) { ec_add (p, &r); } if (hi == 0 && ki == 1) { ec_sub (p, &r); } if (i >= z) { break; } i++; ec_double (&r); } } /* ec_multiply */
void ec_add (ec_point *p, const ec_point *q) /* sets p := p + q */ { gf_point lambda, t, tx, ty, x3; /* first check if there is indeed work to do (q != 0): */ if (q->x[0] != 0 || q->y[0] != 0) { if (p->x[0] != 0 || p->y[0] != 0) { /* p != 0 and q != 0 */ if (gf_equal (p->x, q->x)) { /* either p == q or p == -q: */ if (gf_equal (p->y, q->y)) { /* points are equal; double p: */ ec_double (p); } else { /* must be inverse: result is zero */ /* (should assert that q->y = p->x + p->y) */ p->x[0] = p->y[0] = 0; } } else { /* p != 0, q != 0, p != q, p != -q */ /* evaluate lambda = (y1 + y2)/(x1 + x2): */ gf_add (ty, p->y, q->y); gf_add (tx, p->x, q->x); gf_invert (t, tx); gf_multiply (lambda, ty, t); /* evaluate x3 = lambda^2 + lambda + x1 + x2: */ gf_square (x3, lambda); gf_add (x3, x3, lambda); gf_add (x3, x3, tx); /* evaluate y3 = lambda*(x1 + x3) + x3 + y1: */ gf_add (tx, p->x, x3); gf_multiply (t, lambda, tx); gf_add (t, t, x3); gf_add (p->y, t, p->y); /* deposit the value of x3: */ gf_copy (p->x, x3); } } else { /* just copy q into p: */ gf_copy (p->x, q->x); gf_copy (p->y, q->y); } } } /* ec_add */
static void ec_add(const uint32_t *px, const uint32_t *py, const uint32_t *qx, const uint32_t *qy, uint32_t *Sx, uint32_t *Sy){ uint32_t tempA[8]; uint32_t tempB[8]; uint32_t tempC[8]; uint32_t tempD[16]; if(isZero(px) && isZero(py)){ copy(qx, Sx,arrayLength); copy(qy, Sy,arrayLength); return; } else if(isZero(qx) && isZero(qy)) { copy(px, Sx,arrayLength); copy(py, Sy,arrayLength); return; } if(isSame(px, qx, arrayLength)){ if(!isSame(py, qy, arrayLength)){ setZero(Sx, 8); setZero(Sy, 8); return; } else { ec_double(px, py, Sx, Sy); return; } } fieldSub(py, qy, ecc_prime_m, tempA); fieldSub(px, qx, ecc_prime_m, tempB); fieldInv(tempB, ecc_prime_m, ecc_prime_r, tempB); fieldMult(tempA, tempB, tempD, arrayLength); fieldModP(tempC, tempD); //tempC = lambda fieldMult(tempC, tempC, tempD, arrayLength); //tempA = lambda^2 fieldModP(tempA, tempD); fieldSub(tempA, px, ecc_prime_m, tempB); //lambda^2 - Px fieldSub(tempB, qx, ecc_prime_m, Sx); //lambda^2 - Px - Qx fieldSub(qx, Sx, ecc_prime_m, tempB); fieldMult(tempC, tempB, tempD, arrayLength); fieldModP(tempC, tempD); fieldSub(tempC, qy, ecc_prime_m, Sy); }
void ecc_ec_mult(const uint32_t *px, const uint32_t *py, const uint32_t *secret, uint32_t *resultx, uint32_t *resulty){ uint32_t Qx[8]; uint32_t Qy[8]; setZero(Qx, 8); setZero(Qy, 8); uint32_t tempx[8]; uint32_t tempy[8]; int i; for (i = 256;i--;){ ec_double(Qx, Qy, tempx, tempy); copy(tempx, Qx,arrayLength); copy(tempy, Qy,arrayLength); if (((secret[i / 32]) & ((uint32_t)1 << (i % 32)))) { ec_add(Qx, Qy, px, py, tempx, tempy); //eccAdd copy(tempx, Qx,arrayLength); copy(tempy, Qy,arrayLength); } } copy(Qx, resultx,arrayLength); copy(Qy, resulty,arrayLength); }
void ecc_ec_double(const uint32_t *px, const uint32_t *py, uint32_t *Dx, uint32_t *Dy) { ec_double(px, py, Dx, Dy); }