1 #include "sc25519.h"
2 
3 /*Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493
4  *                                    = 7237005577332262213973186563042994240857116359379907606001950938285454250989
5  */
6 
7 /* Contains order, 2*order, 4*order, 8*order, each represented in 4 consecutive unsigned long long */
8 static const unsigned long long order[16] = {0x5812631A5CF5D3EDULL, 0x14DEF9DEA2F79CD6ULL,
9                                              0x0000000000000000ULL, 0x1000000000000000ULL,
10                                              0xB024C634B9EBA7DAULL, 0x29BDF3BD45EF39ACULL,
11                                              0x0000000000000000ULL, 0x2000000000000000ULL,
12                                              0x60498C6973D74FB4ULL, 0x537BE77A8BDE7359ULL,
13                                              0x0000000000000000ULL, 0x4000000000000000ULL,
14                                              0xC09318D2E7AE9F68ULL, 0xA6F7CEF517BCE6B2ULL,
15                                              0x0000000000000000ULL, 0x8000000000000000ULL};
16 
smaller(unsigned long long a,unsigned long long b)17 static unsigned long long smaller(unsigned long long a,unsigned long long b)
18 {
19   unsigned long long atop = a >> 32;
20   unsigned long long abot = a & 4294967295;
21   unsigned long long btop = b >> 32;
22   unsigned long long bbot = b & 4294967295;
23   unsigned long long atopbelowbtop = (atop - btop) >> 63;
24   unsigned long long atopeqbtop = ((atop ^ btop) - 1) >> 63;
25   unsigned long long abotbelowbbot = (abot - bbot) >> 63;
26   return atopbelowbtop | (atopeqbtop & abotbelowbbot);
27 }
28 
sc25519_from32bytes(sc25519 * r,const unsigned char x[32])29 void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
30 {
31   unsigned long long t[4];
32   unsigned long long b;
33   unsigned long long mask;
34   int i, j;
35 
36   /* assuming little-endian */
37   r->v[0] = *(unsigned long long *)x;
38   r->v[1] = *(((unsigned long long *)x)+1);
39   r->v[2] = *(((unsigned long long *)x)+2);
40   r->v[3] = *(((unsigned long long *)x)+3);
41 
42   for(j=3;j>=0;j--)
43   {
44     b=0;
45     for(i=0;i<4;i++)
46     {
47       b += order[4*j+i]; /* no overflow for this particular order */
48       t[i] = r->v[i] - b;
49       b = smaller(r->v[i],b);
50     }
51     mask = b - 1;
52     for(i=0;i<4;i++)
53       r->v[i] ^= mask & (r->v[i] ^ t[i]);
54   }
55 }
56