tunsafe-clang15/installer/signplugin/tiny/morph25519.c
2018-08-08 13:53:31 +02:00

88 lines
1.9 KiB
C

/* Montgomery <-> Edwards isomorphism
* Daniel Beer <dlbeer@gmail.com>, 18 Jan 2014
*
* This file is in the public domain.
*/
#include "morph25519.h"
#include "f25519.h"
void morph25519_e2m(uint8_t *montgomery, const uint8_t *y)
{
uint8_t yplus[F25519_SIZE];
uint8_t yminus[F25519_SIZE];
f25519_sub(yplus, f25519_one, y);
f25519_inv__distinct(yminus, yplus);
f25519_add(yplus, f25519_one, y);
f25519_mul__distinct(montgomery, yplus, yminus);
f25519_normalize(montgomery);
}
static void mx2ey(uint8_t *ey, const uint8_t *mx)
{
uint8_t n[F25519_SIZE];
uint8_t d[F25519_SIZE];
f25519_add(n, mx, f25519_one);
f25519_inv__distinct(d, n);
f25519_sub(n, mx, f25519_one);
f25519_mul__distinct(ey, n, d);
}
static uint8_t ey2ex(uint8_t *x, const uint8_t *y, int parity)
{
static const uint8_t d[F25519_SIZE] = {
0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52
};
uint8_t a[F25519_SIZE];
uint8_t b[F25519_SIZE];
uint8_t c[F25519_SIZE];
/* Compute c = y^2 */
f25519_mul__distinct(c, y, y);
/* Compute b = (1+dy^2)^-1 */
f25519_mul__distinct(b, c, d);
f25519_add(a, b, f25519_one);
f25519_inv__distinct(b, a);
/* Compute a = y^2-1 */
f25519_sub(a, c, f25519_one);
/* Compute c = a*b = (y^2+1)/(1-dy^2) */
f25519_mul__distinct(c, a, b);
/* Compute a, b = +/-sqrt(c), if c is square */
f25519_sqrt(a, c);
f25519_neg(b, a);
/* Select one of them, based on the parity bit */
f25519_select(x, a, b, (a[0] ^ parity) & 1);
/* Verify that x^2 = c */
f25519_mul__distinct(a, x, x);
f25519_normalize(a);
f25519_normalize(c);
return f25519_eq(a, c);
}
uint8_t morph25519_m2e(uint8_t *ex, uint8_t *ey,
const uint8_t *mx, int parity)
{
uint8_t ok;
mx2ey(ey, mx);
ok = ey2ex(ex, ey, parity);
f25519_normalize(ex);
f25519_normalize(ey);
return ok;
}