red25519 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,239 @@
1
+ //#include "crypto_hashblocks.h"
2
+
3
+ typedef unsigned long long uint64;
4
+
5
+ static uint64 load_bigendian(const unsigned char *x)
6
+ {
7
+ return
8
+ (uint64) (x[7]) \
9
+ | (((uint64) (x[6])) << 8) \
10
+ | (((uint64) (x[5])) << 16) \
11
+ | (((uint64) (x[4])) << 24) \
12
+ | (((uint64) (x[3])) << 32) \
13
+ | (((uint64) (x[2])) << 40) \
14
+ | (((uint64) (x[1])) << 48) \
15
+ | (((uint64) (x[0])) << 56)
16
+ ;
17
+ }
18
+
19
+ static void store_bigendian(unsigned char *x,uint64 u)
20
+ {
21
+ x[7] = u; u >>= 8;
22
+ x[6] = u; u >>= 8;
23
+ x[5] = u; u >>= 8;
24
+ x[4] = u; u >>= 8;
25
+ x[3] = u; u >>= 8;
26
+ x[2] = u; u >>= 8;
27
+ x[1] = u; u >>= 8;
28
+ x[0] = u;
29
+ }
30
+
31
+ #define SHR(x,c) ((x) >> (c))
32
+ #define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c))))
33
+
34
+ #define Ch(x,y,z) ((x & y) ^ (~x & z))
35
+ #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
36
+ #define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
37
+ #define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
38
+ #define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7))
39
+ #define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6))
40
+
41
+ #define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0;
42
+
43
+ #define EXPAND \
44
+ M(w0 ,w14,w9 ,w1 ) \
45
+ M(w1 ,w15,w10,w2 ) \
46
+ M(w2 ,w0 ,w11,w3 ) \
47
+ M(w3 ,w1 ,w12,w4 ) \
48
+ M(w4 ,w2 ,w13,w5 ) \
49
+ M(w5 ,w3 ,w14,w6 ) \
50
+ M(w6 ,w4 ,w15,w7 ) \
51
+ M(w7 ,w5 ,w0 ,w8 ) \
52
+ M(w8 ,w6 ,w1 ,w9 ) \
53
+ M(w9 ,w7 ,w2 ,w10) \
54
+ M(w10,w8 ,w3 ,w11) \
55
+ M(w11,w9 ,w4 ,w12) \
56
+ M(w12,w10,w5 ,w13) \
57
+ M(w13,w11,w6 ,w14) \
58
+ M(w14,w12,w7 ,w15) \
59
+ M(w15,w13,w8 ,w0 )
60
+
61
+ #define F(w,k) \
62
+ T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \
63
+ T2 = Sigma0(a) + Maj(a,b,c); \
64
+ h = g; \
65
+ g = f; \
66
+ f = e; \
67
+ e = d + T1; \
68
+ d = c; \
69
+ c = b; \
70
+ b = a; \
71
+ a = T1 + T2;
72
+
73
+ int crypto_hashblocks(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen)
74
+ {
75
+ uint64 state[8];
76
+ uint64 a;
77
+ uint64 b;
78
+ uint64 c;
79
+ uint64 d;
80
+ uint64 e;
81
+ uint64 f;
82
+ uint64 g;
83
+ uint64 h;
84
+ uint64 T1;
85
+ uint64 T2;
86
+
87
+ a = load_bigendian(statebytes + 0); state[0] = a;
88
+ b = load_bigendian(statebytes + 8); state[1] = b;
89
+ c = load_bigendian(statebytes + 16); state[2] = c;
90
+ d = load_bigendian(statebytes + 24); state[3] = d;
91
+ e = load_bigendian(statebytes + 32); state[4] = e;
92
+ f = load_bigendian(statebytes + 40); state[5] = f;
93
+ g = load_bigendian(statebytes + 48); state[6] = g;
94
+ h = load_bigendian(statebytes + 56); state[7] = h;
95
+
96
+ while (inlen >= 128) {
97
+ uint64 w0 = load_bigendian(in + 0);
98
+ uint64 w1 = load_bigendian(in + 8);
99
+ uint64 w2 = load_bigendian(in + 16);
100
+ uint64 w3 = load_bigendian(in + 24);
101
+ uint64 w4 = load_bigendian(in + 32);
102
+ uint64 w5 = load_bigendian(in + 40);
103
+ uint64 w6 = load_bigendian(in + 48);
104
+ uint64 w7 = load_bigendian(in + 56);
105
+ uint64 w8 = load_bigendian(in + 64);
106
+ uint64 w9 = load_bigendian(in + 72);
107
+ uint64 w10 = load_bigendian(in + 80);
108
+ uint64 w11 = load_bigendian(in + 88);
109
+ uint64 w12 = load_bigendian(in + 96);
110
+ uint64 w13 = load_bigendian(in + 104);
111
+ uint64 w14 = load_bigendian(in + 112);
112
+ uint64 w15 = load_bigendian(in + 120);
113
+
114
+ F(w0 ,0x428a2f98d728ae22ULL)
115
+ F(w1 ,0x7137449123ef65cdULL)
116
+ F(w2 ,0xb5c0fbcfec4d3b2fULL)
117
+ F(w3 ,0xe9b5dba58189dbbcULL)
118
+ F(w4 ,0x3956c25bf348b538ULL)
119
+ F(w5 ,0x59f111f1b605d019ULL)
120
+ F(w6 ,0x923f82a4af194f9bULL)
121
+ F(w7 ,0xab1c5ed5da6d8118ULL)
122
+ F(w8 ,0xd807aa98a3030242ULL)
123
+ F(w9 ,0x12835b0145706fbeULL)
124
+ F(w10,0x243185be4ee4b28cULL)
125
+ F(w11,0x550c7dc3d5ffb4e2ULL)
126
+ F(w12,0x72be5d74f27b896fULL)
127
+ F(w13,0x80deb1fe3b1696b1ULL)
128
+ F(w14,0x9bdc06a725c71235ULL)
129
+ F(w15,0xc19bf174cf692694ULL)
130
+
131
+ EXPAND
132
+
133
+ F(w0 ,0xe49b69c19ef14ad2ULL)
134
+ F(w1 ,0xefbe4786384f25e3ULL)
135
+ F(w2 ,0x0fc19dc68b8cd5b5ULL)
136
+ F(w3 ,0x240ca1cc77ac9c65ULL)
137
+ F(w4 ,0x2de92c6f592b0275ULL)
138
+ F(w5 ,0x4a7484aa6ea6e483ULL)
139
+ F(w6 ,0x5cb0a9dcbd41fbd4ULL)
140
+ F(w7 ,0x76f988da831153b5ULL)
141
+ F(w8 ,0x983e5152ee66dfabULL)
142
+ F(w9 ,0xa831c66d2db43210ULL)
143
+ F(w10,0xb00327c898fb213fULL)
144
+ F(w11,0xbf597fc7beef0ee4ULL)
145
+ F(w12,0xc6e00bf33da88fc2ULL)
146
+ F(w13,0xd5a79147930aa725ULL)
147
+ F(w14,0x06ca6351e003826fULL)
148
+ F(w15,0x142929670a0e6e70ULL)
149
+
150
+ EXPAND
151
+
152
+ F(w0 ,0x27b70a8546d22ffcULL)
153
+ F(w1 ,0x2e1b21385c26c926ULL)
154
+ F(w2 ,0x4d2c6dfc5ac42aedULL)
155
+ F(w3 ,0x53380d139d95b3dfULL)
156
+ F(w4 ,0x650a73548baf63deULL)
157
+ F(w5 ,0x766a0abb3c77b2a8ULL)
158
+ F(w6 ,0x81c2c92e47edaee6ULL)
159
+ F(w7 ,0x92722c851482353bULL)
160
+ F(w8 ,0xa2bfe8a14cf10364ULL)
161
+ F(w9 ,0xa81a664bbc423001ULL)
162
+ F(w10,0xc24b8b70d0f89791ULL)
163
+ F(w11,0xc76c51a30654be30ULL)
164
+ F(w12,0xd192e819d6ef5218ULL)
165
+ F(w13,0xd69906245565a910ULL)
166
+ F(w14,0xf40e35855771202aULL)
167
+ F(w15,0x106aa07032bbd1b8ULL)
168
+
169
+ EXPAND
170
+
171
+ F(w0 ,0x19a4c116b8d2d0c8ULL)
172
+ F(w1 ,0x1e376c085141ab53ULL)
173
+ F(w2 ,0x2748774cdf8eeb99ULL)
174
+ F(w3 ,0x34b0bcb5e19b48a8ULL)
175
+ F(w4 ,0x391c0cb3c5c95a63ULL)
176
+ F(w5 ,0x4ed8aa4ae3418acbULL)
177
+ F(w6 ,0x5b9cca4f7763e373ULL)
178
+ F(w7 ,0x682e6ff3d6b2b8a3ULL)
179
+ F(w8 ,0x748f82ee5defb2fcULL)
180
+ F(w9 ,0x78a5636f43172f60ULL)
181
+ F(w10,0x84c87814a1f0ab72ULL)
182
+ F(w11,0x8cc702081a6439ecULL)
183
+ F(w12,0x90befffa23631e28ULL)
184
+ F(w13,0xa4506cebde82bde9ULL)
185
+ F(w14,0xbef9a3f7b2c67915ULL)
186
+ F(w15,0xc67178f2e372532bULL)
187
+
188
+ EXPAND
189
+
190
+ F(w0 ,0xca273eceea26619cULL)
191
+ F(w1 ,0xd186b8c721c0c207ULL)
192
+ F(w2 ,0xeada7dd6cde0eb1eULL)
193
+ F(w3 ,0xf57d4f7fee6ed178ULL)
194
+ F(w4 ,0x06f067aa72176fbaULL)
195
+ F(w5 ,0x0a637dc5a2c898a6ULL)
196
+ F(w6 ,0x113f9804bef90daeULL)
197
+ F(w7 ,0x1b710b35131c471bULL)
198
+ F(w8 ,0x28db77f523047d84ULL)
199
+ F(w9 ,0x32caab7b40c72493ULL)
200
+ F(w10,0x3c9ebe0a15c9bebcULL)
201
+ F(w11,0x431d67c49c100d4cULL)
202
+ F(w12,0x4cc5d4becb3e42b6ULL)
203
+ F(w13,0x597f299cfc657e2aULL)
204
+ F(w14,0x5fcb6fab3ad6faecULL)
205
+ F(w15,0x6c44198c4a475817ULL)
206
+
207
+ a += state[0];
208
+ b += state[1];
209
+ c += state[2];
210
+ d += state[3];
211
+ e += state[4];
212
+ f += state[5];
213
+ g += state[6];
214
+ h += state[7];
215
+
216
+ state[0] = a;
217
+ state[1] = b;
218
+ state[2] = c;
219
+ state[3] = d;
220
+ state[4] = e;
221
+ state[5] = f;
222
+ state[6] = g;
223
+ state[7] = h;
224
+
225
+ in += 128;
226
+ inlen -= 128;
227
+ }
228
+
229
+ store_bigendian(statebytes + 0,state[0]);
230
+ store_bigendian(statebytes + 8,state[1]);
231
+ store_bigendian(statebytes + 16,state[2]);
232
+ store_bigendian(statebytes + 24,state[3]);
233
+ store_bigendian(statebytes + 32,state[4]);
234
+ store_bigendian(statebytes + 40,state[5]);
235
+ store_bigendian(statebytes + 48,state[6]);
236
+ store_bigendian(statebytes + 56,state[7]);
237
+
238
+ return inlen;
239
+ }
@@ -0,0 +1,72 @@
1
+ /*
2
+ 20080913
3
+ D. J. Bernstein
4
+ Public domain.
5
+ */
6
+
7
+ #include "sha512.h"
8
+
9
+ extern int crypto_hashblocks(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen);
10
+
11
+ #define blocks crypto_hashblocks
12
+
13
+ static const unsigned char iv[64] = {
14
+ 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
15
+ 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
16
+ 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
17
+ 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
18
+ 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
19
+ 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
20
+ 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
21
+ 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
22
+ } ;
23
+
24
+ typedef unsigned long long uint64;
25
+
26
+ int crypto_hash_sha512(unsigned char *out,const unsigned char *in,unsigned long long inlen)
27
+ {
28
+ unsigned char h[64];
29
+ unsigned char padded[256];
30
+ int i;
31
+ unsigned long long bytes = inlen;
32
+
33
+ for (i = 0;i < 64;++i) h[i] = iv[i];
34
+
35
+ blocks(h,in,inlen);
36
+ in += inlen;
37
+ inlen &= 127;
38
+ in -= inlen;
39
+
40
+ for (i = 0;i < inlen;++i) padded[i] = in[i];
41
+ padded[inlen] = 0x80;
42
+
43
+ if (inlen < 112) {
44
+ for (i = inlen + 1;i < 119;++i) padded[i] = 0;
45
+ padded[119] = bytes >> 61;
46
+ padded[120] = bytes >> 53;
47
+ padded[121] = bytes >> 45;
48
+ padded[122] = bytes >> 37;
49
+ padded[123] = bytes >> 29;
50
+ padded[124] = bytes >> 21;
51
+ padded[125] = bytes >> 13;
52
+ padded[126] = bytes >> 5;
53
+ padded[127] = bytes << 3;
54
+ blocks(h,padded,128);
55
+ } else {
56
+ for (i = inlen + 1;i < 247;++i) padded[i] = 0;
57
+ padded[247] = bytes >> 61;
58
+ padded[248] = bytes >> 53;
59
+ padded[249] = bytes >> 45;
60
+ padded[250] = bytes >> 37;
61
+ padded[251] = bytes >> 29;
62
+ padded[252] = bytes >> 21;
63
+ padded[253] = bytes >> 13;
64
+ padded[254] = bytes >> 5;
65
+ padded[255] = bytes << 3;
66
+ blocks(h,padded,256);
67
+ }
68
+
69
+ for (i = 0;i < 64;++i) out[i] = h[i];
70
+
71
+ return 0;
72
+ }
@@ -0,0 +1,4 @@
1
+ extern int crypto_hashblocks(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen);
2
+ extern int crypto_hash_sha512(unsigned char *out,const unsigned char *in,unsigned long long inlen);
3
+
4
+ #define crypto_hash_sha512_BYTES 64
@@ -0,0 +1,40 @@
1
+ #include "crypto_verify_32.h"
2
+
3
+ int crypto_verify_32(const unsigned char *x,const unsigned char *y)
4
+ {
5
+ unsigned int differentbits = 0;
6
+ #define F(i) differentbits |= x[i] ^ y[i];
7
+ F(0)
8
+ F(1)
9
+ F(2)
10
+ F(3)
11
+ F(4)
12
+ F(5)
13
+ F(6)
14
+ F(7)
15
+ F(8)
16
+ F(9)
17
+ F(10)
18
+ F(11)
19
+ F(12)
20
+ F(13)
21
+ F(14)
22
+ F(15)
23
+ F(16)
24
+ F(17)
25
+ F(18)
26
+ F(19)
27
+ F(20)
28
+ F(21)
29
+ F(22)
30
+ F(23)
31
+ F(24)
32
+ F(25)
33
+ F(26)
34
+ F(27)
35
+ F(28)
36
+ F(29)
37
+ F(30)
38
+ F(31)
39
+ return (1 & ((differentbits - 1) >> 8)) - 1;
40
+ }
data/lib/red25519.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'red25519/version'
2
+ require 'red25519_engine'
3
+ require 'red25519/keys'
4
+
5
+ module Ed25519
6
+ SECRET_KEY_BYTES = 32
7
+ PUBLIC_KEY_BYTES = 32
8
+ SIGNATURE_BYTES = 64
9
+
10
+ class SelfTestFailure < StandardError; end
11
+
12
+ def self.test
13
+ signature_key = Ed25519::SigningKey.new("A" * 32)
14
+
15
+ unless signature_key.verify_key.to_hex == 'db995fe25169d141cab9bbba92baa01f9f2e1ece7df4cb2ac05190f37fcc1f9d'
16
+ raise SelfTestFailure, "failed to generate verify key correctly"
17
+ end
18
+
19
+ message = "crypto libraries should self-test on boot"
20
+ signature = signature_key.sign(message)
21
+ unless signature.unpack("H*").first == 'c62c12a3a6cbfa04800d4be81468ef8aecd152a6a26a81d91257baecef13ba209531fe905a843e833c8b71cee04400fa2af3a29fef1152ece470421848758d0a'
22
+ raise SelfTestFailure, "failed to generate correct signature"
23
+ end
24
+
25
+ verify_key = signature_key.verify_key
26
+ unless verify_key.verify(signature, message)
27
+ raise SelfTestFailure, "failed to verify a valid signature"
28
+ end
29
+
30
+ bad_signature = signature[0...63] + 'X'
31
+ unless verify_key.verify(bad_signature, message) == false
32
+ raise SelfTestFailure, "failed to detect an invalid signature"
33
+ end
34
+ end
35
+ end
36
+
37
+ Ed25519.test
38
+
39
+ # TIMTOWTDI!!!
40
+ Red25519 = Ed25519
@@ -0,0 +1,73 @@
1
+ require 'securerandom'
2
+ require 'hkdf'
3
+
4
+ module Ed25519
5
+ class SigningKey
6
+ attr_reader :verify_key
7
+
8
+ def self.generate
9
+ random_bytes = SecureRandom.random_bytes(Ed25519::SECRET_KEY_BYTES)
10
+ hkdf = HKDF.new(random_bytes)
11
+ new hkdf.next_bytes(Ed25519::SECRET_KEY_BYTES)
12
+ end
13
+
14
+ def initialize(seed)
15
+ case seed.length
16
+ when 32
17
+ @seed = seed
18
+ when 64
19
+ @seed = [seed].pack("H*")
20
+ else raise ArgumentError, "seed must be 32 or 64 bytes long"
21
+ end
22
+
23
+ verify_key, @signing_key = Ed25519::Engine.create_keypair(@seed)
24
+ @verify_key = VerifyKey.new(verify_key)
25
+ end
26
+
27
+ def sign(message)
28
+ Ed25519::Engine.sign(@signing_key, message)
29
+ end
30
+
31
+ def inspect
32
+ "#<Ed25519::SigningKey:#{to_hex}>"
33
+ end
34
+
35
+ def to_bytes
36
+ @seed
37
+ end
38
+ alias_method :to_s, :to_bytes
39
+
40
+ def to_hex
41
+ to_bytes.unpack("H*").first
42
+ end
43
+ end
44
+
45
+ class VerifyKey
46
+ def initialize(string)
47
+ case string.length
48
+ when 32
49
+ @key = string
50
+ when 64
51
+ @key = [string].pack("H*")
52
+ else raise ArgumentError, "seed must be 32 or 64 bytes long"
53
+ end
54
+ end
55
+
56
+ def verify(signature, message)
57
+ Ed25519::Engine.verify(@key, signature, message)
58
+ end
59
+
60
+ def inspect
61
+ "#<Ed25519::VerifyKey:#{to_hex}>"
62
+ end
63
+
64
+ def to_bytes
65
+ @key
66
+ end
67
+ alias_method :to_s, :to_bytes
68
+
69
+ def to_hex
70
+ to_bytes.unpack("H*").first
71
+ end
72
+ end
73
+ end