red25519 1.1.0-jruby

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,228 @@
1
+ package org.red25519;
2
+
3
+ import java.math.BigInteger;
4
+ import java.nio.ByteBuffer;
5
+ import java.security.MessageDigest;
6
+ import java.security.NoSuchAlgorithmException;
7
+ import java.util.Arrays;
8
+
9
+ /* Written by k3d3
10
+ * Released to the public domain
11
+ */
12
+
13
+ public class ed25519 {
14
+ static final int b = 256;
15
+ static final BigInteger q = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819949");
16
+ static final BigInteger qm2 = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819947");
17
+ static final BigInteger qp3 = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819952");
18
+ static final BigInteger l = new BigInteger("7237005577332262213973186563042994240857116359379907606001950938285454250989");
19
+ static final BigInteger d = new BigInteger("-4513249062541557337682894930092624173785641285191125241628941591882900924598840740");
20
+ static final BigInteger I = new BigInteger("19681161376707505956807079304988542015446066515923890162744021073123829784752");
21
+ static final BigInteger By = new BigInteger("46316835694926478169428394003475163141307993866256225615783033603165251855960");
22
+ static final BigInteger Bx = new BigInteger("15112221349535400772501151409588531511454012693041857206046113283949847762202");
23
+ static final BigInteger[] B = {Bx.mod(q),By.mod(q)};
24
+ static final BigInteger un = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819967");
25
+
26
+ static byte[] H(byte[] m) {
27
+ MessageDigest md;
28
+ try {
29
+ md = MessageDigest.getInstance("SHA-512");
30
+ md.reset();
31
+ return md.digest(m);
32
+ } catch (NoSuchAlgorithmException e) {
33
+ e.printStackTrace();
34
+ System.exit(1);
35
+ }
36
+ return null;
37
+ }
38
+
39
+ static BigInteger expmod(BigInteger b, BigInteger e, BigInteger m) {
40
+ //System.out.println("expmod open with b=" + b + " e=" + e + " m=" + m);
41
+ if (e.equals(BigInteger.ZERO)) {
42
+ //System.out.println("expmod close with 1z");
43
+ return BigInteger.ONE;
44
+ }
45
+ BigInteger t = expmod(b, e.divide(BigInteger.valueOf(2)), m).pow(2).mod(m);
46
+ //System.out.println("expmod 1/2 t="+t+" e="+e+" testbit="+(e.testBit(0)?1:0));
47
+ if (e.testBit(0)) {
48
+ t = t.multiply(b).mod(m);
49
+ }
50
+ //System.out.println("expmod close with " + t);
51
+ return t;
52
+ }
53
+
54
+ static BigInteger inv(BigInteger x) {
55
+ //System.out.println("inv open with " + x);
56
+ //System.out.println("inv close with " + expmod(x, qm2, q));
57
+ return expmod(x, qm2, q);
58
+ }
59
+
60
+ static BigInteger xrecover(BigInteger y) {
61
+ BigInteger y2 = y.multiply(y);
62
+ BigInteger xx = (y2.subtract(BigInteger.ONE)).multiply(inv(d.multiply(y2).add(BigInteger.ONE)));
63
+ BigInteger x = expmod(xx, qp3.divide(BigInteger.valueOf(8)), q);
64
+ if (!x.multiply(x).subtract(xx).mod(q).equals(BigInteger.ZERO)) x = (x.multiply(I).mod(q));
65
+ if (!x.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) x = q.subtract(x);
66
+ return x;
67
+ }
68
+
69
+ static BigInteger[] edwards(BigInteger[] P, BigInteger[] Q) {
70
+ BigInteger x1 = P[0];
71
+ BigInteger y1 = P[1];
72
+ BigInteger x2 = Q[0];
73
+ BigInteger y2 = Q[1];
74
+ BigInteger dtemp = d.multiply(x1).multiply(x2).multiply(y1).multiply(y2);
75
+ //System.out.println("edwards open with "+x1+","+x2+" "+y1+","+y2+" d="+d+" dtemp="+dtemp);
76
+ BigInteger x3 = ((x1.multiply(y2)).add((x2.multiply(y1)))).multiply(inv(BigInteger.ONE.add(dtemp)));
77
+ //System.out.println("edwards 1/2 with "+x1+","+x2+" "+y1+","+y2+" d="+d+" dtemp="+dtemp);
78
+ BigInteger y3 = ((y1.multiply(y2)).add((x1.multiply(x2)))).multiply(inv(BigInteger.ONE.subtract(dtemp)));
79
+ //System.out.println("edwards 2/2 with "+x1+","+x2+" "+y1+","+y2+" d="+d+" dtemp="+dtemp);
80
+ //System.out.println("edwards close with "+x3.mod(q)+","+y3.mod(q));
81
+ return new BigInteger[]{x3.mod(q), y3.mod(q)};
82
+ }
83
+
84
+ static BigInteger[] scalarmult(BigInteger[] P, BigInteger e) {
85
+ //System.out.println("scalarmult open with e = " + e);
86
+ if (e.equals(BigInteger.ZERO)) {
87
+ //System.out.println("scalarmult close with Q = 0,1");
88
+ return new BigInteger[]{BigInteger.ZERO, BigInteger.ONE};
89
+ }
90
+ BigInteger[] Q = scalarmult(P, e.divide(BigInteger.valueOf(2)));
91
+ //System.out.println("scalarmult asQ = " + Q[0] + "," + Q[1]);
92
+ Q = edwards(Q, Q);
93
+ //System.out.println("scalarmult aeQ = " + Q[0] + "," + Q[1] + " e="+e+" testbit="+(e.testBit(0)?1:0));
94
+ if (e.testBit(0)) Q = edwards(Q, P);
95
+ //System.out.println("scalarmult close with Q = " + Q[0] + "," + Q[1]);
96
+ return Q;
97
+ }
98
+
99
+ static byte[] encodeint(BigInteger y) {
100
+ byte[] in = y.toByteArray();
101
+ byte[] out = new byte[in.length];
102
+ for (int i=0;i<in.length;i++) {
103
+ out[i] = in[in.length-1-i];
104
+ }
105
+ return out;
106
+ }
107
+
108
+ static byte[] encodepoint(BigInteger[] P) {
109
+ BigInteger x = P[0];
110
+ BigInteger y = P[1];
111
+ byte[] out = encodeint(y);
112
+ //System.out.println("encodepoint x="+x+" testbit="+(x.testBit(0) ? 1 : 0));
113
+ out[out.length-1] |= (x.testBit(0) ? 0x80 : 0);
114
+ return out;
115
+ }
116
+
117
+ static int bit(byte[] h, int i) {
118
+ //System.out.println("bit open with i="+i);
119
+ //System.out.println("bit close with "+(h[i/8] >> (i%8) & 1));
120
+ return h[i/8] >> (i%8) & 1;
121
+ }
122
+
123
+ static byte[] publickey(byte[] sk) {
124
+ byte[] h = H(sk);
125
+ //System.out.println("publickey open with h=" + test.getHex(h));
126
+ BigInteger a = BigInteger.valueOf(2).pow(b-2);
127
+ for (int i=3;i<(b-2);i++) {
128
+ BigInteger apart = BigInteger.valueOf(2).pow(i).multiply(BigInteger.valueOf(bit(h,i)));
129
+ //System.out.println("publickey apart="+apart);
130
+ a = a.add(apart);
131
+ }
132
+ BigInteger[] A = scalarmult(B,a);
133
+ //System.out.println("publickey close with A="+A[0]+","+A[1]+" out="+test.getHex(encodepoint(A)));
134
+ return encodepoint(A);
135
+ }
136
+
137
+ static BigInteger Hint(byte[] m) {
138
+ byte[] h = H(m);
139
+ BigInteger hsum = BigInteger.ZERO;
140
+ for (int i=0;i<2*b;i++) {
141
+ hsum = hsum.add(BigInteger.valueOf(2).pow(i).multiply(BigInteger.valueOf(bit(h,i))));
142
+ }
143
+ return hsum;
144
+ }
145
+
146
+ static byte[] signature(byte[] m, byte[] sk, byte[] pk) {
147
+ byte[] h = H(sk);
148
+ //System.out.println("signature open with m="+test.getHex(m)+" h="+test.getHex(h)+" pk="+test.getHex(pk));
149
+ BigInteger a = BigInteger.valueOf(2).pow(b-2);
150
+ for (int i=3;i<(b-2);i++) {
151
+ a = a.add(BigInteger.valueOf(2).pow(i).multiply(BigInteger.valueOf(bit(h,i))));
152
+ }
153
+ //System.out.println("signature a="+a);
154
+ ByteBuffer rsub = ByteBuffer.allocate((b/8)+m.length);
155
+ rsub.put(h, b/8, b/4-b/8).put(m);
156
+ //System.out.println("signature rsub="+test.getHex(rsub.array()));
157
+ BigInteger r = Hint(rsub.array());
158
+ //System.out.println("signature r="+r);
159
+ BigInteger[] R = scalarmult(B,r);
160
+ ByteBuffer Stemp = ByteBuffer.allocate(32+pk.length+m.length);
161
+ Stemp.put(encodepoint(R)).put(pk).put(m);
162
+ BigInteger S = r.add(Hint(Stemp.array()).multiply(a)).mod(l);
163
+ ByteBuffer out = ByteBuffer.allocate(64);
164
+ out.put(encodepoint(R)).put(encodeint(S));
165
+ return out.array();
166
+ }
167
+
168
+ static boolean isoncurve(BigInteger[] P) {
169
+ BigInteger x = P[0];
170
+ BigInteger y = P[1];
171
+ //System.out.println("isoncurve open with P="+x+","+y);
172
+ BigInteger xx = x.multiply(x);
173
+ BigInteger yy = y.multiply(y);
174
+ BigInteger dxxyy = d.multiply(yy).multiply(xx);
175
+ //System.out.println("isoncurve close with "+xx.negate().add(yy).subtract(BigInteger.ONE).subtract(dxxyy).mod(q));
176
+ return xx.negate().add(yy).subtract(BigInteger.ONE).subtract(dxxyy).mod(q).equals(BigInteger.ZERO);
177
+ }
178
+
179
+ static BigInteger decodeint(byte[] s) {
180
+ byte[] out = new byte[s.length];
181
+ for (int i=0;i<s.length;i++) {
182
+ out[i] = s[s.length-1-i];
183
+ }
184
+ return new BigInteger(out).and(un);
185
+ }
186
+
187
+ static BigInteger[] decodepoint(byte[] s) throws Exception {
188
+ byte[] ybyte = new byte[s.length];
189
+ for (int i=0;i<s.length;i++) {
190
+ ybyte[i] = s[s.length-1-i];
191
+ }
192
+ //System.out.println("decodepoint open with s="+test.getHex(s)+" ybyte="+test.getHex(ybyte));
193
+ BigInteger y = new BigInteger(ybyte).and(un);
194
+ //System.out.println("decodepoint y="+y);
195
+ BigInteger x = xrecover(y);
196
+ //System.out.println("decodepoint x="+x+" testbit="+(x.testBit(0)?1:0)+" bit="+bit(s, b-1));
197
+ if ((x.testBit(0)?1:0) != bit(s, b-1)) {
198
+ x = q.subtract(x);
199
+ }
200
+ BigInteger[] P = {x,y};
201
+ if (!isoncurve(P)) throw new Exception("decoding point that is not on curve");
202
+ return P;
203
+ }
204
+
205
+ static boolean checkvalid(byte[] s, byte[] m, byte[] pk) throws Exception {
206
+ if (s.length != b/4) throw new Exception("signature length is wrong");
207
+ if (pk.length != b/8) throw new Exception("public-key length is wrong");
208
+ //System.out.println("checkvalid open with s="+test.getHex(s)+" m="+test.getHex(m)+" pk="+test.getHex(pk));
209
+ byte[] Rbyte = Arrays.copyOfRange(s, 0, b/8);
210
+ //System.out.println("checkvalid Rbyte="+test.getHex(Rbyte));
211
+ BigInteger[] R = decodepoint(Rbyte);
212
+ BigInteger[] A = decodepoint(pk);
213
+ //System.out.println("checkvalid R="+R[0]+","+R[1]+" A="+A[0]+","+A[1]);
214
+ byte[] Sbyte = Arrays.copyOfRange(s, b/8, b/4);
215
+ //System.out.println("checkvalid Sbyte="+test.getHex(Sbyte));
216
+ BigInteger S = decodeint(Sbyte);
217
+ //System.out.println("checkvalid S="+S);
218
+ ByteBuffer Stemp = ByteBuffer.allocate(32+pk.length+m.length);
219
+ Stemp.put(encodepoint(R)).put(pk).put(m);
220
+ BigInteger h = Hint(Stemp.array());
221
+ BigInteger[] ra = scalarmult(B,S);
222
+ BigInteger[] rb = edwards(R,scalarmult(A,h));
223
+ //System.out.println("checkvalid ra="+ra[0]+","+ra[1]+" rb="+rb[0]+","+rb[1]);
224
+ if (!ra[0].equals(rb[0]) || !ra[1].equals(rb[1])) // Constant time comparison
225
+ return false;
226
+ return true;
227
+ }
228
+ }
@@ -0,0 +1,82 @@
1
+ #include "ruby.h"
2
+ #include "crypto_sign.h"
3
+
4
+ static VALUE mEd25519 = Qnil;
5
+ static VALUE mEd25519_Engine = Qnil;
6
+
7
+ static VALUE Ed25519_Engine_create_keypair(VALUE self, VALUE seed);
8
+ static VALUE Ed25519_Engine_sign(VALUE self, VALUE signing_key, VALUE msg);
9
+ static VALUE Ed25519_Engine_verify(VALUE self, VALUE verify_key, VALUE signature, VALUE msg);
10
+
11
+ void Init_red25519_engine()
12
+ {
13
+ mEd25519 = rb_define_module("Ed25519");
14
+ mEd25519_Engine = rb_define_module_under(mEd25519, "Engine");
15
+
16
+ rb_define_singleton_method(mEd25519_Engine, "create_keypair", Ed25519_Engine_create_keypair, 1);
17
+ rb_define_singleton_method(mEd25519_Engine, "sign", Ed25519_Engine_sign, 2);
18
+ rb_define_singleton_method(mEd25519_Engine, "verify", Ed25519_Engine_verify, 3);
19
+ }
20
+
21
+ static VALUE Ed25519_Engine_create_keypair(VALUE self, VALUE seed)
22
+ {
23
+ unsigned char verify_key[PUBLICKEYBYTES], signing_key[SECRETKEYBYTES];
24
+
25
+ seed = rb_convert_type(seed, T_STRING, "String", "to_str");
26
+
27
+ if(RSTRING_LEN(seed) != SECRETKEYBYTES / 2)
28
+ rb_raise(rb_eArgError, "seed must be exactly %d bytes", SECRETKEYBYTES / 2);
29
+
30
+ crypto_sign_publickey(verify_key, signing_key, RSTRING_PTR(seed));
31
+
32
+ rb_ary_new3(2,
33
+ rb_str_new(verify_key, PUBLICKEYBYTES),
34
+ rb_str_new(signing_key, SECRETKEYBYTES)
35
+ );
36
+ }
37
+
38
+ static VALUE Ed25519_Engine_sign(VALUE self, VALUE signing_key, VALUE msg)
39
+ {
40
+ unsigned char *sig_and_msg;
41
+ unsigned long long sig_and_msg_len;
42
+ VALUE result;
43
+
44
+ if(RSTRING_LEN(signing_key) != SECRETKEYBYTES)
45
+ rb_raise(rb_eArgError, "private signing keys must be %d bytes", SECRETKEYBYTES);
46
+
47
+ sig_and_msg = (unsigned char *)xmalloc(SIGNATUREBYTES + RSTRING_LEN(msg));
48
+ crypto_sign(sig_and_msg, &sig_and_msg_len, RSTRING_PTR(msg), RSTRING_LEN(msg), RSTRING_PTR(signing_key));
49
+ result = rb_str_new(sig_and_msg, SIGNATUREBYTES);
50
+ free(sig_and_msg);
51
+
52
+ return result;
53
+ }
54
+
55
+ static VALUE Ed25519_Engine_verify(VALUE self, VALUE verify_key, VALUE signature, VALUE msg)
56
+ {
57
+ unsigned char *sig_and_msg, *buffer;
58
+ unsigned long long sig_and_msg_len, buffer_len;
59
+ int result;
60
+
61
+ if(RSTRING_LEN(verify_key) != PUBLICKEYBYTES)
62
+ rb_raise(rb_eArgError, "public verify keys must be %d bytes", PUBLICKEYBYTES);
63
+
64
+ if(RSTRING_LEN(signature) != SIGNATUREBYTES)
65
+ rb_raise(rb_eArgError, "public verify keys must be %d bytes", PUBLICKEYBYTES);
66
+
67
+ sig_and_msg_len = SIGNATUREBYTES + RSTRING_LEN(msg);
68
+ sig_and_msg = (unsigned char *)xmalloc(sig_and_msg_len);
69
+ buffer = (unsigned char *)xmalloc(sig_and_msg_len);
70
+ memcpy(sig_and_msg, RSTRING_PTR(signature), SIGNATUREBYTES);
71
+ memcpy(sig_and_msg + SIGNATUREBYTES, RSTRING_PTR(msg), RSTRING_LEN(msg));
72
+
73
+ result = crypto_sign_open(
74
+ buffer, &buffer_len,
75
+ sig_and_msg, sig_and_msg_len,
76
+ RSTRING_PTR(verify_key));
77
+
78
+ free(sig_and_msg);
79
+ free(buffer);
80
+
81
+ return result == 0 ? Qtrue : Qfalse;
82
+ }
@@ -0,0 +1,298 @@
1
+ #include "sc25519.h"
2
+
3
+ /*Arithmetic modulo the group order m = 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
+ static crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
12
+ {
13
+ unsigned int x = a;
14
+ x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */
15
+ x >>= 31; /* 0: no; 1: yes */
16
+ return x;
17
+ }
18
+
19
+ /* Reduce coefficients of r before calling reduce_add_sub */
20
+ static void reduce_add_sub(sc25519 *r)
21
+ {
22
+ crypto_uint32 pb = 0;
23
+ crypto_uint32 b;
24
+ crypto_uint32 mask;
25
+ int i;
26
+ unsigned char t[32];
27
+
28
+ for(i=0;i<32;i++)
29
+ {
30
+ pb += m[i];
31
+ b = lt(r->v[i],pb);
32
+ t[i] = r->v[i]-pb+(b<<8);
33
+ pb = b;
34
+ }
35
+ mask = b - 1;
36
+ for(i=0;i<32;i++)
37
+ r->v[i] ^= mask & (r->v[i] ^ t[i]);
38
+ }
39
+
40
+ /* Reduce coefficients of x before calling barrett_reduce */
41
+ static void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
42
+ {
43
+ /* See HAC, Alg. 14.42 */
44
+ int i,j;
45
+ crypto_uint32 q2[66];
46
+ crypto_uint32 *q3 = q2 + 33;
47
+ crypto_uint32 r1[33];
48
+ crypto_uint32 r2[33];
49
+ crypto_uint32 carry;
50
+ crypto_uint32 pb = 0;
51
+ crypto_uint32 b;
52
+
53
+ for (i = 0;i < 66;++i) q2[i] = 0;
54
+ for (i = 0;i < 33;++i) r2[i] = 0;
55
+
56
+ for(i=0;i<33;i++)
57
+ for(j=0;j<33;j++)
58
+ if(i+j >= 31) q2[i+j] += mu[i]*x[j+31];
59
+ carry = q2[31] >> 8;
60
+ q2[32] += carry;
61
+ carry = q2[32] >> 8;
62
+ q2[33] += carry;
63
+
64
+ for(i=0;i<33;i++)r1[i] = x[i];
65
+ for(i=0;i<32;i++)
66
+ for(j=0;j<33;j++)
67
+ if(i+j < 33) r2[i+j] += m[i]*q3[j];
68
+
69
+ for(i=0;i<32;i++)
70
+ {
71
+ carry = r2[i] >> 8;
72
+ r2[i+1] += carry;
73
+ r2[i] &= 0xff;
74
+ }
75
+
76
+ for(i=0;i<32;i++)
77
+ {
78
+ pb += r2[i];
79
+ b = lt(r1[i],pb);
80
+ r->v[i] = r1[i]-pb+(b<<8);
81
+ pb = b;
82
+ }
83
+
84
+ /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3
85
+ * If so: Handle it here!
86
+ */
87
+
88
+ reduce_add_sub(r);
89
+ reduce_add_sub(r);
90
+ }
91
+
92
+ void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
93
+ {
94
+ int i;
95
+ crypto_uint32 t[64];
96
+ for(i=0;i<32;i++) t[i] = x[i];
97
+ for(i=32;i<64;++i) t[i] = 0;
98
+ barrett_reduce(r, t);
99
+ }
100
+
101
+ void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16])
102
+ {
103
+ int i;
104
+ for(i=0;i<16;i++) r->v[i] = x[i];
105
+ }
106
+
107
+ void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
108
+ {
109
+ int i;
110
+ crypto_uint32 t[64];
111
+ for(i=0;i<64;i++) t[i] = x[i];
112
+ barrett_reduce(r, t);
113
+ }
114
+
115
+ void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x)
116
+ {
117
+ int i;
118
+ for(i=0;i<16;i++)
119
+ r->v[i] = x->v[i];
120
+ for(i=0;i<16;i++)
121
+ r->v[16+i] = 0;
122
+ }
123
+
124
+ void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
125
+ {
126
+ int i;
127
+ for(i=0;i<32;i++) r[i] = x->v[i];
128
+ }
129
+
130
+ int sc25519_iszero_vartime(const sc25519 *x)
131
+ {
132
+ int i;
133
+ for(i=0;i<32;i++)
134
+ if(x->v[i] != 0) return 0;
135
+ return 1;
136
+ }
137
+
138
+ int sc25519_isshort_vartime(const sc25519 *x)
139
+ {
140
+ int i;
141
+ for(i=31;i>15;i--)
142
+ if(x->v[i] != 0) return 0;
143
+ return 1;
144
+ }
145
+
146
+ int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y)
147
+ {
148
+ int i;
149
+ for(i=31;i>=0;i--)
150
+ {
151
+ if(x->v[i] < y->v[i]) return 1;
152
+ if(x->v[i] > y->v[i]) return 0;
153
+ }
154
+ return 0;
155
+ }
156
+
157
+ void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
158
+ {
159
+ int i, carry;
160
+ for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
161
+ for(i=0;i<31;i++)
162
+ {
163
+ carry = r->v[i] >> 8;
164
+ r->v[i+1] += carry;
165
+ r->v[i] &= 0xff;
166
+ }
167
+ reduce_add_sub(r);
168
+ }
169
+
170
+ void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y)
171
+ {
172
+ crypto_uint32 b = 0;
173
+ crypto_uint32 t;
174
+ int i;
175
+ for(i=0;i<32;i++)
176
+ {
177
+ t = x->v[i] - y->v[i] - b;
178
+ r->v[i] = t & 255;
179
+ b = (t >> 8) & 1;
180
+ }
181
+ }
182
+
183
+ void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
184
+ {
185
+ int i,j,carry;
186
+ crypto_uint32 t[64];
187
+ for(i=0;i<64;i++)t[i] = 0;
188
+
189
+ for(i=0;i<32;i++)
190
+ for(j=0;j<32;j++)
191
+ t[i+j] += x->v[i] * y->v[j];
192
+
193
+ /* Reduce coefficients */
194
+ for(i=0;i<63;i++)
195
+ {
196
+ carry = t[i] >> 8;
197
+ t[i+1] += carry;
198
+ t[i] &= 0xff;
199
+ }
200
+
201
+ barrett_reduce(r, t);
202
+ }
203
+
204
+ void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y)
205
+ {
206
+ sc25519 t;
207
+ sc25519_from_shortsc(&t, y);
208
+ sc25519_mul(r, x, &t);
209
+ }
210
+
211
+ void sc25519_window3(signed char r[85], const sc25519 *s)
212
+ {
213
+ char carry;
214
+ int i;
215
+ for(i=0;i<10;i++)
216
+ {
217
+ r[8*i+0] = s->v[3*i+0] & 7;
218
+ r[8*i+1] = (s->v[3*i+0] >> 3) & 7;
219
+ r[8*i+2] = (s->v[3*i+0] >> 6) & 7;
220
+ r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
221
+ r[8*i+3] = (s->v[3*i+1] >> 1) & 7;
222
+ r[8*i+4] = (s->v[3*i+1] >> 4) & 7;
223
+ r[8*i+5] = (s->v[3*i+1] >> 7) & 7;
224
+ r[8*i+5] ^= (s->v[3*i+2] << 1) & 7;
225
+ r[8*i+6] = (s->v[3*i+2] >> 2) & 7;
226
+ r[8*i+7] = (s->v[3*i+2] >> 5) & 7;
227
+ }
228
+ r[8*i+0] = s->v[3*i+0] & 7;
229
+ r[8*i+1] = (s->v[3*i+0] >> 3) & 7;
230
+ r[8*i+2] = (s->v[3*i+0] >> 6) & 7;
231
+ r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
232
+ r[8*i+3] = (s->v[3*i+1] >> 1) & 7;
233
+ r[8*i+4] = (s->v[3*i+1] >> 4) & 7;
234
+
235
+ /* Making it signed */
236
+ carry = 0;
237
+ for(i=0;i<84;i++)
238
+ {
239
+ r[i] += carry;
240
+ r[i+1] += r[i] >> 3;
241
+ r[i] &= 7;
242
+ carry = r[i] >> 2;
243
+ r[i] -= carry<<3;
244
+ }
245
+ r[84] += carry;
246
+ }
247
+
248
+ void sc25519_window5(signed char r[51], const sc25519 *s)
249
+ {
250
+ char carry;
251
+ int i;
252
+ for(i=0;i<6;i++)
253
+ {
254
+ r[8*i+0] = s->v[5*i+0] & 31;
255
+ r[8*i+1] = (s->v[5*i+0] >> 5) & 31;
256
+ r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;
257
+ r[8*i+2] = (s->v[5*i+1] >> 2) & 31;
258
+ r[8*i+3] = (s->v[5*i+1] >> 7) & 31;
259
+ r[8*i+3] ^= (s->v[5*i+2] << 1) & 31;
260
+ r[8*i+4] = (s->v[5*i+2] >> 4) & 31;
261
+ r[8*i+4] ^= (s->v[5*i+3] << 4) & 31;
262
+ r[8*i+5] = (s->v[5*i+3] >> 1) & 31;
263
+ r[8*i+6] = (s->v[5*i+3] >> 6) & 31;
264
+ r[8*i+6] ^= (s->v[5*i+4] << 2) & 31;
265
+ r[8*i+7] = (s->v[5*i+4] >> 3) & 31;
266
+ }
267
+ r[8*i+0] = s->v[5*i+0] & 31;
268
+ r[8*i+1] = (s->v[5*i+0] >> 5) & 31;
269
+ r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;
270
+ r[8*i+2] = (s->v[5*i+1] >> 2) & 31;
271
+
272
+ /* Making it signed */
273
+ carry = 0;
274
+ for(i=0;i<50;i++)
275
+ {
276
+ r[i] += carry;
277
+ r[i+1] += r[i] >> 5;
278
+ r[i] &= 31;
279
+ carry = r[i] >> 4;
280
+ r[i] -= carry<<5;
281
+ }
282
+ r[50] += carry;
283
+ }
284
+
285
+ void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)
286
+ {
287
+ int i;
288
+ for(i=0;i<31;i++)
289
+ {
290
+ r[4*i] = ( s1->v[i] & 3) ^ (( s2->v[i] & 3) << 2);
291
+ r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2);
292
+ r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2);
293
+ r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2);
294
+ }
295
+ r[124] = ( s1->v[31] & 3) ^ (( s2->v[31] & 3) << 2);
296
+ r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2);
297
+ r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2);
298
+ }
@@ -0,0 +1,73 @@
1
+ #ifndef SC25519_H
2
+ #define SC25519_H
3
+
4
+ #include "crypto_int32.h"
5
+ #include "crypto_uint32.h"
6
+
7
+ #define sc25519 crypto_sign_ed25519_ref_sc25519
8
+ #define shortsc25519 crypto_sign_ed25519_ref_shortsc25519
9
+ #define sc25519_from32bytes crypto_sign_ed25519_ref_sc25519_from32bytes
10
+ #define shortsc25519_from16bytes crypto_sign_ed25519_ref_shortsc25519_from16bytes
11
+ #define sc25519_from64bytes crypto_sign_ed25519_ref_sc25519_from64bytes
12
+ #define sc25519_from_shortsc crypto_sign_ed25519_ref_sc25519_from_shortsc
13
+ #define sc25519_to32bytes crypto_sign_ed25519_ref_sc25519_to32bytes
14
+ #define sc25519_iszero_vartime crypto_sign_ed25519_ref_sc25519_iszero_vartime
15
+ #define sc25519_isshort_vartime crypto_sign_ed25519_ref_sc25519_isshort_vartime
16
+ #define sc25519_lt_vartime crypto_sign_ed25519_ref_sc25519_lt_vartime
17
+ #define sc25519_add crypto_sign_ed25519_ref_sc25519_add
18
+ #define sc25519_sub_nored crypto_sign_ed25519_ref_sc25519_sub_nored
19
+ #define sc25519_mul crypto_sign_ed25519_ref_sc25519_mul
20
+ #define sc25519_mul_shortsc crypto_sign_ed25519_ref_sc25519_mul_shortsc
21
+ #define sc25519_window3 crypto_sign_ed25519_ref_sc25519_window3
22
+ #define sc25519_window5 crypto_sign_ed25519_ref_sc25519_window5
23
+ #define sc25519_2interleave2 crypto_sign_ed25519_ref_sc25519_2interleave2
24
+
25
+ typedef struct
26
+ {
27
+ crypto_uint32 v[32];
28
+ }
29
+ sc25519;
30
+
31
+ typedef struct
32
+ {
33
+ crypto_uint32 v[16];
34
+ }
35
+ shortsc25519;
36
+
37
+ void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]);
38
+
39
+ void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]);
40
+
41
+ void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]);
42
+
43
+ void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x);
44
+
45
+ void sc25519_to32bytes(unsigned char r[32], const sc25519 *x);
46
+
47
+ int sc25519_iszero_vartime(const sc25519 *x);
48
+
49
+ int sc25519_isshort_vartime(const sc25519 *x);
50
+
51
+ int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y);
52
+
53
+ void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y);
54
+
55
+ void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y);
56
+
57
+ void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y);
58
+
59
+ void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y);
60
+
61
+ /* Convert s into a representation of the form \sum_{i=0}^{84}r[i]2^3
62
+ * with r[i] in {-4,...,3}
63
+ */
64
+ void sc25519_window3(signed char r[85], const sc25519 *s);
65
+
66
+ /* Convert s into a representation of the form \sum_{i=0}^{50}r[i]2^5
67
+ * with r[i] in {-16,...,15}
68
+ */
69
+ void sc25519_window5(signed char r[51], const sc25519 *s);
70
+
71
+ void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2);
72
+
73
+ #endif