085e3f928a605059853ec5f0192db72d2c90e409
[trex.git] /
1 #include "sc25519.h"
2
3 /*Arithmetic modulo the group order n = 2^252 +  27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */
4
5 static const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14,
6                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
7
8 static const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21,
9                                      0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
10
11 /* Reduce coefficients of r before calling reduce_add_sub */
12 static void reduce_add_sub(sc25519 *r)
13 {
14   int i, b, pb=0, nb;
15   unsigned char t[32];
16
17   for(i=0;i<32;i++)
18   {
19     b = (r->v[i]<pb+m[i]);
20     t[i] = r->v[i]-pb-m[i]+b*256;
21     pb = b;
22   }
23   nb = 1-b;
24   for(i=0;i<32;i++)
25     r->v[i] = r->v[i]*b + t[i]*nb;
26 }
27
28 /* Reduce coefficients of x before calling barrett_reduce */
29 static void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
30 {
31   /* See HAC, Alg. 14.42 */
32   int i,j;
33   crypto_uint32 q2[66] = {0};
34   crypto_uint32 *q3 = q2 + 33;
35   crypto_uint32 r1[33];
36   crypto_uint32 r2[33] = {0};
37   crypto_uint32 carry;
38   int b, pb=0;
39
40   for(i=0;i<33;i++)
41     for(j=0;j<33;j++)
42       if(i+j >= 31) q2[i+j] += mu[i]*x[j+31];
43   carry = q2[31] >> 8;
44   q2[32] += carry;
45   carry = q2[32] >> 8;
46   q2[33] += carry;
47
48   for(i=0;i<33;i++)r1[i] = x[i];
49   for(i=0;i<32;i++) {
50     for(j=0;j<33;j++) {
51       if(i+j < 33) {
52           /* coverity[overrun-local] */
53           r2[i+j] += m[i]*q3[j];
54       }
55     }
56   }
57   for(i=0;i<32;i++)
58   {
59     carry = r2[i] >> 8;
60     r2[i+1] += carry;
61     r2[i] &= 0xff;
62   }
63
64   for(i=0;i<32;i++)
65   {
66     b = (r1[i]<pb+r2[i]);
67     r->v[i] = r1[i]-pb-r2[i]+b*256;
68     pb = b;
69   }
70
71   /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3
72    * If so: Handle  it here!
73    */
74
75   reduce_add_sub(r);
76   reduce_add_sub(r);
77 }
78
79 /*
80 static int iszero(const sc25519 *x)
81 {
82   // Implement
83   return 0;
84 }
85 */
86
87 void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
88 {
89   int i;
90   crypto_uint32 t[64] = {0};
91   for(i=0;i<32;i++) t[i] = x[i];
92   barrett_reduce(r, t);
93 }
94
95 void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
96 {
97   int i;
98   crypto_uint32 t[64] = {0};
99   for(i=0;i<64;i++) t[i] = x[i];
100   barrett_reduce(r, t);
101 }
102
103 /* XXX: What we actually want for crypto_group is probably just something like
104  * void sc25519_frombytes(sc25519 *r, const unsigned char *x, size_t xlen)
105  */
106
107 void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
108 {
109   int i;
110   for(i=0;i<32;i++) r[i] = x->v[i];
111 }
112
113 void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
114 {
115   int i, carry;
116   for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
117   for(i=0;i<31;i++)
118   {
119     carry = r->v[i] >> 8;
120     r->v[i+1] += carry;
121     r->v[i] &= 0xff;
122   }
123   reduce_add_sub(r);
124 }
125
126 void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
127 {
128   int i,j,carry;
129   crypto_uint32 t[64];
130   for(i=0;i<64;i++)t[i] = 0;
131
132   for(i=0;i<32;i++)
133     for(j=0;j<32;j++)
134       t[i+j] += x->v[i] * y->v[j];
135
136   /* Reduce coefficients */
137   for(i=0;i<63;i++)
138   {
139     carry = t[i] >> 8;
140     t[i+1] += carry;
141     t[i] &= 0xff;
142   }
143
144   barrett_reduce(r, t);
145 }
146
147 void sc25519_square(sc25519 *r, const sc25519 *x)
148 {
149   sc25519_mul(r, x, x);
150 }