1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 07:28:10 +00:00

upgrade ed25519 to forthy42 fork

This commit is contained in:
Pavol Rusnak 2017-03-28 18:01:42 +02:00
parent 87c920a7e7
commit cb471ba2ec
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
10 changed files with 346 additions and 89 deletions

View File

@ -21,6 +21,7 @@ CFLAGS += $(OPTFLAGS) \
-Winit-self \
-Wuninitialized \
-Wformat-security \
-Wno-unused-function \
-Werror
# disable sequence point warning because of AES code

View File

@ -403,8 +403,8 @@ static void
curve25519_expand(bignum25519 out, const unsigned char in[32]) {
static const union { uint8_t b[2]; uint16_t s; } endian_check = {{1,0}};
uint32_t x0,x1,x2,x3,x4,x5,x6,x7;
if (endian_check.s == 1) {
/* Take care, this only works when in is aligned */
x0 = *(uint32_t *)(in + 0);
x1 = *(uint32_t *)(in + 4);
x2 = *(uint32_t *)(in + 8);

View File

@ -1,4 +1,4 @@
static const ge25519 ALIGN(16) ge25519_basepoint = {
const ge25519 ALIGN(16) ge25519_basepoint = {
{0x0325d51a,0x018b5823,0x00f6592a,0x0104a92d,0x01a4b31d,0x01d6dc5c,0x027118fe,0x007fd814,0x013cd6e5,0x0085a4db},
{0x02666658,0x01999999,0x00cccccc,0x01333333,0x01999999,0x00666666,0x03333333,0x00cccccc,0x02666666,0x01999999},
{0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000},
@ -9,11 +9,11 @@ static const ge25519 ALIGN(16) ge25519_basepoint = {
d
*/
static const bignum25519 ALIGN(16) ge25519_ecd = {
const bignum25519 ALIGN(16) ge25519_ecd = {
0x035978a3,0x00d37284,0x03156ebd,0x006a0a0e,0x0001c029,0x0179e898,0x03a03cbb,0x01ce7198,0x02e2b6ff,0x01480db3
};
static const bignum25519 ALIGN(16) ge25519_ec2d = {
const bignum25519 ALIGN(16) ge25519_ec2d = {
0x02b2f159,0x01a6e509,0x022add7a,0x00d4141d,0x00038052,0x00f3d130,0x03407977,0x019ce331,0x01c56dff,0x00901b67
};
@ -21,11 +21,11 @@ static const bignum25519 ALIGN(16) ge25519_ec2d = {
sqrt(-1)
*/
static const bignum25519 ALIGN(16) ge25519_sqrtneg1 = {
const bignum25519 ALIGN(16) ge25519_sqrtneg1 = {
0x020ea0b0,0x0186c9d2,0x008f189d,0x0035697f,0x00bd0c60,0x01fbd7a7,0x02804c9e,0x01e16569,0x0004fc1d,0x00ae0c92
};
static const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32] = {
const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32] = {
{{0x0340913e,0x000e4175,0x03d673a2,0x002e8a05,0x03f4e67c,0x008f8a09,0x00c21a34,0x004cf4b8,0x01298f81,0x0113f4be},{0x018c3b85,0x0124f1bd,0x01c325f7,0x0037dc60,0x033e4cb7,0x003d42c2,0x01a44c32,0x014ca4e1,0x03a33d4b,0x001f3e74},{0x037aaa68,0x00448161,0x0093d579,0x011e6556,0x009b67a0,0x0143598c,0x01bee5ee,0x00b50b43,0x0289f0c6,0x01bc45ed}},
{{0x00fcd265,0x0047fa29,0x034faacc,0x01ef2e0d,0x00ef4d4f,0x014bd6bd,0x00f98d10,0x014c5026,0x007555bd,0x00aae456},{0x00ee9730,0x016c2a13,0x017155e4,0x01874432,0x00096a10,0x01016732,0x01a8014f,0x011e9823,0x01b9a80f,0x01e85938},{0x01d0d889,0x01a4cfc3,0x034c4295,0x0110e1ae,0x0162508c,0x00f2db4c,0x0072a2c6,0x0098da2e,0x02f12b9b,0x0168a09a}},
{{0x0047d6ba,0x0060b0e9,0x0136eff2,0x008a5939,0x03540053,0x0064a087,0x02788e5c,0x00be7c67,0x033eb1b5,0x005529f9},{0x00a5bb33,0x00af1102,0x01a05442,0x001e3af7,0x02354123,0x00bfec44,0x01f5862d,0x00dd7ba3,0x03146e20,0x00a51733},{0x012a8285,0x00f6fc60,0x023f9797,0x003e85ee,0x009c3820,0x01bda72d,0x01b3858d,0x00d35683,0x0296b3bb,0x010eaaf9}},

View File

@ -1,23 +1,23 @@
static const ge25519 ge25519_basepoint = {
const ge25519 ge25519_basepoint = {
{0x00062d608f25d51a,0x000412a4b4f6592a,0x00075b7171a4b31d,0x0001ff60527118fe,0x000216936d3cd6e5},
{0x0006666666666658,0x0004cccccccccccc,0x0001999999999999,0x0003333333333333,0x0006666666666666},
{0x0000000000000001,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000},
{0x00068ab3a5b7dda3,0x00000eea2a5eadbb,0x0002af8df483c27e,0x000332b375274732,0x00067875f0fd78b7}
};
static const bignum25519 ge25519_ecd = {
const bignum25519 ge25519_ecd = {
0x00034dca135978a3,0x0001a8283b156ebd,0x0005e7a26001c029,0x000739c663a03cbb,0x00052036cee2b6ff
};
static const bignum25519 ge25519_ec2d = {
const bignum25519 ge25519_ec2d = {
0x00069b9426b2f159,0x00035050762add7a,0x0003cf44c0038052,0x0006738cc7407977,0x0002406d9dc56dff
};
static const bignum25519 ge25519_sqrtneg1 = {
const bignum25519 ge25519_sqrtneg1 = {
0x00061b274a0ea0b0,0x0000d5a5fc8f189d,0x0007ef5e9cbd0c60,0x00078595a6804c9e,0x0002b8324804fc1d
};
static const ge25519_niels ge25519_niels_sliding_multiples[32] = {
const ge25519_niels ge25519_niels_sliding_multiples[32] = {
{{0x00003905d740913e,0x0000ba2817d673a2,0x00023e2827f4e67c,0x000133d2e0c21a34,0x00044fd2f9298f81},{0x000493c6f58c3b85,0x0000df7181c325f7,0x0000f50b0b3e4cb7,0x0005329385a44c32,0x00007cf9d3a33d4b},{0x00011205877aaa68,0x000479955893d579,0x00050d66309b67a0,0x0002d42d0dbee5ee,0x0006f117b689f0c6}},
{{0x00011fe8a4fcd265,0x0007bcb8374faacc,0x00052f5af4ef4d4f,0x0005314098f98d10,0x0002ab91587555bd},{0x0005b0a84cee9730,0x00061d10c97155e4,0x0004059cc8096a10,0x00047a608da8014f,0x0007a164e1b9a80f},{0x0006933f0dd0d889,0x00044386bb4c4295,0x0003cb6d3162508c,0x00026368b872a2c6,0x0005a2826af12b9b}},
{{0x000182c3a447d6ba,0x00022964e536eff2,0x000192821f540053,0x0002f9f19e788e5c,0x000154a7e73eb1b5},{0x0002bc4408a5bb33,0x000078ebdda05442,0x0002ffb112354123,0x000375ee8df5862d,0x0002945ccf146e20},{0x0003dbf1812a8285,0x0000fa17ba3f9797,0x0006f69cb49c3820,0x00034d5a0db3858d,0x00043aabe696b3bb}},

View File

@ -176,7 +176,7 @@ ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q)
pack & unpack
*/
static void
STATIC void
ge25519_pack(unsigned char r[32], const ge25519 *p) {
bignum25519 tx, ty, zi;
unsigned char parity[32];
@ -188,8 +188,7 @@ ge25519_pack(unsigned char r[32], const ge25519 *p) {
r[31] ^= ((parity[0] & 1) << 7);
}
static int
ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) {
STATIC int ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) {
static const unsigned char zero[32] = {0};
static const bignum25519 one = {1};
unsigned char parity = p[31] >> 7;
@ -243,14 +242,20 @@ ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) {
scalarmults
*/
DONNA_INLINE static void ge25519_set_neutral(ge25519 *r)
{
memset(r, 0, sizeof(ge25519));
r->y[0] = 1;
r->z[0] = 1;
}
#define S1_SWINDOWSIZE 5
#define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2))
#define S2_SWINDOWSIZE 7
#define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2))
/* computes [s1]p1 + [s2]basepoint */
static void
ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) {
/* computes [s1]p1 + [s2]base */
STATIC void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) {
signed char slide1[256], slide2[256];
ge25519_pniels pre1[S1_TABLE_SIZE];
ge25519 d1;
@ -265,10 +270,7 @@ ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256
for (i = 0; i < S1_TABLE_SIZE - 1; i++)
ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]);
/* set neutral */
memset(r, 0, sizeof(ge25519));
r->y[0] = 1;
r->z[0] = 1;
ge25519_set_neutral(r);
i = 255;
while ((i >= 0) && !(slide1[i] | slide2[i]))
@ -291,11 +293,156 @@ ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256
}
}
/* computes [s1]p1 */
STATIC void ge25519_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1) {
signed char slide1[256];
ge25519_pniels pre1[S1_TABLE_SIZE];
ge25519 d1;
ge25519_p1p1 t;
int32_t i;
contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE);
ge25519_double(&d1, p1);
ge25519_full_to_pniels(pre1, p1);
for (i = 0; i < S1_TABLE_SIZE - 1; i++)
ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]);
/* set neutral */
ge25519_set_neutral(r);
i = 255;
while ((i >= 0) && !slide1[i])
i--;
for (; i >= 0; i--) {
ge25519_double_p1p1(&t, r);
if (slide1[i]) {
ge25519_p1p1_to_full(r, &t);
ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7);
}
ge25519_p1p1_to_partial(r, &t);
}
}
/*
* The following conditional move stuff uses conditional moves.
* I will check on which compilers this works, and provide suitable
* workarounds for those where it doesn't.
*
* This works on gcc 4.x and above with -O3. Don't use -O2, this will
* cause the code to not generate conditional moves. Don't use any -march=
* with less than i686 on x86
*/
DONNA_INLINE static void ge25519_cmove_stride4(long * r, long * p, long * pos, long * n, int stride) {
long x0=r[0], x1=r[1], x2=r[2], x3=r[3], y0, y1, y2, y3;
for(; p<n; p+=stride) {
int flag=(p==pos);
y0 = p[0];
y1 = p[1];
y2 = p[2];
y3 = p[3];
x0 = flag ? y0 : x0;
x1 = flag ? y1 : x1;
x2 = flag ? y2 : x2;
x3 = flag ? y3 : x3;
}
r[0] = x0;
r[1] = x1;
r[2] = x2;
r[3] = x3;
}
#define HAS_CMOVE_STRIDE4
DONNA_INLINE static void ge25519_cmove_stride4b(long * r, long * p, long * pos, long * n, int stride) {
long x0=p[0], x1=p[1], x2=p[2], x3=p[3], y0, y1, y2, y3;
for(p+=stride; p<n; p+=stride) {
int flag=(p==pos);
y0 = p[0];
y1 = p[1];
y2 = p[2];
y3 = p[3];
x0 = flag ? y0 : x0;
x1 = flag ? y1 : x1;
x2 = flag ? y2 : x2;
x3 = flag ? y3 : x3;
}
r[0] = x0;
r[1] = x1;
r[2] = x2;
r[3] = x3;
}
#define HAS_CMOVE_STRIDE4B
STATIC void ge25519_move_conditional_pniels_array(ge25519_pniels * r, const ge25519_pniels * p, int pos, int n) {
#ifdef HAS_CMOVE_STRIDE4B
size_t i;
for(i=0; i<sizeof(ge25519_pniels)/sizeof(long); i+=4) {
ge25519_cmove_stride4b(((long*)r)+i,
((long*)p)+i,
((long*)(p+pos))+i,
((long*)(p+n))+i,
sizeof(ge25519_pniels)/sizeof(long));
}
#else
size_t i;
for(i=0; i<n; i++) {
ge25519_move_conditional_pniels(r, p+i, pos==i);
}
#endif
}
STATIC void ge25519_move_conditional_niels_array(ge25519_niels * r, const uint8_t p[8][96], int pos, int n) {
size_t i;
for(i=0; i<96/sizeof(long); i+=4) {
ge25519_cmove_stride4(((long*)r)+i,
((long*)p)+i,
((long*)(p+pos))+i,
((long*)(p+n))+i,
96/sizeof(long));
}
}
/* computes [s1]p1, constant time */
STATIC void ge25519_scalarmult(ge25519 *r, const ge25519 *p1, const bignum256modm s1) {
signed char slide1[64];
ge25519_pniels pre1[9];
ge25519_pniels pre;
ge25519 d1;
ge25519_p1p1 t;
int32_t i;
contract256_window4_modm(slide1, s1);
/* set neutral */
ge25519_set_neutral(r);
ge25519_full_to_pniels(pre1, r);
ge25519_full_to_pniels(pre1+1, p1);
ge25519_double(&d1, p1);
ge25519_full_to_pniels(pre1+2, &d1);
for (i = 1; i < 7; i++) {
ge25519_pnielsadd(&pre1[i+2], &d1, &pre1[i]);
}
for (i = 63; i >= 0; i--) {
int k=abs(slide1[i]);
ge25519_double_partial(r, r);
ge25519_double_partial(r, r);
ge25519_double_partial(r, r);
ge25519_double_p1p1(&t, r);
ge25519_move_conditional_pniels_array(&pre, pre1, k, 9);
ge25519_p1p1_to_full(r, &t);
ge25519_pnielsadd_p1p1(&t, r, &pre, (unsigned char)slide1[i] >> 7);
ge25519_p1p1_to_partial(r, &t);
}
}
#if !defined(HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS)
static uint32_t
DONNA_INLINE static uint32_t
ge25519_windowb_equal(uint32_t b, uint32_t c) {
return ((b ^ c) - 1) >> 31;
}
@ -306,15 +453,13 @@ ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][
uint32_t sign = (uint32_t)((unsigned char)b >> 7);
uint32_t mask = ~(sign - 1);
uint32_t u = (b + mask) ^ mask;
uint32_t i;
/* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */
uint8_t packed[96] = {0};
packed[0] = 1;
packed[32] = 1;
for (i = 0; i < 8; i++)
curve25519_move_conditional_bytes(packed, table[(pos * 8) + i], ge25519_windowb_equal(u, i + 1));
ge25519_move_conditional_niels_array((ge25519_niels *)packed, &table[pos*8], u-1, 8);
/* expand in to t */
curve25519_expand(t->ysubx, packed + 0);
@ -362,3 +507,7 @@ ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t basepoint_table[256][96]
}
}
STATIC void ge25519_scalarmult_base(ge25519 *r, const bignum256modm s) {
ge25519_scalarmult_base_niels(r, ge25519_niels_base_multiples, s);
}

View File

@ -149,7 +149,7 @@ ge25519_double(ge25519 *r, const ge25519 *p) {
ge25519_p1p1_to_full(r, &t);
}
static void
STATIC void
ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q) {
ge25519_p1p1 ALIGN(16) t;
ge25519_add_p1p1(&t, p, q);
@ -205,7 +205,7 @@ ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q)
pack & unpack
*/
static void
STATIC void
ge25519_pack(unsigned char r[32], const ge25519 *p) {
bignum25519 ALIGN(16) tx, ty, zi;
unsigned char parity[32];
@ -218,7 +218,7 @@ ge25519_pack(unsigned char r[32], const ge25519 *p) {
}
static int
STATIC int
ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) {
static const bignum25519 ALIGN(16) one = {1};
static const unsigned char zero[32] = {0};
@ -275,12 +275,20 @@ ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) {
scalarmults
*/
DONNA_INLINE static void ge25519_set_neutral(ge25519 *r)
{
memset(r, 0, sizeof(ge25519));
r->y[0] = 1;
r->z[0] = 1;
}
#define S1_SWINDOWSIZE 5
#define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2))
#define S2_SWINDOWSIZE 7
#define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2))
static void
/* computes [s1]p1 + [s2]base */
STATIC void
ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) {
signed char slide1[256], slide2[256];
ge25519_pniels ALIGN(16) pre1[S1_TABLE_SIZE];
@ -322,13 +330,131 @@ ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256
}
}
#if !defined(HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS)
#ifndef MM16
# define MM16 __attribute__((aligned(16)))
#endif
static uint32_t
ge25519_windowb_equal(uint32_t b, uint32_t c) {
return ((b ^ c) - 1) >> 31;
STATIC void
ge25519_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1) {
signed char slide1[256];
ge25519_pniels MM16 pre1[S1_TABLE_SIZE];
ge25519 MM16 d1;
ge25519_p1p1 MM16 t;
int32_t i;
contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE);
ge25519_double(&d1, p1);
ge25519_full_to_pniels(pre1, p1);
for (i = 0; i < S1_TABLE_SIZE - 1; i++)
ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]);
/* set neutral */
memset(r, 0, sizeof(ge25519));
r->y[0] = 1;
r->z[0] = 1;
i = 255;
while ((i >= 0) && !slide1[i])
i--;
for (; i >= 0; i--) {
ge25519_double_p1p1(&t, r);
if (slide1[i]) {
ge25519_p1p1_to_full(r, &t);
ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7);
}
ge25519_p1p1_to_partial(r, &t);
}
}
DONNA_INLINE static void ge25519_cmove_stride4(long * r, long * p, long * pos, long * n, int stride) {
int i;
long x0=p[0], x1=p[1], x2=p[2], x3=p[3], y0, y1, y2, y3;
for(p+=stride; p<n; p+=stride) {
y0 = p[0];
y1 = p[1];
y2 = p[2];
y3 = p[3];
x0 = (p==pos) ? y0 : x0;
x1 = (p==pos) ? y1 : x1;
x2 = (p==pos) ? y2 : x2;
x3 = (p==pos) ? y3 : x3;
}
r[0] = x0;
r[1] = x1;
r[2] = x2;
r[3] = x3;
}
#define HAS_CMOVE_STRIDE4
STATIC void ge25519_move_conditional_pniels_array(ge25519_pniels * r, const ge25519_pniels * p, int pos, int n) {
#ifdef HAS_CMOVE_STRIDE4
int i;
for(i=0; i<sizeof(ge25519_pniels)/sizeof(long); i+=4) {
ge25519_cmove_stride4(((long*)r)+i,
((long*)p)+i,
((long*)(p+pos))+i,
((long*)(p+n))+i,
sizeof(ge25519_pniels)/sizeof(long));
}
#else
int i;
for(i=0; i<n; i++) {
ge25519_move_conditional_pniels(r, p+i, pos==i);
}
#endif
}
STATIC void ge25519_move_conditional_niels_array(ge25519_niels * r, const uint8_t p[8][96], int pos, int n) {
int i;
for(i=0; i<96/sizeof(long); i+=4) {
ge25519_cmove_stride4(((long*)r)+i,
((long*)p)+i,
((long*)(p+pos))+i,
((long*)(p+n))+i,
96/sizeof(long));
}
}
/* computes [s1]p1, constant time */
STATIC void ge25519_scalarmult(ge25519 *r, const ge25519 *p1, const bignum256modm s1) {
signed char slide1[64];
ge25519_pniels MM16 pre1[9];
ge25519_pniels MM16 pre;
ge25519 MM16 d1, r1;
ge25519_p1p1 MM16 t;
int32_t i, j;
contract256_window4_modm(slide1, s1);
/* set neutral */
ge25519_set_neutral(r);
ge25519_full_to_pniels(pre1, r);
ge25519_full_to_pniels(pre1+1, p1);
ge25519_double(&d1, p1);
ge25519_full_to_pniels(pre1+2, &d1);
for (i = 0; i < 7; i++) {
ge25519_pnielsadd(&pre1[i+2], &d1, &pre1[i]);
}
for (i = 63; i >= 0; i--) {
int k=abs(slide1[i]);
ge25519_double_partial(r, r);
ge25519_double_partial(r, r);
ge25519_double_partial(r, r);
ge25519_double_p1p1(&t, r);
ge25519_move_conditional_pniels_array(&pre, pre1, k, 9);
ge25519_p1p1_to_full(r, &t);
ge25519_pnielsadd_p1p1(&t, r, &pre, (unsigned char)slide1[i] >> 7);
ge25519_p1p1_to_partial(r, &t);
}
}
#if !defined(HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS)
static void
ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) {
bignum25519 ALIGN(16) neg;
@ -342,8 +468,7 @@ ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][
packed[0] = 1;
packed[32] = 1;
for (i = 0; i < 8; i++)
curve25519_move_conditional_bytes(packed, table[(pos * 8) + i], ge25519_windowb_equal(u, i + 1));
ge25519_move_conditional_niels_array(packed, &table[pos*8], u-1, 8);
/* expand in to t */
curve25519_expand(t->ysubx, packed + 0);
@ -355,10 +480,9 @@ ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][
curve25519_neg(neg, t->t2d);
curve25519_swap_conditional(t->t2d, neg, sign);
}
#endif /* HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS */
static void
STATIC void
ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t table[256][96], const bignum256modm s) {
signed char b[64];
uint32_t i;
@ -388,3 +512,8 @@ ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t table[256][96], const bi
ge25519_nielsadd2(r, &t);
}
}
STATIC void ge25519_scalarmult_base(ge25519 *r, const bignum256modm s) {
ge25519_scalarmult_base_niels(r, ge25519_niels_base_multiples, s);
}

View File

@ -49,6 +49,9 @@
#define CPU_X86_64
#elif defined(__i586__) || defined(__i686__) || (defined(_M_IX86) && (_M_IX86 >= 500))
#define CPU_X86 500
#ifdef __SSE2__
#define ED25519_SSE2
#endif
#elif defined(__i486__) || (defined(_M_IX86) && (_M_IX86 >= 400))
#define CPU_X86 400
#elif defined(__i386__) || (defined(_M_IX86) && (_M_IX86 >= 300)) || defined(__X86__) || defined(_X86_) || defined(__I86__)

View File

@ -13,6 +13,7 @@
#define ED25519_FN3(fn,suffix) fn##suffix
#define ED25519_FN2(fn,suffix) ED25519_FN3(fn,suffix)
#define ED25519_FN(fn) ED25519_FN2(fn,ED25519_SUFFIX)
#define STATIC static
#include "ed25519-donna.h"
#include "ed25519.h"

View File

@ -140,8 +140,7 @@ barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256m
}
/* addition modulo m */
static void
add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
STATIC void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
bignum256modm_element_t c;
c = x[0] + y[0]; r[0] = c & 0x3fffffff; c >>= 30;
@ -158,8 +157,7 @@ add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
}
/* multiplication modulo m */
static void
mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
STATIC void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
bignum256modm r1, q1;
uint64_t c;
bignum256modm_element_t f;
@ -204,8 +202,7 @@ mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
barrett_reduce256_modm(r, q1, r1);
}
static void
expand256_modm(bignum256modm out, const unsigned char *in, size_t len) {
STATIC void expand256_modm(bignum256modm out, const unsigned char *in, size_t len) {
unsigned char work[64] = {0};
bignum256modm_element_t x[16];
bignum256modm q1;
@ -257,8 +254,7 @@ expand256_modm(bignum256modm out, const unsigned char *in, size_t len) {
barrett_reduce256_modm(out, q1, out);
}
static void
expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
STATIC void expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
bignum256modm_element_t x[8];
x[0] = U8TO32_LE(in + 0);
@ -281,8 +277,7 @@ expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
out[8] = ((x[ 7] >> 16) ) & 0x0000ffff;
}
static void
contract256_modm(unsigned char out[32], const bignum256modm in) {
STATIC void contract256_modm(unsigned char out[32], const bignum256modm in) {
U32TO8_LE(out + 0, (in[0] ) | (in[1] << 30));
U32TO8_LE(out + 4, (in[1] >> 2) | (in[2] << 28));
U32TO8_LE(out + 8, (in[2] >> 4) | (in[3] << 26));
@ -295,8 +290,7 @@ contract256_modm(unsigned char out[32], const bignum256modm in) {
static void
contract256_window4_modm(signed char r[64], const bignum256modm in) {
STATIC void contract256_window4_modm(signed char r[64], const bignum256modm in) {
char carry;
signed char *quads = r;
bignum256modm_element_t i, j, v;
@ -331,8 +325,7 @@ contract256_window4_modm(signed char r[64], const bignum256modm in) {
r[63] += carry;
}
static void
contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) {
STATIC void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) {
int i,j,k,b;
int m = (1 << (windowsize - 1)) - 1, soplen = 256;
signed char *bits = r;
@ -379,8 +372,7 @@ contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int wi
*/
/* out = a - b, a must be larger than b */
static void
sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm b, size_t limbsize) {
STATIC void sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm b, size_t limbsize) {
size_t i = 0;
bignum256modm_element_t carry = 0;
switch (limbsize) {
@ -399,8 +391,7 @@ sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm
/* is a < b */
static int
lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
STATIC int lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
switch (limbsize) {
case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1;
case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1;
@ -416,8 +407,7 @@ lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize)
}
/* is a <= b */
static int
lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
STATIC int lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
switch (limbsize) {
case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1;
case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1;
@ -434,8 +424,7 @@ lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize)
/* is a == 0 */
static int
iszero256_modm_batch(const bignum256modm a) {
STATIC int iszero256_modm_batch(const bignum256modm a) {
size_t i;
for (i = 0; i < 9; i++)
if (a[i])
@ -444,8 +433,7 @@ iszero256_modm_batch(const bignum256modm a) {
}
/* is a == 1 */
static int
isone256_modm_batch(const bignum256modm a) {
STATIC int isone256_modm_batch(const bignum256modm a) {
size_t i;
if (a[0] != 1)
return 0;
@ -456,8 +444,7 @@ isone256_modm_batch(const bignum256modm a) {
}
/* can a fit in to (at most) 128 bits */
static int
isatmost128bits256_modm_batch(const bignum256modm a) {
STATIC int isatmost128bits256_modm_batch(const bignum256modm a) {
uint32_t mask =
((a[8] ) | /* 16 */
(a[7] ) | /* 46 */

View File

@ -107,8 +107,7 @@ barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256m
}
static void
add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
STATIC void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
bignum256modm_element_t c;
c = x[0] + y[0]; r[0] = c & 0xffffffffffffff; c >>= 56;
@ -120,8 +119,7 @@ add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
reduce256_modm(r);
}
static void
mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
STATIC void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
bignum256modm q1, r1;
uint128_t c, mul;
bignum256modm_element_t f;
@ -149,8 +147,7 @@ mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
barrett_reduce256_modm(r, q1, r1);
}
static void
expand256_modm(bignum256modm out, const unsigned char *in, size_t len) {
STATIC void expand256_modm(bignum256modm out, const unsigned char *in, size_t len) {
unsigned char work[64] = {0};
bignum256modm_element_t x[16];
bignum256modm q1;
@ -186,8 +183,7 @@ expand256_modm(bignum256modm out, const unsigned char *in, size_t len) {
barrett_reduce256_modm(out, q1, out);
}
static void
expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
STATIC void expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
bignum256modm_element_t x[4];
x[0] = U8TO64_LE(in + 0);
@ -202,16 +198,14 @@ expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
out[4] = ((x[ 3] >> 32) ) & 0x000000ffffffff;
}
static void
contract256_modm(unsigned char out[32], const bignum256modm in) {
STATIC void contract256_modm(unsigned char out[32], const bignum256modm in) {
U64TO8_LE(out + 0, (in[0] ) | (in[1] << 56));
U64TO8_LE(out + 8, (in[1] >> 8) | (in[2] << 48));
U64TO8_LE(out + 16, (in[2] >> 16) | (in[3] << 40));
U64TO8_LE(out + 24, (in[3] >> 24) | (in[4] << 32));
}
static void
contract256_window4_modm(signed char r[64], const bignum256modm in) {
STATIC void contract256_window4_modm(signed char r[64], const bignum256modm in) {
char carry;
signed char *quads = r;
bignum256modm_element_t i, j, v, m;
@ -237,8 +231,7 @@ contract256_window4_modm(signed char r[64], const bignum256modm in) {
r[63] += carry;
}
static void
contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) {
STATIC void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) {
int i,j,k,b;
int m = (1 << (windowsize - 1)) - 1, soplen = 256;
signed char *bits = r;
@ -284,8 +277,7 @@ contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int wi
*/
/* out = a - b, a must be larger than b */
static void
sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm b, size_t limbsize) {
STATIC void sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm b, size_t limbsize) {
size_t i = 0;
bignum256modm_element_t carry = 0;
switch (limbsize) {
@ -300,8 +292,7 @@ sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm
/* is a < b */
static int
lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
STATIC int lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
size_t i = 0;
bignum256modm_element_t t, carry = 0;
switch (limbsize) {
@ -315,8 +306,7 @@ lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize)
}
/* is a <= b */
static int
lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
STATIC int lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
size_t i = 0;
bignum256modm_element_t t, carry = 0;
switch (limbsize) {
@ -330,8 +320,7 @@ lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize)
}
/* is a == 0 */
static int
iszero256_modm_batch(const bignum256modm a) {
STATIC int iszero256_modm_batch(const bignum256modm a) {
size_t i;
for (i = 0; i < 5; i++)
if (a[i])
@ -340,8 +329,7 @@ iszero256_modm_batch(const bignum256modm a) {
}
/* is a == 1 */
static int
isone256_modm_batch(const bignum256modm a) {
STATIC int isone256_modm_batch(const bignum256modm a) {
size_t i;
for (i = 0; i < 5; i++)
if (a[i] != ((i) ? 0 : 1))
@ -350,8 +338,7 @@ isone256_modm_batch(const bignum256modm a) {
}
/* can a fit in to (at most) 128 bits */
static int
isatmost128bits256_modm_batch(const bignum256modm a) {
STATIC int isatmost128bits256_modm_batch(const bignum256modm a) {
uint64_t mask =
((a[4] ) | /* 32 */
(a[3] ) | /* 88 */