////////////// // 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; }
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); }