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