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:
parent
87c920a7e7
commit
cb471ba2ec
1
Makefile
1
Makefile
@ -21,6 +21,7 @@ CFLAGS += $(OPTFLAGS) \
|
||||
-Winit-self \
|
||||
-Wuninitialized \
|
||||
-Wformat-security \
|
||||
-Wno-unused-function \
|
||||
-Werror
|
||||
|
||||
# disable sequence point warning because of AES code
|
||||
|
@ -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);
|
||||
|
@ -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}},
|
||||
|
@ -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}},
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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__)
|
||||
|
@ -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"
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user