|
|
@ -45,116 +45,116 @@ load_4(const unsigned char *in) |
|
|
|
#endif |
|
|
|
|
|
|
|
void |
|
|
|
fe_invert(fe out, const fe z) |
|
|
|
fe25519_invert(fe25519 out, const fe25519 z) |
|
|
|
{ |
|
|
|
fe t0; |
|
|
|
fe t1; |
|
|
|
fe t2; |
|
|
|
fe t3; |
|
|
|
int i; |
|
|
|
|
|
|
|
fe_sq(t0, z); |
|
|
|
fe_sq(t1, t0); |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe_mul(t1, z, t1); |
|
|
|
fe_mul(t0, t0, t1); |
|
|
|
fe_sq(t2, t0); |
|
|
|
fe_mul(t1, t1, t2); |
|
|
|
fe_sq(t2, t1); |
|
|
|
fe25519 t0; |
|
|
|
fe25519 t1; |
|
|
|
fe25519 t2; |
|
|
|
fe25519 t3; |
|
|
|
int i; |
|
|
|
|
|
|
|
fe25519_sq(t0, z); |
|
|
|
fe25519_sq(t1, t0); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
fe25519_mul(t1, z, t1); |
|
|
|
fe25519_mul(t0, t0, t1); |
|
|
|
fe25519_sq(t2, t0); |
|
|
|
fe25519_mul(t1, t1, t2); |
|
|
|
fe25519_sq(t2, t1); |
|
|
|
for (i = 1; i < 5; ++i) { |
|
|
|
fe_sq(t2, t2); |
|
|
|
fe25519_sq(t2, t2); |
|
|
|
} |
|
|
|
fe_mul(t1, t2, t1); |
|
|
|
fe_sq(t2, t1); |
|
|
|
fe25519_mul(t1, t2, t1); |
|
|
|
fe25519_sq(t2, t1); |
|
|
|
for (i = 1; i < 10; ++i) { |
|
|
|
fe_sq(t2, t2); |
|
|
|
fe25519_sq(t2, t2); |
|
|
|
} |
|
|
|
fe_mul(t2, t2, t1); |
|
|
|
fe_sq(t3, t2); |
|
|
|
fe25519_mul(t2, t2, t1); |
|
|
|
fe25519_sq(t3, t2); |
|
|
|
for (i = 1; i < 20; ++i) { |
|
|
|
fe_sq(t3, t3); |
|
|
|
fe25519_sq(t3, t3); |
|
|
|
} |
|
|
|
fe_mul(t2, t3, t2); |
|
|
|
fe_sq(t2, t2); |
|
|
|
fe25519_mul(t2, t3, t2); |
|
|
|
fe25519_sq(t2, t2); |
|
|
|
for (i = 1; i < 10; ++i) { |
|
|
|
fe_sq(t2, t2); |
|
|
|
fe25519_sq(t2, t2); |
|
|
|
} |
|
|
|
fe_mul(t1, t2, t1); |
|
|
|
fe_sq(t2, t1); |
|
|
|
fe25519_mul(t1, t2, t1); |
|
|
|
fe25519_sq(t2, t1); |
|
|
|
for (i = 1; i < 50; ++i) { |
|
|
|
fe_sq(t2, t2); |
|
|
|
fe25519_sq(t2, t2); |
|
|
|
} |
|
|
|
fe_mul(t2, t2, t1); |
|
|
|
fe_sq(t3, t2); |
|
|
|
fe25519_mul(t2, t2, t1); |
|
|
|
fe25519_sq(t3, t2); |
|
|
|
for (i = 1; i < 100; ++i) { |
|
|
|
fe_sq(t3, t3); |
|
|
|
fe25519_sq(t3, t3); |
|
|
|
} |
|
|
|
fe_mul(t2, t3, t2); |
|
|
|
fe_sq(t2, t2); |
|
|
|
fe25519_mul(t2, t3, t2); |
|
|
|
fe25519_sq(t2, t2); |
|
|
|
for (i = 1; i < 50; ++i) { |
|
|
|
fe_sq(t2, t2); |
|
|
|
fe25519_sq(t2, t2); |
|
|
|
} |
|
|
|
fe_mul(t1, t2, t1); |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe25519_mul(t1, t2, t1); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
for (i = 1; i < 5; ++i) { |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
} |
|
|
|
fe_mul(out, t1, t0); |
|
|
|
fe25519_mul(out, t1, t0); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
fe_pow22523(fe out, const fe z) |
|
|
|
fe25519_pow22523(fe25519 out, const fe25519 z) |
|
|
|
{ |
|
|
|
fe t0; |
|
|
|
fe t1; |
|
|
|
fe t2; |
|
|
|
int i; |
|
|
|
|
|
|
|
fe_sq(t0, z); |
|
|
|
fe_sq(t1, t0); |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe_mul(t1, z, t1); |
|
|
|
fe_mul(t0, t0, t1); |
|
|
|
fe_sq(t0, t0); |
|
|
|
fe_mul(t0, t1, t0); |
|
|
|
fe_sq(t1, t0); |
|
|
|
fe25519 t0; |
|
|
|
fe25519 t1; |
|
|
|
fe25519 t2; |
|
|
|
int i; |
|
|
|
|
|
|
|
fe25519_sq(t0, z); |
|
|
|
fe25519_sq(t1, t0); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
fe25519_mul(t1, z, t1); |
|
|
|
fe25519_mul(t0, t0, t1); |
|
|
|
fe25519_sq(t0, t0); |
|
|
|
fe25519_mul(t0, t1, t0); |
|
|
|
fe25519_sq(t1, t0); |
|
|
|
for (i = 1; i < 5; ++i) { |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
} |
|
|
|
fe_mul(t0, t1, t0); |
|
|
|
fe_sq(t1, t0); |
|
|
|
fe25519_mul(t0, t1, t0); |
|
|
|
fe25519_sq(t1, t0); |
|
|
|
for (i = 1; i < 10; ++i) { |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
} |
|
|
|
fe_mul(t1, t1, t0); |
|
|
|
fe_sq(t2, t1); |
|
|
|
fe25519_mul(t1, t1, t0); |
|
|
|
fe25519_sq(t2, t1); |
|
|
|
for (i = 1; i < 20; ++i) { |
|
|
|
fe_sq(t2, t2); |
|
|
|
fe25519_sq(t2, t2); |
|
|
|
} |
|
|
|
fe_mul(t1, t2, t1); |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe25519_mul(t1, t2, t1); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
for (i = 1; i < 10; ++i) { |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
} |
|
|
|
fe_mul(t0, t1, t0); |
|
|
|
fe_sq(t1, t0); |
|
|
|
fe25519_mul(t0, t1, t0); |
|
|
|
fe25519_sq(t1, t0); |
|
|
|
for (i = 1; i < 50; ++i) { |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
} |
|
|
|
fe_mul(t1, t1, t0); |
|
|
|
fe_sq(t2, t1); |
|
|
|
fe25519_mul(t1, t1, t0); |
|
|
|
fe25519_sq(t2, t1); |
|
|
|
for (i = 1; i < 100; ++i) { |
|
|
|
fe_sq(t2, t2); |
|
|
|
fe25519_sq(t2, t2); |
|
|
|
} |
|
|
|
fe_mul(t1, t2, t1); |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe25519_mul(t1, t2, t1); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
for (i = 1; i < 50; ++i) { |
|
|
|
fe_sq(t1, t1); |
|
|
|
fe25519_sq(t1, t1); |
|
|
|
} |
|
|
|
fe_mul(t0, t1, t0); |
|
|
|
fe_sq(t0, t0); |
|
|
|
fe_sq(t0, t0); |
|
|
|
fe_mul(out, t0, z); |
|
|
|
fe25519_mul(t0, t1, t0); |
|
|
|
fe25519_sq(t0, t0); |
|
|
|
fe25519_sq(t0, t0); |
|
|
|
fe25519_mul(out, t0, z); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
@ -164,19 +164,19 @@ fe_pow22523(fe out, const fe z) |
|
|
|
void |
|
|
|
ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) |
|
|
|
{ |
|
|
|
fe t0; |
|
|
|
|
|
|
|
fe_add(r->X, p->Y, p->X); |
|
|
|
fe_sub(r->Y, p->Y, p->X); |
|
|
|
fe_mul(r->Z, r->X, q->YplusX); |
|
|
|
fe_mul(r->Y, r->Y, q->YminusX); |
|
|
|
fe_mul(r->T, q->T2d, p->T); |
|
|
|
fe_mul(r->X, p->Z, q->Z); |
|
|
|
fe_add(t0, r->X, r->X); |
|
|
|
fe_sub(r->X, r->Z, r->Y); |
|
|
|
fe_add(r->Y, r->Z, r->Y); |
|
|
|
fe_add(r->Z, t0, r->T); |
|
|
|
fe_sub(r->T, t0, r->T); |
|
|
|
fe25519 t0; |
|
|
|
|
|
|
|
fe25519_add(r->X, p->Y, p->X); |
|
|
|
fe25519_sub(r->Y, p->Y, p->X); |
|
|
|
fe25519_mul(r->Z, r->X, q->YplusX); |
|
|
|
fe25519_mul(r->Y, r->Y, q->YminusX); |
|
|
|
fe25519_mul(r->T, q->T2d, p->T); |
|
|
|
fe25519_mul(r->X, p->Z, q->Z); |
|
|
|
fe25519_add(t0, r->X, r->X); |
|
|
|
fe25519_sub(r->X, r->Z, r->Y); |
|
|
|
fe25519_add(r->Y, r->Z, r->Y); |
|
|
|
fe25519_add(r->Z, t0, r->T); |
|
|
|
fe25519_sub(r->T, t0, r->T); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
@ -224,44 +224,44 @@ slide_vartime(signed char *r, const unsigned char *a) |
|
|
|
int |
|
|
|
ge_frombytes(ge_p3 *h, const unsigned char *s) |
|
|
|
{ |
|
|
|
fe u; |
|
|
|
fe v; |
|
|
|
fe v3; |
|
|
|
fe vxx; |
|
|
|
fe m_root_check, p_root_check; |
|
|
|
fe negx; |
|
|
|
fe x_sqrtm1; |
|
|
|
int has_m_root, has_p_root; |
|
|
|
|
|
|
|
fe_frombytes(h->Y, s); |
|
|
|
fe_1(h->Z); |
|
|
|
fe_sq(u, h->Y); |
|
|
|
fe_mul(v, u, d); |
|
|
|
fe_sub(u, u, h->Z); /* u = y^2-1 */ |
|
|
|
fe_add(v, v, h->Z); /* v = dy^2+1 */ |
|
|
|
|
|
|
|
fe_sq(v3, v); |
|
|
|
fe_mul(v3, v3, v); /* v3 = v^3 */ |
|
|
|
fe_sq(h->X, v3); |
|
|
|
fe_mul(h->X, h->X, v); |
|
|
|
fe_mul(h->X, h->X, u); /* x = uv^7 */ |
|
|
|
|
|
|
|
fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ |
|
|
|
fe_mul(h->X, h->X, v3); |
|
|
|
fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ |
|
|
|
|
|
|
|
fe_sq(vxx, h->X); |
|
|
|
fe_mul(vxx, vxx, v); |
|
|
|
fe_sub(m_root_check, vxx, u); /* vx^2-u */ |
|
|
|
fe_add(p_root_check, vxx, u); /* vx^2+u */ |
|
|
|
has_m_root = fe_iszero(m_root_check); |
|
|
|
has_p_root = fe_iszero(p_root_check); |
|
|
|
fe_mul(x_sqrtm1, h->X, sqrtm1); /* x*sqrt(-1) */ |
|
|
|
fe_cmov(h->X, x_sqrtm1, 1 - has_m_root); |
|
|
|
|
|
|
|
fe_neg(negx, h->X); |
|
|
|
fe_cmov(h->X, negx, fe_isnegative(h->X) ^ (s[31] >> 7)); |
|
|
|
fe_mul(h->T, h->X, h->Y); |
|
|
|
fe25519 u; |
|
|
|
fe25519 v; |
|
|
|
fe25519 v3; |
|
|
|
fe25519 vxx; |
|
|
|
fe25519 m_root_check, p_root_check; |
|
|
|
fe25519 negx; |
|
|
|
fe25519 x_sqrtm1; |
|
|
|
int has_m_root, has_p_root; |
|
|
|
|
|
|
|
fe25519_frombytes(h->Y, s); |
|
|
|
fe25519_1(h->Z); |
|
|
|
fe25519_sq(u, h->Y); |
|
|
|
fe25519_mul(v, u, d); |
|
|
|
fe25519_sub(u, u, h->Z); /* u = y^2-1 */ |
|
|
|
fe25519_add(v, v, h->Z); /* v = dy^2+1 */ |
|
|
|
|
|
|
|
fe25519_sq(v3, v); |
|
|
|
fe25519_mul(v3, v3, v); /* v3 = v^3 */ |
|
|
|
fe25519_sq(h->X, v3); |
|
|
|
fe25519_mul(h->X, h->X, v); |
|
|
|
fe25519_mul(h->X, h->X, u); /* x = uv^7 */ |
|
|
|
|
|
|
|
fe25519_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ |
|
|
|
fe25519_mul(h->X, h->X, v3); |
|
|
|
fe25519_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ |
|
|
|
|
|
|
|
fe25519_sq(vxx, h->X); |
|
|
|
fe25519_mul(vxx, vxx, v); |
|
|
|
fe25519_sub(m_root_check, vxx, u); /* vx^2-u */ |
|
|
|
fe25519_add(p_root_check, vxx, u); /* vx^2+u */ |
|
|
|
has_m_root = fe25519_iszero(m_root_check); |
|
|
|
has_p_root = fe25519_iszero(p_root_check); |
|
|
|
fe25519_mul(x_sqrtm1, h->X, sqrtm1); /* x*sqrt(-1) */ |
|
|
|
fe25519_cmov(h->X, x_sqrtm1, 1 - has_m_root); |
|
|
|
|
|
|
|
fe25519_neg(negx, h->X); |
|
|
|
fe25519_cmov(h->X, negx, fe25519_isnegative(h->X) ^ (s[31] >> 7)); |
|
|
|
fe25519_mul(h->T, h->X, h->Y); |
|
|
|
|
|
|
|
return (has_m_root | has_p_root) - 1; |
|
|
|
} |
|
|
@ -269,44 +269,44 @@ ge_frombytes(ge_p3 *h, const unsigned char *s) |
|
|
|
int |
|
|
|
ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) |
|
|
|
{ |
|
|
|
fe u; |
|
|
|
fe v; |
|
|
|
fe v3; |
|
|
|
fe vxx; |
|
|
|
fe m_root_check, p_root_check; |
|
|
|
|
|
|
|
fe_frombytes(h->Y, s); |
|
|
|
fe_1(h->Z); |
|
|
|
fe_sq(u, h->Y); |
|
|
|
fe_mul(v, u, d); |
|
|
|
fe_sub(u, u, h->Z); /* u = y^2-1 */ |
|
|
|
fe_add(v, v, h->Z); /* v = dy^2+1 */ |
|
|
|
|
|
|
|
fe_sq(v3, v); |
|
|
|
fe_mul(v3, v3, v); /* v3 = v^3 */ |
|
|
|
fe_sq(h->X, v3); |
|
|
|
fe_mul(h->X, h->X, v); |
|
|
|
fe_mul(h->X, h->X, u); /* x = uv^7 */ |
|
|
|
|
|
|
|
fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ |
|
|
|
fe_mul(h->X, h->X, v3); |
|
|
|
fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ |
|
|
|
|
|
|
|
fe_sq(vxx, h->X); |
|
|
|
fe_mul(vxx, vxx, v); |
|
|
|
fe_sub(m_root_check, vxx, u); /* vx^2-u */ |
|
|
|
if (fe_iszero(m_root_check) == 0) { |
|
|
|
fe_add(p_root_check, vxx, u); /* vx^2+u */ |
|
|
|
if (fe_iszero(p_root_check) == 0) { |
|
|
|
fe25519 u; |
|
|
|
fe25519 v; |
|
|
|
fe25519 v3; |
|
|
|
fe25519 vxx; |
|
|
|
fe25519 m_root_check, p_root_check; |
|
|
|
|
|
|
|
fe25519_frombytes(h->Y, s); |
|
|
|
fe25519_1(h->Z); |
|
|
|
fe25519_sq(u, h->Y); |
|
|
|
fe25519_mul(v, u, d); |
|
|
|
fe25519_sub(u, u, h->Z); /* u = y^2-1 */ |
|
|
|
fe25519_add(v, v, h->Z); /* v = dy^2+1 */ |
|
|
|
|
|
|
|
fe25519_sq(v3, v); |
|
|
|
fe25519_mul(v3, v3, v); /* v3 = v^3 */ |
|
|
|
fe25519_sq(h->X, v3); |
|
|
|
fe25519_mul(h->X, h->X, v); |
|
|
|
fe25519_mul(h->X, h->X, u); /* x = uv^7 */ |
|
|
|
|
|
|
|
fe25519_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ |
|
|
|
fe25519_mul(h->X, h->X, v3); |
|
|
|
fe25519_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ |
|
|
|
|
|
|
|
fe25519_sq(vxx, h->X); |
|
|
|
fe25519_mul(vxx, vxx, v); |
|
|
|
fe25519_sub(m_root_check, vxx, u); /* vx^2-u */ |
|
|
|
if (fe25519_iszero(m_root_check) == 0) { |
|
|
|
fe25519_add(p_root_check, vxx, u); /* vx^2+u */ |
|
|
|
if (fe25519_iszero(p_root_check) == 0) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
fe_mul(h->X, h->X, sqrtm1); |
|
|
|
fe25519_mul(h->X, h->X, sqrtm1); |
|
|
|
} |
|
|
|
|
|
|
|
if (fe_isnegative(h->X) == (s[31] >> 7)) { |
|
|
|
fe_neg(h->X, h->X); |
|
|
|
if (fe25519_isnegative(h->X) == (s[31] >> 7)) { |
|
|
|
fe25519_neg(h->X, h->X); |
|
|
|
} |
|
|
|
fe_mul(h->T, h->X, h->Y); |
|
|
|
fe25519_mul(h->T, h->X, h->Y); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
@ -318,18 +318,18 @@ ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) |
|
|
|
static void |
|
|
|
ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) |
|
|
|
{ |
|
|
|
fe t0; |
|
|
|
|
|
|
|
fe_add(r->X, p->Y, p->X); |
|
|
|
fe_sub(r->Y, p->Y, p->X); |
|
|
|
fe_mul(r->Z, r->X, q->yplusx); |
|
|
|
fe_mul(r->Y, r->Y, q->yminusx); |
|
|
|
fe_mul(r->T, q->xy2d, p->T); |
|
|
|
fe_add(t0, p->Z, p->Z); |
|
|
|
fe_sub(r->X, r->Z, r->Y); |
|
|
|
fe_add(r->Y, r->Z, r->Y); |
|
|
|
fe_add(r->Z, t0, r->T); |
|
|
|
fe_sub(r->T, t0, r->T); |
|
|
|
fe25519 t0; |
|
|
|
|
|
|
|
fe25519_add(r->X, p->Y, p->X); |
|
|
|
fe25519_sub(r->Y, p->Y, p->X); |
|
|
|
fe25519_mul(r->Z, r->X, q->yplusx); |
|
|
|
fe25519_mul(r->Y, r->Y, q->yminusx); |
|
|
|
fe25519_mul(r->T, q->xy2d, p->T); |
|
|
|
fe25519_add(t0, p->Z, p->Z); |
|
|
|
fe25519_sub(r->X, r->Z, r->Y); |
|
|
|
fe25519_add(r->Y, r->Z, r->Y); |
|
|
|
fe25519_add(r->Z, t0, r->T); |
|
|
|
fe25519_sub(r->T, t0, r->T); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
@ -339,18 +339,18 @@ ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) |
|
|
|
static void |
|
|
|
ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) |
|
|
|
{ |
|
|
|
fe t0; |
|
|
|
|
|
|
|
fe_add(r->X, p->Y, p->X); |
|
|
|
fe_sub(r->Y, p->Y, p->X); |
|
|
|
fe_mul(r->Z, r->X, q->yminusx); |
|
|
|
fe_mul(r->Y, r->Y, q->yplusx); |
|
|
|
fe_mul(r->T, q->xy2d, p->T); |
|
|
|
fe_add(t0, p->Z, p->Z); |
|
|
|
fe_sub(r->X, r->Z, r->Y); |
|
|
|
fe_add(r->Y, r->Z, r->Y); |
|
|
|
fe_sub(r->Z, t0, r->T); |
|
|
|
fe_add(r->T, t0, r->T); |
|
|
|
fe25519 t0; |
|
|
|
|
|
|
|
fe25519_add(r->X, p->Y, p->X); |
|
|
|
fe25519_sub(r->Y, p->Y, p->X); |
|
|
|
fe25519_mul(r->Z, r->X, q->yminusx); |
|
|
|
fe25519_mul(r->Y, r->Y, q->yplusx); |
|
|
|
fe25519_mul(r->T, q->xy2d, p->T); |
|
|
|
fe25519_add(t0, p->Z, p->Z); |
|
|
|
fe25519_sub(r->X, r->Z, r->Y); |
|
|
|
fe25519_add(r->Y, r->Z, r->Y); |
|
|
|
fe25519_sub(r->Z, t0, r->T); |
|
|
|
fe25519_add(r->T, t0, r->T); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
@ -360,9 +360,9 @@ ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) |
|
|
|
void |
|
|
|
ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) |
|
|
|
{ |
|
|
|
fe_mul(r->X, p->X, p->T); |
|
|
|
fe_mul(r->Y, p->Y, p->Z); |
|
|
|
fe_mul(r->Z, p->Z, p->T); |
|
|
|
fe25519_mul(r->X, p->X, p->T); |
|
|
|
fe25519_mul(r->Y, p->Y, p->Z); |
|
|
|
fe25519_mul(r->Z, p->Z, p->T); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
@ -372,18 +372,18 @@ ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) |
|
|
|
static void |
|
|
|
ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) |
|
|
|
{ |
|
|
|
fe_mul(r->X, p->X, p->T); |
|
|
|
fe_mul(r->Y, p->Y, p->Z); |
|
|
|
fe_mul(r->Z, p->Z, p->T); |
|
|
|
fe_mul(r->T, p->X, p->Y); |
|
|
|
fe25519_mul(r->X, p->X, p->T); |
|
|
|
fe25519_mul(r->Y, p->Y, p->Z); |
|
|
|
fe25519_mul(r->Z, p->Z, p->T); |
|
|
|
fe25519_mul(r->T, p->X, p->Y); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
ge_p2_0(ge_p2 *h) |
|
|
|
{ |
|
|
|
fe_0(h->X); |
|
|
|
fe_1(h->Y); |
|
|
|
fe_1(h->Z); |
|
|
|
fe25519_0(h->X); |
|
|
|
fe25519_1(h->Y); |
|
|
|
fe25519_1(h->Z); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
@ -393,26 +393,26 @@ ge_p2_0(ge_p2 *h) |
|
|
|
static void |
|
|
|
ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) |
|
|
|
{ |
|
|
|
fe t0; |
|
|
|
|
|
|
|
fe_sq(r->X, p->X); |
|
|
|
fe_sq(r->Z, p->Y); |
|
|
|
fe_sq2(r->T, p->Z); |
|
|
|
fe_add(r->Y, p->X, p->Y); |
|
|
|
fe_sq(t0, r->Y); |
|
|
|
fe_add(r->Y, r->Z, r->X); |
|
|
|
fe_sub(r->Z, r->Z, r->X); |
|
|
|
fe_sub(r->X, t0, r->Y); |
|
|
|
fe_sub(r->T, r->T, r->Z); |
|
|
|
fe25519 t0; |
|
|
|
|
|
|
|
fe25519_sq(r->X, p->X); |
|
|
|
fe25519_sq(r->Z, p->Y); |
|
|
|
fe25519_sq2(r->T, p->Z); |
|
|
|
fe25519_add(r->Y, p->X, p->Y); |
|
|
|
fe25519_sq(t0, r->Y); |
|
|
|
fe25519_add(r->Y, r->Z, r->X); |
|
|
|
fe25519_sub(r->Z, r->Z, r->X); |
|
|
|
fe25519_sub(r->X, t0, r->Y); |
|
|
|
fe25519_sub(r->T, r->T, r->Z); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
ge_p3_0(ge_p3 *h) |
|
|
|
{ |
|
|
|
fe_0(h->X); |
|
|
|
fe_1(h->Y); |
|
|
|
fe_1(h->Z); |
|
|
|
fe_0(h->T); |
|
|
|
fe25519_0(h->X); |
|
|
|
fe25519_1(h->Y); |
|
|
|
fe25519_1(h->Z); |
|
|
|
fe25519_0(h->T); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
@ -422,27 +422,27 @@ ge_p3_0(ge_p3 *h) |
|
|
|
void |
|
|
|
ge_p3_to_cached(ge_cached *r, const ge_p3 *p) |
|
|
|
{ |
|
|
|
fe_add(r->YplusX, p->Y, p->X); |
|
|
|
fe_sub(r->YminusX, p->Y, p->X); |
|
|
|
fe_copy(r->Z, p->Z); |
|
|
|
fe_mul(r->T2d, p->T, d2); |
|
|
|
fe25519_add(r->YplusX, p->Y, p->X); |
|
|
|
fe25519_sub(r->YminusX, p->Y, p->X); |
|
|
|
fe25519_copy(r->Z, p->Z); |
|
|
|
fe25519_mul(r->T2d, p->T, d2); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
ge_p3_to_precomp(ge_precomp *pi, const ge_p3 *p) |
|
|
|
{ |
|
|
|
fe recip; |
|
|
|
fe x; |
|
|
|
fe y; |
|
|
|
fe xy; |
|
|
|
|
|
|
|
fe_invert(recip, p->Z); |
|
|
|
fe_mul(x, p->X, recip); |
|
|
|
fe_mul(y, p->Y, recip); |
|
|
|
fe_add(pi->yplusx, y, x); |
|
|
|
fe_sub(pi->yminusx, y, x); |
|
|
|
fe_mul(xy, x, y); |
|
|
|
fe_mul(pi->xy2d, xy, d2); |
|
|
|
fe25519 recip; |
|
|
|
fe25519 x; |
|
|
|
fe25519 y; |
|
|
|
fe25519 xy; |
|
|
|
|
|
|
|
fe25519_invert(recip, p->Z); |
|
|
|
fe25519_mul(x, p->X, recip); |
|
|
|
fe25519_mul(y, p->Y, recip); |
|
|
|
fe25519_add(pi->yplusx, y, x); |
|
|
|
fe25519_sub(pi->yminusx, y, x); |
|
|
|
fe25519_mul(xy, x, y); |
|
|
|
fe25519_mul(pi->xy2d, xy, d2); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
@ -452,23 +452,23 @@ ge_p3_to_precomp(ge_precomp *pi, const ge_p3 *p) |
|
|
|
static void |
|
|
|
ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) |
|
|
|
{ |
|
|
|
fe_copy(r->X, p->X); |
|
|
|
fe_copy(r->Y, p->Y); |
|
|
|
fe_copy(r->Z, p->Z); |
|
|
|
fe25519_copy(r->X, p->X); |
|
|
|
fe25519_copy(r->Y, p->Y); |
|
|
|
fe25519_copy(r->Z, p->Z); |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
ge_p3_tobytes(unsigned char *s, const ge_p3 *h) |
|
|
|
{ |
|
|
|
fe recip; |
|
|
|
fe x; |
|
|
|
fe y; |
|
|
|
|
|
|
|
fe_invert(recip, h->Z); |
|
|
|
fe_mul(x, h->X, recip); |
|
|
|
fe_mul(y, h->Y, recip); |
|
|
|
fe_tobytes(s, y); |
|
|
|
s[31] ^= fe_isnegative(x) << 7; |
|
|
|
fe25519 recip; |
|
|
|
fe25519 x; |
|
|
|
fe25519 y; |
|
|
|
|
|
|
|
fe25519_invert(recip, h->Z); |
|
|
|
fe25519_mul(x, h->X, recip); |
|
|
|
fe25519_mul(y, h->Y, recip); |
|
|
|
fe25519_tobytes(s, y); |
|
|
|
s[31] ^= fe25519_isnegative(x) << 7; |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
@ -486,9 +486,9 @@ ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) |
|
|
|
static void |
|
|
|
ge_precomp_0(ge_precomp *h) |
|
|
|
{ |
|
|
|
fe_1(h->yplusx); |
|
|
|
fe_1(h->yminusx); |
|
|
|
fe_0(h->xy2d); |
|
|
|
fe25519_1(h->yplusx); |
|
|
|
fe25519_1(h->yminusx); |
|
|
|
fe25519_0(h->xy2d); |
|
|
|
} |
|
|
|
|
|
|
|
static unsigned char |
|
|
@ -519,9 +519,9 @@ negative(signed char b) |
|
|
|
static void |
|
|
|
ge_cmov(ge_precomp *t, const ge_precomp *u, unsigned char b) |
|
|
|
{ |
|
|
|
fe_cmov(t->yplusx, u->yplusx, b); |
|
|
|
fe_cmov(t->yminusx, u->yminusx, b); |
|
|
|
fe_cmov(t->xy2d, u->xy2d, b); |
|
|
|
fe25519_cmov(t->yplusx, u->yplusx, b); |
|
|
|
fe25519_cmov(t->yminusx, u->yminusx, b); |
|
|
|
fe25519_cmov(t->xy2d, u->xy2d, b); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
@ -540,9 +540,9 @@ ge_select(ge_precomp *t, const ge_precomp precomp[8], const signed char b) |
|
|
|
ge_cmov(t, &precomp[5], equal(babs, 6)); |
|
|
|
ge_cmov(t, &precomp[6], equal(babs, 7)); |
|
|
|
ge_cmov(t, &precomp[7], equal(babs, 8)); |
|
|
|
fe_copy(minust.yplusx, t->yminusx); |
|
|
|
fe_copy(minust.yminusx, t->yplusx); |
|
|
|
fe_neg(minust.xy2d, t->xy2d); |
|
|
|
fe25519_copy(minust.yplusx, t->yminusx); |
|
|
|
fe25519_copy(minust.yminusx, t->yplusx); |
|
|
|
fe25519_neg(minust.xy2d, t->xy2d); |
|
|
|
ge_cmov(t, &minust, bnegative); |
|
|
|
} |
|
|
|
|
|
|
@ -566,33 +566,33 @@ ge_select_base(ge_precomp *t, const int pos, const signed char b) |
|
|
|
static void |
|
|
|
ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) |
|
|
|
{ |
|
|
|
fe t0; |
|
|
|
|
|
|
|
fe_add(r->X, p->Y, p->X); |
|
|
|
fe_sub(r->Y, p->Y, p->X); |
|
|
|
fe_mul(r->Z, r->X, q->YminusX); |
|
|
|
fe_mul(r->Y, r->Y, q->YplusX); |
|
|
|
fe_mul(r->T, q->T2d, p->T); |
|
|
|
fe_mul(r->X, p->Z, q->Z); |
|
|
|
fe_add(t0, r->X, r->X); |
|
|
|
fe_sub(r->X, r->Z, r->Y); |
|
|
|
fe_add(r->Y, r->Z, r->Y); |
|
|
|
fe_sub(r->Z, t0, r->T); |
|
|
|
fe_add(r->T, t0, r->T); |
|
|
|
fe25519 t0; |
|
|
|
|
|
|
|
fe25519_add(r->X, p->Y, p->X); |
|
|
|
fe25519_sub(r->Y, p->Y, p->X); |
|
|
|
fe25519_mul(r->Z, r->X, q->YminusX); |
|
|
|
fe25519_mul(r->Y, r->Y, q->YplusX); |
|
|
|
fe25519_mul(r->T, q->T2d, p->T); |
|
|
|
fe25519_mul(r->X, p->Z, q->Z); |
|
|
|
fe25519_add(t0, r->X, r->X); |
|
|
|
fe25519_sub(r->X, r->Z, r->Y); |
|
|
|
fe25519_add(r->Y, r->Z, r->Y); |
|
|
|
fe25519_sub(r->Z, t0, r->T); |
|
|
|
fe25519_add(r->T, t0, r->T); |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
ge_tobytes(unsigned char *s, const ge_p2 *h) |
|
|
|
{ |
|
|
|
fe recip; |
|
|
|
fe x; |
|
|
|
fe y; |
|
|
|
|
|
|
|
fe_invert(recip, h->Z); |
|
|
|
fe_mul(x, h->X, recip); |
|
|
|
fe_mul(y, h->Y, recip); |
|
|
|
fe_tobytes(s, y); |
|
|
|
s[31] ^= fe_isnegative(x) << 7; |
|
|
|
fe25519 recip; |
|
|
|
fe25519 x; |
|
|
|
fe25519 y; |
|
|
|
|
|
|
|
fe25519_invert(recip, h->Z); |
|
|
|
fe25519_mul(x, h->X, recip); |
|
|
|
fe25519_mul(y, h->Y, recip); |
|
|
|
fe25519_tobytes(s, y); |
|
|
|
s[31] ^= fe25519_isnegative(x) << 7; |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
@ -893,26 +893,26 @@ ge_mul_l(ge_p3 *r, const ge_p3 *A) |
|
|
|
int |
|
|
|
ge_is_on_curve(const ge_p3 *p) |
|
|
|
{ |
|
|
|
fe x2; |
|
|
|
fe y2; |
|
|
|
fe z2; |
|
|
|
fe z4; |
|
|
|
fe t0; |
|
|
|
fe t1; |
|
|
|
|
|
|
|
fe_sq(x2, p->X); |
|
|
|
fe_sq(y2, p->Y); |
|
|
|
fe_sq(z2, p->Z); |
|
|
|
fe_sub(t0, y2, x2); |
|
|
|
fe_mul(t0, t0, z2); |
|
|
|
|
|
|
|
fe_mul(t1, x2, y2); |
|
|
|
fe_mul(t1, t1, d); |
|
|
|
fe_sq(z4, z2); |
|
|
|
fe_add(t1, t1, z4); |
|
|
|
fe_sub(t0, t0, t1); |
|
|
|
|
|
|
|
return fe_iszero(t0); |
|
|
|
fe25519 x2; |
|
|
|
fe25519 y2; |
|
|
|
fe25519 z2; |
|
|
|
fe25519 z4; |
|
|
|
fe25519 t0; |
|
|
|
fe25519 t1; |
|
|
|
|
|
|
|
fe25519_sq(x2, p->X); |
|
|
|
fe25519_sq(y2, p->Y); |
|
|
|
fe25519_sq(z2, p->Z); |
|
|
|
fe25519_sub(t0, y2, x2); |
|
|
|
fe25519_mul(t0, t0, z2); |
|
|
|
|
|
|
|
fe25519_mul(t1, x2, y2); |
|
|
|
fe25519_mul(t1, t1, d); |
|
|
|
fe25519_sq(z4, z2); |
|
|
|
fe25519_add(t1, t1, z4); |
|
|
|
fe25519_sub(t0, t0, t1); |
|
|
|
|
|
|
|
return fe25519_iszero(t0); |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
@ -922,7 +922,7 @@ ge_is_on_main_subgroup(const ge_p3 *p) |
|
|
|
|
|
|
|
ge_mul_l(&pl, p); |
|
|
|
|
|
|
|
return fe_iszero(pl.X); |
|
|
|
return fe25519_iszero(pl.X); |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|