136 lines
4.6 KiB
C
136 lines
4.6 KiB
C
#include "ge.h"
|
|
|
|
static void slide(signed char *r,const unsigned char *a)
|
|
{
|
|
int i;
|
|
int b;
|
|
int k;
|
|
|
|
for (i = 0;i < 256;++i)
|
|
r[i] = 1 & (a[i >> 3] >> (i & 7));
|
|
|
|
for (i = 0;i < 256;++i)
|
|
if (r[i]) {
|
|
for (b = 1;b <= 6 && i + b < 256;++b) {
|
|
if (r[i + b]) {
|
|
if (r[i] + (r[i + b] << b) <= 15) {
|
|
r[i] += r[i + b] << b; r[i + b] = 0;
|
|
} else if (r[i] - (r[i + b] << b) >= -15) {
|
|
r[i] -= r[i + b] << b;
|
|
for (k = i + b;k < 256;++k) {
|
|
if (!r[k]) {
|
|
r[k] = 1;
|
|
break;
|
|
}
|
|
r[k] = 0;
|
|
}
|
|
} else
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
static ge_precomp Bi[8] = {
|
|
{
|
|
{ 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 },
|
|
{ -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 },
|
|
{ -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 },
|
|
},
|
|
{
|
|
{ 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 },
|
|
{ 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 },
|
|
{ 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 },
|
|
},
|
|
{
|
|
{ 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 },
|
|
{ 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 },
|
|
{ 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 },
|
|
},
|
|
{
|
|
{ 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 },
|
|
{ -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 },
|
|
{ 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 },
|
|
},
|
|
{
|
|
{ -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 },
|
|
{ -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 },
|
|
{ 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 },
|
|
},
|
|
{
|
|
{ -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 },
|
|
{ 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 },
|
|
{ 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 },
|
|
},
|
|
{
|
|
{ -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 },
|
|
{ -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 },
|
|
{ -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 },
|
|
},
|
|
{
|
|
{ -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 },
|
|
{ -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 },
|
|
{ -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 },
|
|
},
|
|
} ;
|
|
|
|
/*
|
|
r = a * A + b * B
|
|
where a = a[0]+256*a[1]+...+256^31 a[31].
|
|
and b = b[0]+256*b[1]+...+256^31 b[31].
|
|
B is the Ed25519 base point (x,4/5) with x positive.
|
|
*/
|
|
|
|
void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b)
|
|
{
|
|
signed char aslide[256];
|
|
signed char bslide[256];
|
|
ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
|
|
ge_p1p1 t;
|
|
ge_p3 u;
|
|
ge_p3 A2;
|
|
int i;
|
|
|
|
slide(aslide,a);
|
|
slide(bslide,b);
|
|
|
|
ge_p3_to_cached(&Ai[0],A);
|
|
ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t);
|
|
ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u);
|
|
ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u);
|
|
ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u);
|
|
ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u);
|
|
ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u);
|
|
ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u);
|
|
ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u);
|
|
|
|
ge_p2_0(r);
|
|
|
|
for (i = 255;i >= 0;--i) {
|
|
if (aslide[i] || bslide[i]) break;
|
|
}
|
|
|
|
for (;i >= 0;--i) {
|
|
ge_p2_dbl(&t,r);
|
|
|
|
if (aslide[i] > 0) {
|
|
ge_p1p1_to_p3(&u,&t);
|
|
ge_add(&t,&u,&Ai[aslide[i]/2]);
|
|
} else if (aslide[i] < 0) {
|
|
ge_p1p1_to_p3(&u,&t);
|
|
ge_sub(&t,&u,&Ai[(-aslide[i])/2]);
|
|
}
|
|
|
|
if (bslide[i] > 0) {
|
|
ge_p1p1_to_p3(&u,&t);
|
|
ge_madd(&t,&u,&Bi[bslide[i]/2]);
|
|
} else if (bslide[i] < 0) {
|
|
ge_p1p1_to_p3(&u,&t);
|
|
ge_msub(&t,&u,&Bi[(-bslide[i])/2]);
|
|
}
|
|
|
|
ge_p1p1_to_p2(r,&t);
|
|
}
|
|
}
|