#include "fe.h"
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;
+ unsigned char e[32];
+ unsigned int i;
- int pos;
- unsigned int swap;
- unsigned int b;
+ fe x1;
+ fe x2;
+ fe z2;
+ fe x3;
+ fe z3;
+ fe tmp0;
+ fe tmp1;
- /* copy the private key and make sure it's valid */
- for (i = 0; i < 32; ++i) {
- e[i] = private_key[i];
- }
+ int pos;
+ unsigned int swap;
+ unsigned int b;
- e[0] &= 248;
- e[31] &= 63;
- e[31] |= 64;
+ /* copy the private key and make sure it's valid */
+ for(i = 0; i < 32; ++i) {
+ e[i] = private_key[i];
+ }
- /* 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);
+ e[0] &= 248;
+ e[31] &= 63;
+ e[31] |= 64;
- fe_1(x2);
- fe_0(z2);
- fe_copy(x3, x1);
- fe_1(z3);
+ /* 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);
- 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_1(x2);
+ fe_0(z2);
+ fe_copy(x3, x1);
+ fe_1(z3);
- /* 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);
- }
+ swap = 0;
- fe_cswap(x2, x3, swap);
- fe_cswap(z2, z3, swap);
+ 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_invert(z2, z2);
- fe_mul(x2, x2, z2);
- fe_tobytes(shared_secret, x2);
+ /* 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);
}