Example #1
0
//////////////
// eBAT API //
//////////////
int crypto_dh_keypair(uchar *pk, uchar *sk)
{
  int i;
  mpz_t key;
  Kfield K;
  KSpoint base_point, res;
  KSparam KS;
  
  // Get random bytes for sk
  randombytes(sk,SECRETKEY_BYTES);
  sk[0] &= ~1; // clear bits 0
  
  // init field and base_point
  Kfield_init();
  KSinit(K, base_point);
  Kset_uipoly(base_point->x, 1);
  Kset_uipoly(base_point->y, 1);
  Kset_uipoly(base_point->z, 4);
  {
	  mpz_t tz;
	  mpz_init_set_str(tz,"908681679267597915035722095941517",10);
	  Kset_uipoly_wide(base_point->t, tz[0]._mp_d, tz[0]._mp_size);
	  mpz_clear(tz);
  }

  // put the key in an mpz
  mpz_init_set_ui(key, 0);
  for (i = SECRETKEY_BYTES-1; i > 0; --i) {
    mpz_add_ui(key, key, sk[i]);
    mpz_mul_2exp(key, key, 8);
  }
  mpz_add_ui(key, key, sk[0]);

  // Scalar multiplication
  KSinit(K, res);
  StandardKS(K, KS);
  KSmul(K, res, base_point, key, KS);
  Kinv(res->x, res->x);
  Kmul(res->y, res->y, res->x);
  Kmul(res->z, res->z, res->x);
  Kmul(res->t, res->t, res->x);
  
  // put the result in pk
  elt2bytes(pk, res->y);
  elt2bytes(pk+16, res->z);
  elt2bytes(pk+32, res->t);
 
  // clean
  mpz_clear(key);
  KSclear(K, base_point);
  KSclear(K, res);
  Kfield_clear();
  
  return 0;
}
Example #2
0
int crypto_dh(uchar *s,
    const uchar *pk,
    const uchar *sk)
{
  int i;
  mpz_t key;
  Kfield K;
  KSpoint base_point, res;
  KSparam KS;
  
  // init field and base_point
  Kfield_init();
  KSinit(K, base_point);

  // read base_point from {pk,pklen}
  bytes2elt(base_point->y, pk);
  bytes2elt(base_point->z, pk+16);
  bytes2elt(base_point->t, pk+32);
  base_point->x[0] = 1UL;
  for (i = 1; i < LIMB_PER_ELT; ++i)
    base_point->x[i] = 0UL;

  // put the key in an mpz
  mpz_init_set_ui(key, 0);
  for (i = SECRETKEY_BYTES-1; i > 0; --i) {
    mpz_add_ui(key, key, sk[i]);
    mpz_mul_2exp(key, key, 8);
  }
  mpz_add_ui(key, key, sk[0]);

  // Scalar multiplication
  KSinit(K, res);
  StandardKS(K, KS);
  KSmul(K, res, base_point, key, KS);
  Kinv(res->x, res->x);
  Kmul(res->y, res->y, res->x);
  Kmul(res->z, res->z, res->x);
  Kmul(res->t, res->t, res->x);

  
  // put the result in s
  elt2bytes(s, res->y);
  elt2bytes(s+16, res->z);
  elt2bytes(s+32, res->t);
 
  // clean
  mpz_clear(key);
  KSclear(K, base_point);
  KSclear(K, res);
  Kfield_clear();
  
  return 0;
}  
int main(int argc, char** argv) {
  mpz_t key;
  // field and dst_field are the same for this field
  mpfq_p_127_735_field k;
  KSpoint res, base_point;
  KSparam KS;
  int i;

  mpfq_p_127_735_field_init(k);

  if (argc != 6) {
    fprintf(stderr, "usage: %s key base_point\n", argv[0]);
    fprintf(stderr, "    key        is the secret key (an integer < 2^254)\n");
    fprintf(stderr, "    base_point is the point to multiply\n");
    fprintf(stderr, "    base_point must be of the form  1 y z t\n");
    fprintf(stderr, "    (integers less than 2^127, whitespace separated.\n");
    return 1;
  }

  // KS parameters.
  mpfq_p_127_735_init(k, &(KS->y0 ));
  mpfq_p_127_735_init(k, &(KS->z0 ));
  mpfq_p_127_735_init(k, &(KS->t0 ));
  mpfq_p_127_735_init(k, &(KS->y0p));
  mpfq_p_127_735_init(k, &(KS->z0p));
  mpfq_p_127_735_init(k, &(KS->t0p));

  mpfq_p_127_735_sscan(k, KS->y0, "86208552985914662648361214299883935423");
  mpfq_p_127_735_sscan(k, KS->z0, "160053938517731349632395585267160595069");
  mpfq_p_127_735_sscan(k, KS->t0, "35005564474699507747312683600916451858");
  mpfq_p_127_735_sscan(k, KS->y0p, "94814796580219064497014986095768528928");
  mpfq_p_127_735_sscan(k, KS->z0p, "42902767594179849850407630572137072504");
  mpfq_p_127_735_sscan(k, KS->t0p, "22524084758416781578372604087642334537");

  mpz_init_set_str(key, argv[1], 10);
  KSinit(k, base_point);
  mpfq_p_127_735_sscan(k, base_point->x, argv[2]);
  mpfq_p_127_735_sscan(k, base_point->y, argv[3]);
  mpfq_p_127_735_sscan(k, base_point->z, argv[4]);
  mpfq_p_127_735_sscan(k, base_point->t, argv[5]);
  
  KSinit(k, res);
  for (i = 0; i < 1000; ++i) {
    KSmul(k, res, base_point, key, KS);
  }

  mpfq_p_127_735_inv(k, res->x, res->x);
  mpfq_p_127_735_mul(k, res->y, res->y, res->x);
  mpfq_p_127_735_mul(k, res->z, res->z, res->x);
  mpfq_p_127_735_mul(k, res->t, res->t, res->x);
  mpfq_p_127_735_set_ui(k, res->x, 1UL);

  KSprint(k, res); printf("\n");

  mpfq_p_127_735_clear(k, &(KS->y0 ));
  mpfq_p_127_735_clear(k, &(KS->z0 ));
  mpfq_p_127_735_clear(k, &(KS->t0 ));
  mpfq_p_127_735_clear(k, &(KS->y0p));
  mpfq_p_127_735_clear(k, &(KS->z0p));
  mpfq_p_127_735_clear(k, &(KS->t0p));

  KSclear(k, base_point);
  KSclear(k, res);
  mpfq_p_127_735_field_clear(k);
  mpz_clear(key);
  return 0; 
}
// scalar multiplication on Surf127_735.
// key is 4 limb long.
void KSmul(mpfq_p_127_735_field k, dst_KSpoint res, src_KSpoint P, mpz_t key,
    src_KSparam KS) {
  KSpoint Pm, Pp;
  mpfq_p_127_735_elt tmpy, tmpz, tmpt;
  mpfq_p_127_735_elt YY, ZZ, TT;
  KSpoint_struct *pm, *pp, *tmp;
  int i, l;

  if (mpz_cmp_ui(key, 0)==0) {
    // implement me!
    assert (0);
  }

  if (mpz_cmp_ui(key, 1)==0) {
    KScopy(k, res, P);
    return;
  }

  KSinit(k, Pm); KSinit(k, Pp);
  KScopy(k, Pm, P);
  KSdouble(k, Pp, Pm, KS);

  if (mpz_cmp_ui(key, 2)==0) {
    KScopy(k, res, Pp);
    KSclear(k, Pm);
    KSclear(k, Pp);
    return;
  }

  mpfq_p_127_735_init(k, &tmpy);
  mpfq_p_127_735_init(k, &tmpz);
  mpfq_p_127_735_init(k, &tmpt);

  mpfq_p_127_735_init(k, &YY);
  mpfq_p_127_735_init(k, &ZZ);
  mpfq_p_127_735_init(k, &TT);

  mpfq_p_127_735_mul(k, tmpy, P->y, P->z);
  mpfq_p_127_735_mul(k, tmpz, tmpy, P->t);
  mpfq_p_127_735_inv(k, tmpz, tmpz);
  mpfq_p_127_735_mul(k, tmpz, tmpz, P->x);
  mpfq_p_127_735_mul(k, TT, tmpz, tmpy); // x/t
  mpfq_p_127_735_mul(k, tmpy, P->z, P->t);
  mpfq_p_127_735_mul(k, YY, tmpz, tmpy); // x/y
  mpfq_p_127_735_mul(k, tmpy, P->y, P->t);
  mpfq_p_127_735_mul(k, ZZ, tmpz, tmpy); // x/z

  // initialize loop
  pm = Pm;
  pp = Pp;

  // loop
  l = mpz_sizeinbase(key, 2);
  assert (mpz_tstbit(key, l-1) == 1);
  for (i = l-2; i >= 0; --i) {
    int swap;
    swap = (mpz_tstbit(key, i) == 1);
    if (swap) {
      tmp = pp; pp = pm; pm = tmp;
    }
    // pseudo add(pm, pp)  -> pp  ;   dble(pm) -> pm
    // Total: 32A + 16P + 9S

    KShadamard(k, pm);					// 8A
    mpfq_p_127_735_mul(k, tmpy, pm->y, KS->y0p);	
    mpfq_p_127_735_mul(k, tmpz, pm->z, KS->z0p);
    mpfq_p_127_735_mul(k, tmpt, pm->t, KS->t0p);	// 3P
    
    KShadamard(k, pp);					// 8A

    mpfq_p_127_735_mul(k, pp->x, pp->x, pm->x);
    mpfq_p_127_735_mul(k, pp->y, pp->y, tmpy);
    mpfq_p_127_735_mul(k, pp->z, pp->z, tmpz);
    mpfq_p_127_735_mul(k, pp->t, pp->t, tmpt);		// 4P
    
    KShadamard(k, pp);					// 8A

    mpfq_p_127_735_sqr(k, pp->x, pp->x);
    mpfq_p_127_735_sqr(k, pp->y, pp->y);
    mpfq_p_127_735_sqr(k, pp->z, pp->z);
    mpfq_p_127_735_sqr(k, pp->t, pp->t);		// 4S

    mpfq_p_127_735_mul(k, pp->y, pp->y, YY);
    mpfq_p_127_735_mul(k, pp->z, pp->z, ZZ);
    mpfq_p_127_735_mul(k, pp->t, pp->t, TT);		// 3P

    mpfq_p_127_735_sqr(k, pm->x, pm->x);		// 1S

    mpfq_p_127_735_mul(k, pm->y, pm->y, tmpy); 
    mpfq_p_127_735_mul(k, pm->z, pm->z, tmpz);
    mpfq_p_127_735_mul(k, pm->t, pm->t, tmpt);		// 3P

    KShadamard(k, pm);					// 8A
    
    mpfq_p_127_735_sqr(k, pm->x, pm->x);
    mpfq_p_127_735_sqr(k, pm->y, pm->y); 
    mpfq_p_127_735_sqr(k, pm->z, pm->z);
    mpfq_p_127_735_sqr(k, pm->t, pm->t);		// 4S

    mpfq_p_127_735_mul(k, pm->y, pm->y, KS->y0);
    mpfq_p_127_735_mul(k, pm->z, pm->z, KS->z0);
    mpfq_p_127_735_mul(k, pm->t, pm->t, KS->t0);	// 3P
    if (swap) {
      tmp = pp; pp = pm; pm = tmp;
    }
  }

  KScopy(k, res, pm);
  KSclear(k, Pm);
  KSclear(k, Pp);
 
  mpfq_p_127_735_clear(k, &YY);
  mpfq_p_127_735_clear(k, &ZZ);
  mpfq_p_127_735_clear(k, &TT);
  mpfq_p_127_735_clear(k, &tmpy);
  mpfq_p_127_735_clear(k, &tmpz);
  mpfq_p_127_735_clear(k, &tmpt);
}