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