2 #include "crypto_uint32.h"
4 static unsigned char equal(signed char b
,signed char 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 */
15 static unsigned char negative(signed char b
)
17 unsigned long long x
= b
; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
18 x
>>= 63; /* 1: yes; 0: no */
22 static void cmov(ge_precomp
*t
,ge_precomp
*u
,unsigned char b
)
24 fe_cmov(t
->yplusx
,u
->yplusx
,b
);
25 fe_cmov(t
->yminusx
,u
->yminusx
,b
);
26 fe_cmov(t
->xy2d
,u
->xy2d
,b
);
29 /* base[i][j] = (j+1)*256^i*B */
30 static ge_precomp base
[32][8] = {
34 static void select(ge_precomp
*t
,int pos
,signed char b
)
37 unsigned char bnegative
= negative(b
);
38 unsigned char babs
= b
- (((-bnegative
) & b
) << 1);
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
);
57 where a = a[0]+256*a[1]+...+256^31 a[31]
58 B is the Ed25519 base point (x,4/5) with x positive.
64 void ge_scalarmult_base(ge_p3
*h
,const unsigned char *a
)
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;
77 /* each e[i] is between 0 and 15 */
78 /* e[63] is between 0 and 7 */
81 for (i
= 0;i
< 63;++i
) {
88 /* each e[i] is between -8 and 8 */
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
);
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
);
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
);