f3490a94c0992ccf4991e82ec724e3c5153fab14
[trex.git] /
1 #include "ge.h"
2 #include "crypto_uint32.h"
3
4 #ifdef __cplusplus
5 # if __GNUC__
6 #  pragma GCC diagnostic ignored "-Wlong-long"
7 # endif
8 #endif
9
10 static unsigned char equal(signed char b,signed char c)
11 {
12   unsigned char ub = b;
13   unsigned char uc = c;
14   unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
15   crypto_uint32 y = x; /* 0: yes; 1..255: no */
16   y -= 1; /* 4294967295: yes; 0..254: no */
17   y >>= 31; /* 1: yes; 0: no */
18   return y;
19 }
20
21 static unsigned char negative(signed char b)
22 {
23   unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
24   x >>= 63; /* 1: yes; 0: no */
25   return x;
26 }
27
28 static void cmov(ge_precomp *t,ge_precomp *u,unsigned char b)
29 {
30   fe_cmov(t->yplusx,u->yplusx,b);
31   fe_cmov(t->yminusx,u->yminusx,b);
32   fe_cmov(t->xy2d,u->xy2d,b);
33 }
34
35 /* base[i][j] = (j+1)*256^i*B */
36 static ge_precomp base[32][8] = {
37 #include "base.h"
38 } ;
39
40 static void ge_select(ge_precomp *t,int pos,signed char b)
41 {
42   ge_precomp minust;
43   unsigned char bnegative = negative(b);
44   unsigned char babs = b - (((-bnegative) & b) << 1);
45
46   ge_precomp_0(t);
47   cmov(t,&base[pos][0],equal(babs,1));
48   cmov(t,&base[pos][1],equal(babs,2));
49   cmov(t,&base[pos][2],equal(babs,3));
50   cmov(t,&base[pos][3],equal(babs,4));
51   cmov(t,&base[pos][4],equal(babs,5));
52   cmov(t,&base[pos][5],equal(babs,6));
53   cmov(t,&base[pos][6],equal(babs,7));
54   cmov(t,&base[pos][7],equal(babs,8));
55   fe_copy(minust.yplusx,t->yminusx);
56   fe_copy(minust.yminusx,t->yplusx);
57   fe_neg(minust.xy2d,t->xy2d);
58   cmov(t,&minust,bnegative);
59 }
60
61 /*
62 h = a * B
63 where a = a[0]+256*a[1]+...+256^31 a[31]
64 B is the Ed25519 base point (x,4/5) with x positive.
65
66 Preconditions:
67   a[31] <= 127
68 */
69
70 void ge_scalarmult_base(ge_p3 *h,const unsigned char *a)
71 {
72   signed char e[64];
73   signed char carry;
74   ge_p1p1 r;
75   ge_p2 s;
76   ge_precomp t;
77   int i;
78
79   for (i = 0;i < 32;++i) {
80     e[2 * i + 0] = (a[i] >> 0) & 15;
81     e[2 * i + 1] = (a[i] >> 4) & 15;
82   }
83   /* each e[i] is between 0 and 15 */
84   /* e[63] is between 0 and 7 */
85
86   carry = 0;
87   for (i = 0;i < 63;++i) {
88     e[i] += carry;
89     carry = e[i] + 8;
90     carry >>= 4;
91     e[i] -= carry << 4;
92   }
93   e[63] += carry;
94   /* each e[i] is between -8 and 8 */
95
96   ge_p3_0(h);
97   for (i = 1;i < 64;i += 2) {
98     ge_select(&t,i / 2,e[i]);
99     ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);
100   }
101
102   ge_p3_dbl(&r,h);  ge_p1p1_to_p2(&s,&r);
103   ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
104   ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
105   ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r);
106
107   for (i = 0;i < 64;i += 2) {
108     ge_select(&t,i / 2,e[i]);
109     ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);
110   }
111 }