void fe_mont_rhs(fe v2, fe u) {
  fe A, one;
  fe u2, Au, inner;

  fe_1(one);
  fe_0(A);
  A[0] = 486662;                     /* A = 486662 */

  fe_sq(u2, u);                      /* u^2 */
  fe_mul(Au, A, u);                  /* Au */
  fe_add(inner, u2, Au);             /* u^2 + Au */
  fe_add(inner, inner, one);         /* u^2 + Au + 1 */
  fe_mul(v2, u, inner);              /* u(u^2 + Au + 1) */
}
Beispiel #2
0
/* 
out = (1 / in) % m;
... using Fermat's Little Theorem
44 mul, 262 sq
*/
static void _inv(fe out, const fe in) {

    fe o, x2, x4, x8, x16, x32, t[16];
    long long i;

    _sq(o, in);
    for (i = 0; i < 1 - 1; ++i) _sq(o, o);
    _mul(x2, o, in);
    _sq(o, x2);
    for (i = 0; i < 2 - 1; ++i) _sq(o, o);
    _mul(x4, o, x2);
    _sq(o, x4);
    for (i = 0; i < 4 - 1; ++i) _sq(o, o);
    _mul(x8, o, x4);
    _sq(o, x8);
    for (i = 0; i < 8 - 1; ++i) _sq(o, o);
    _mul(x16, o, x8);
    _sq(o, x16);
    for (i = 0; i < 16 - 1; ++i) _sq(o, o);
    _mul(x32, o, x16);
    _sq(o, x32);
    for (i = 0; i < 32 - 1; ++i) _sq(o, o);
    for (i = 0; i < 32; ++i) _sq(o, o);
    _mul(o, o, x32);
    for (i = 0; i < 32; ++i) _sq(o, o);
    _mul(o, o, x32);

    fe_0(t[0]);
    fe_copy(t[1], in);
    _sq(t[2], t[1]);
    fe_copy(t[3], x2);
    for (i = 4; i < 15; ++i) {
        if ((i & 1) == 0) _sq(t[i], t[i / 2]);
        else _mul(t[i], t[i - 1], in);
    }
    fe_copy(t[15], x4);

    for (i = 0; i < 32; ++i) {
        _sq(o, o); _sq(o, o); _sq(o, o); _sq(o, o);
        _mul(o, o, t[m2[i]]);
    }
    fe_copy(out, o);

    cleanup(o); cleanup(t);
    cleanup(x2); cleanup(x4);
    cleanup(x8); cleanup(x16); cleanup(x32);
}
Beispiel #3
0
static int curve25519(unsigned char* q, unsigned char* n, unsigned char* p)
{
  unsigned char e[32];
  unsigned int i;
  fe x1;
  fe x2;
  fe z2;
  fe x3;
  fe z3;
  fe tmp0;
  fe tmp1;
  int pos;
  unsigned int swap;
  unsigned int b;

  for (i = 0;i < 32;++i) e[i] = n[i];
  e[0] &= 248;
  e[31] &= 127;
  e[31] |= 64;

  fe_frombytes(x1,p);
  fe_1(x2);
  fe_0(z2);
  fe_copy(x3,x1);
  fe_1(z3);

  swap = 0;
  for (pos = 254;pos >= 0;--pos) {
    b = e[pos / 8] >> (pos & 7);
    b &= 1;
    swap ^= b;
    fe_cswap(x2,x3,swap);
    fe_cswap(z2,z3,swap);
    swap = b;
#include <cyassl/ctaocrypt/ecc25519_montgomery.h>
  }
  fe_cswap(x2,x3,swap);
  fe_cswap(z2,z3,swap);

  fe_invert(z2,z2);
  fe_mul(x2,x2,z2);
  fe_tobytes(q,x2);

  return 0;
}
Beispiel #4
0
void fe_sqrt(fe out, const fe a)
{
  fe exp, b, b2, bi, i;
#ifndef NDEBUG
  fe legendre, zero, one;
#endif

  fe_frombytes(i, i_bytes); 
  fe_pow22523(exp, a);             /* b = a^(q-5)/8        */

  /* PRECONDITION: legendre symbol == 1 (square) or 0 (a == zero) */
#ifndef NDEBUG
  fe_sq(legendre, exp);            /* in^((q-5)/4) */ 
  fe_sq(legendre, legendre);       /* in^((q-5)/2) */
  fe_mul(legendre, legendre, a);   /* in^((q-3)/2) */
  fe_mul(legendre, legendre, a);   /* in^((q-1)/2) */
  
  fe_0(zero);
  fe_1(one);
  assert(fe_isequal(legendre, zero) || fe_isequal(legendre, one));
#endif

  fe_mul(b, a, exp);       /* b = a * a^(q-5)/8    */
  fe_sq(b2, b);            /* b^2 = a * a^(q-1)/4  */

  /* note b^4 == a^2, so b^2 == a or -a
   * if b^2 != a, multiply it by sqrt(-1) */
  fe_mul(bi, b, i);  
  fe_cmov(b, bi, 1 ^ fe_isequal(b2, a));
  fe_copy(out, b);

  /* PRECONDITION: out^2 == a */ 
#ifndef NDEBUG
  fe_sq(b2, out);
  assert(fe_isequal(a, b2));
#endif
}
Beispiel #5
0
void ge_p2_0(ge_p2 *h)
{
  fe_0(h->X);
  fe_1(h->Y);
  fe_1(h->Z);
}
Beispiel #6
0
static int
crypto_scalarmult_curve25519_ref10(unsigned char *q,
                                   const unsigned char *n,
                                   const unsigned char *p)
{
  unsigned char e[32];
  unsigned int i;
  fe x1;
  fe x2;
  fe z2;
  fe x3;
  fe z3;
  fe tmp0;
  fe tmp1;
  int pos;
  unsigned int swap;
  unsigned int b;

  for (i = 0;i < 32;++i) e[i] = n[i];
  e[0] &= 248;
  e[31] &= 127;
  e[31] |= 64;
  fe_frombytes(x1,p);
  fe_1(x2);
  fe_0(z2);
  fe_copy(x3,x1);
  fe_1(z3);

  swap = 0;
  for (pos = 254;pos >= 0;--pos) {
    b = e[pos / 8] >> (pos & 7);
    b &= 1;
    swap ^= b;
    fe_cswap(x2,x3,swap);
    fe_cswap(z2,z3,swap);
    swap = b;
    fe_sub(tmp0,x3,z3);
    fe_sub(tmp1,x2,z2);
    fe_add(x2,x2,z2);
    fe_add(z2,x3,z3);
    fe_mul(z3,tmp0,x2);
    fe_mul(z2,z2,tmp1);
    fe_sq(tmp0,tmp1);
    fe_sq(tmp1,x2);
    fe_add(x3,z3,z2);
    fe_sub(z2,z3,z2);
    fe_mul(x2,tmp1,tmp0);
    fe_sub(tmp1,tmp1,tmp0);
    fe_sq(z2,z2);
    fe_mul121666(z3,tmp1);
    fe_sq(x3,x3);
    fe_add(tmp0,tmp0,z3);
    fe_mul(z3,x1,z2);
    fe_mul(z2,tmp1,tmp0);
  }
  fe_cswap(x2,x3,swap);
  fe_cswap(z2,z3,swap);

  fe_invert(z2,z2);
  fe_mul(x2,x2,z2);
  fe_tobytes(q,x2);
  return 0;
}
int elligator_fast_test(int silent)
{
  unsigned char elligator_correct_output[32] = 
  {
  0x5f, 0x35, 0x20, 0x00, 0x1c, 0x6c, 0x99, 0x36, 
  0xa3, 0x12, 0x06, 0xaf, 0xe7, 0xc7, 0xac, 0x22, 
  0x4e, 0x88, 0x61, 0x61, 0x9b, 0xf9, 0x88, 0x72, 
  0x44, 0x49, 0x15, 0x89, 0x9d, 0x95, 0xf4, 0x6e
  };

  unsigned char hashtopoint_correct_output1[32] = 
  {
  0xce, 0x89, 0x9f, 0xb2, 0x8f, 0xf7, 0x20, 0x91,
  0x5e, 0x14, 0xf5, 0xb7, 0x99, 0x08, 0xab, 0x17,
  0xaa, 0x2e, 0xe2, 0x45, 0xb4, 0xfc, 0x2b, 0xf6,
  0x06, 0x36, 0x29, 0x40, 0xed, 0x7d, 0xe7, 0xed
  };

  unsigned char hashtopoint_correct_output2[32] = 
  {
  0xa0, 0x35, 0xbb, 0xa9, 0x4d, 0x30, 0x55, 0x33, 
  0x0d, 0xce, 0xc2, 0x7f, 0x83, 0xde, 0x79, 0xd0, 
  0x89, 0x67, 0x72, 0x4c, 0x07, 0x8d, 0x68, 0x9d, 
  0x61, 0x52, 0x1d, 0xf9, 0x2c, 0x5c, 0xba, 0x77
  };

  unsigned char calculatev_correct_output[32] = 
  {
  0x1b, 0x77, 0xb5, 0xa0, 0x44, 0x84, 0x7e, 0xb9, 
  0x23, 0xd7, 0x93, 0x18, 0xce, 0xc2, 0xc5, 0xe2, 
  0x84, 0xd5, 0x79, 0x6f, 0x65, 0x63, 0x1b, 0x60, 
  0x9b, 0xf1, 0xf8, 0xce, 0x88, 0x0b, 0x50, 0x9c,
  };

  int count;
  fe in, out;
  unsigned char bytes[32];
  fe_0(in);
  fe_0(out);
  for (count = 0; count < 32; count++) {
    bytes[count] = count;
  }
  fe_frombytes(in, bytes);
  elligator(out, in);
  fe_tobytes(bytes, out);
  TEST("Elligator vector", memcmp(bytes, elligator_correct_output, 32) == 0);

  /* Elligator(0) == 0 test */
  fe_0(in);
  elligator(out, in);
  TEST("Elligator(0) == 0", memcmp(in, out, 32) == 0);

  /* ge_montx_to_p3(0) -> order2 point test */
  fe one, negone, zero;
  fe_1(one);
  fe_0(zero);
  fe_sub(negone, zero, one);
  ge_p3 p3;
  ge_montx_to_p3(&p3, zero, 0);
  TEST("ge_montx_to_p3(0) == order 2 point", 
      fe_isequal(p3.X, zero) &&
      fe_isequal(p3.Y, negone) &&
      fe_isequal(p3.Z, one) && 
      fe_isequal(p3.T, zero));

  /* Hash to point vector test */
  unsigned char htp[32];
  
  for (count=0; count < 32; count++) {
    htp[count] = count;
  }

  hash_to_point(&p3, htp, 32);
  ge_p3_tobytes(htp, &p3);
  TEST("hash_to_point #1", memcmp(htp, hashtopoint_correct_output1, 32) == 0);

  for (count=0; count < 32; count++) {
    htp[count] = count+1;
  }

  hash_to_point(&p3, htp, 32);
  ge_p3_tobytes(htp, &p3);
  TEST("hash_to_point #2", memcmp(htp, hashtopoint_correct_output2, 32) == 0);

  /* calculate_U vector test */
  ge_p3 Bv;
  unsigned char V[32];
  unsigned char Vbuf[200];
  unsigned char a[32];
  unsigned char A[32];
  unsigned char Vmsg[3];
  Vmsg[0] = 0;
  Vmsg[1] = 1;
  Vmsg[2] = 2;
  for (count=0; count < 32; count++) {
    a[count] = 8 + count;
    A[count] = 9 + count;
  }
  sc_clamp(a);
  calculate_Bv_and_V(&Bv, V, Vbuf, a, A, Vmsg, 3);
  TEST("calculate_Bv_and_V vector", memcmp(V, calculatev_correct_output, 32) == 0);
  return 0;
}
Beispiel #8
0
void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) {
    unsigned char e[32];
    unsigned int i;
    
    fe x1;
    fe x2;
    fe z2;
    fe x3;
    fe z3;
    fe tmp0;
    fe tmp1;
	
    int pos;
    unsigned int swap;
    unsigned int b;
	
    /* copy the private key and make sure it's valid */
    for (i = 0; i < 32; ++i) {
        e[i] = private_key[i];
    }
	
    e[0] &= 248;
    e[31] &= 63;
    e[31] |= 64;
	
    /* unpack the public key and convert edwards to montgomery */
    /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */
    fe_frombytes(x1, public_key);
    fe_1(tmp1);
    fe_add(tmp0, x1, tmp1);
    fe_sub(tmp1, tmp1, x1);
    fe_invert(tmp1, tmp1);
    fe_mul(x1, tmp0, tmp1);
	
    fe_1(x2);
    fe_0(z2);
    fe_copy(x3, x1);
    fe_1(z3);
	
    swap = 0;
    for (pos = 254; pos >= 0; --pos) {
        b = e[pos / 8] >> (pos & 7);
        b &= 1;
        swap ^= b;
        fe_cswap(x2, x3, swap);
        fe_cswap(z2, z3, swap);
        swap = b;
		
        /* from montgomery.h */
        fe_sub(tmp0, x3, z3);
        fe_sub(tmp1, x2, z2);
        fe_add(x2, x2, z2);
        fe_add(z2, x3, z3);
        fe_mul(z3, tmp0, x2);
        fe_mul(z2, z2, tmp1);
        fe_sq(tmp0, tmp1);
        fe_sq(tmp1, x2);
        fe_add(x3, z3, z2);
        fe_sub(z2, z3, z2);
        fe_mul(x2, tmp1, tmp0);
        fe_sub(tmp1, tmp1, tmp0);
        fe_sq(z2, z2);
        fe_mul121666(z3, tmp1);
        fe_sq(x3, x3);
        fe_add(tmp0, tmp0, z3);
        fe_mul(z3, x1, z2);
        fe_mul(z2, tmp1, tmp0);
    }
	
    fe_cswap(x2, x3, swap);
    fe_cswap(z2, z3, swap);
	
    fe_invert(z2, z2);
    fe_mul(x2, x2, z2);
    fe_tobytes(shared_secret, x2);
}
Beispiel #9
0
static inline void ge_precomp_0(ge_precomp *h)
{
  fe_1(h->yplusx);
  fe_1(h->yminusx);
  fe_0(h->xy2d);
}