summaryrefslogtreecommitdiff
path: root/nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.c
diff options
context:
space:
mode:
Diffstat (limited to 'nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.c')
-rw-r--r--nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.c b/nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.c
new file mode 100644
index 00000000..5f27eb1b
--- /dev/null
+++ b/nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.c
@@ -0,0 +1,146 @@
1#include "sc25519.h"
2
3/*Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */
4
5static 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
8static 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 */
12static 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 */
29static 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) r2[i+j] += m[i]*q3[j];
52
53 for(i=0;i<32;i++)
54 {
55 carry = r2[i] >> 8;
56 r2[i+1] += carry;
57 r2[i] &= 0xff;
58 }
59
60 for(i=0;i<32;i++)
61 {
62 b = (r1[i]<pb+r2[i]);
63 r->v[i] = r1[i]-pb-r2[i]+b*256;
64 pb = b;
65 }
66
67 /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3
68 * If so: Handle it here!
69 */
70
71 reduce_add_sub(r);
72 reduce_add_sub(r);
73}
74
75/*
76static int iszero(const sc25519 *x)
77{
78 // Implement
79 return 0;
80}
81*/
82
83void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
84{
85 int i;
86 crypto_uint32 t[64] = {0};
87 for(i=0;i<32;i++) t[i] = x[i];
88 barrett_reduce(r, t);
89}
90
91void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
92{
93 int i;
94 crypto_uint32 t[64] = {0};
95 for(i=0;i<64;i++) t[i] = x[i];
96 barrett_reduce(r, t);
97}
98
99/* XXX: What we actually want for crypto_group is probably just something like
100 * void sc25519_frombytes(sc25519 *r, const unsigned char *x, size_t xlen)
101 */
102
103void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
104{
105 int i;
106 for(i=0;i<32;i++) r[i] = x->v[i];
107}
108
109void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
110{
111 int i, carry;
112 for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
113 for(i=0;i<31;i++)
114 {
115 carry = r->v[i] >> 8;
116 r->v[i+1] += carry;
117 r->v[i] &= 0xff;
118 }
119 reduce_add_sub(r);
120}
121
122void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
123{
124 int i,j,carry;
125 crypto_uint32 t[64];
126 for(i=0;i<64;i++)t[i] = 0;
127
128 for(i=0;i<32;i++)
129 for(j=0;j<32;j++)
130 t[i+j] += x->v[i] * y->v[j];
131
132 /* Reduce coefficients */
133 for(i=0;i<63;i++)
134 {
135 carry = t[i] >> 8;
136 t[i+1] += carry;
137 t[i] &= 0xff;
138 }
139
140 barrett_reduce(r, t);
141}
142
143void sc25519_square(sc25519 *r, const sc25519 *x)
144{
145 sc25519_mul(r, x, x);
146}