Beispiel #1
0
static void choose_t(ge25519_aff *t, signed char b)
{
  fe25519 v;
  unsigned char u;
  signed char const mask = b >> 7;
  u = (b + mask) ^ mask;

  *t = ge25519_base_multiples_affine[u];

  fe25519_neg(&v, &t->x);
  fe25519_cmov(&t->x, &v, negative(b));
}
Beispiel #2
0
static void choose_t(ge25519_aff *t, unsigned long long pos, signed char b)
{
  /* constant time */
  fe25519 v;
  *t = ge25519_base_multiples_affine[5*pos+0];
  cmov_aff(t, &ge25519_base_multiples_affine[5*pos+1],equal(b,1) | equal(b,-1));
  cmov_aff(t, &ge25519_base_multiples_affine[5*pos+2],equal(b,2) | equal(b,-2));
  cmov_aff(t, &ge25519_base_multiples_affine[5*pos+3],equal(b,3) | equal(b,-3));
  cmov_aff(t, &ge25519_base_multiples_affine[5*pos+4],equal(b,-4));
  fe25519_neg(&v, &t->x);
  fe25519_cmov(&t->x, &v, negative(b));
}
Beispiel #3
0
/* return 0 on success, -1 otherwise */
int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
{
    unsigned char par;

    fe25519 t, chk, num, den, den2, den4, den6;
    fe25519_setone(&r->z);
    par = p[31] >> 7;
    fe25519_unpack(&r->y, p);
    fe25519_square(&num, &r->y); /* x = y^2 */
    fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */
    fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */
    fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */

    /* Computation of sqrt(num/den) */
    /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
    fe25519_square(&den2, &den);
    fe25519_square(&den4, &den2);
    fe25519_mul(&den6, &den4, &den2);
    fe25519_mul(&t, &den6, &num);
    fe25519_mul(&t, &t, &den);

    fe25519_pow2523(&t, &t);
    /* 2. computation of r->x = t * num * den^3 */
    fe25519_mul(&t, &t, &num);
    fe25519_mul(&t, &t, &den);
    fe25519_mul(&t, &t, &den);
    fe25519_mul(&r->x, &t, &den);

    /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */
    fe25519_square(&chk, &r->x);
    fe25519_mul(&chk, &chk, &den);
    if (!fe25519_iseq_vartime(&chk, &num)) {
        fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1);
    }

    /* 4. Now we have one of the two square roots, except if input was not a square */
    fe25519_square(&chk, &r->x);
    fe25519_mul(&chk, &chk, &den);
    if (!fe25519_iseq_vartime(&chk, &num)) {
        return -1;
    }

    /* 5. Choose the desired square root according to parity: */
    if(fe25519_getparity(&r->x) != (1-par)) {
        fe25519_neg(&r->x, &r->x);
    }

    fe25519_mul(&r->t, &r->x, &r->y);

    return 0;
}
Beispiel #4
0
/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */
static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
{
  fe25519 a,b,c,d;
  fe25519_square(&a, &p->x);
  fe25519_square(&b, &p->y);
  fe25519_square(&c, &p->z);
  fe25519_add(&c, &c, &c);
  fe25519_neg(&d, &a);

  fe25519_add(&r->x, &p->x, &p->y);
  fe25519_square(&r->x, &r->x);
  fe25519_sub(&r->x, &r->x, &a);
  fe25519_sub(&r->x, &r->x, &b);
  fe25519_add(&r->z, &d, &b);
  fe25519_sub(&r->t, &r->z, &c);
  fe25519_sub(&r->y, &d, &b);
}
Beispiel #5
0
/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */
static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
{
  fe25519 a,b,c,d;
  fe25519_square(&a, &p->x);
  fe25519_square(&b, &p->y);
  fe25519_square(&c, &p->z);
  fe25519_add(&c, &c, &c);
  //here, you have to fully reduce &d  because subtraction needs a <= p
  fe25519_freeze(&c); //do not remove
  fe25519_neg(&d, &a);

  fe25519_add(&r->x, &p->x, &p->y);
  fe25519_square(&r->x, &r->x);
  fe25519_sub(&r->x, &r->x, &a);
  fe25519_sub(&r->x, &r->x, &b);
  fe25519_add(&r->z, &d, &b);
  fe25519_sub(&r->t, &r->z, &c);
  fe25519_sub(&r->y, &d, &b);
}
/* computes [s1]p1 + [s2]p2 */
void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const sc25519 *s2)
{
  signed char slide1[256], slide2[256];
  ge25519_pniels pre1[PRE1_SIZE], neg;
  ge25519_p3 d1;
  ge25519_p1p1 t;
  ge25519_niels nneg;
  fe25519 d;
  int i;
  
  sc25519_slide(slide1, s1, S1_SWINDOWSIZE);
  sc25519_slide(slide2, s2, S2_SWINDOWSIZE);

  /* precomputation */
  pre1[0] = *(ge25519_pniels *)p1;                                                                         
  ge25519_dbl_p1p1(&t,(ge25519_p2 *)pre1);      ge25519_p1p1_to_p3(&d1, &t);
  /* Convert pre[0] to projective Niels representation */
  d = pre1[0].ysubx;
  fe25519_sub(&pre1[0].ysubx, &pre1[0].xaddy, &pre1[0].ysubx);
  fe25519_add(&pre1[0].xaddy, &pre1[0].xaddy, &d);
  fe25519_mul(&pre1[0].t2d, &pre1[0].t2d, &ec2d);

  for(i=0;i<PRE1_SIZE-1;i++)
  {
    ge25519_pnielsadd_p1p1(&t, &d1, &pre1[i]);  ge25519_p1p1_to_pniels(&pre1[i+1], &t);
  }

  setneutral(r);
  for (i = 255;i >= 0;--i) {
    if (slide1[i] || slide2[i]) goto firstbit;
  }

  for(;i>=0;i--)
  {
    firstbit:

    ge25519_dbl_p1p1(&t, (ge25519_p2 *)r);

    if(slide1[i]>0)
    {
      ge25519_p1p1_to_p3(r, &t);
      ge25519_pnielsadd_p1p1(&t, r, &pre1[slide1[i]/2]);
    }
    else if(slide1[i]<0)
    {
      ge25519_p1p1_to_p3(r, &t);
      neg = pre1[-slide1[i]/2];
      d = neg.ysubx;
      neg.ysubx = neg.xaddy;
      neg.xaddy = d;
      fe25519_neg(&neg.t2d, &neg.t2d);
      ge25519_pnielsadd_p1p1(&t, r, &neg);
    }

    if(slide2[i]>0)
    {
      ge25519_p1p1_to_p3(r, &t);
      ge25519_nielsadd_p1p1(&t, r, &pre2[slide2[i]/2]);
    }
    else if(slide2[i]<0)
    {
      ge25519_p1p1_to_p3(r, &t);
      nneg = pre2[-slide2[i]/2];
      d = nneg.ysubx;
      nneg.ysubx = nneg.xaddy;
      nneg.xaddy = d;
      fe25519_neg(&nneg.t2d, &nneg.t2d);
      ge25519_nielsadd_p1p1(&t, r, &nneg);
    }

    ge25519_p1p1_to_p2((ge25519_p2 *)r, &t);
  }
}