red25519 1.1.0-jruby

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
+ }
@@ -0,0 +1,27 @@
1
+ require 'java'
2
+
3
+ module Ed25519
4
+ module Engine
5
+ module_function
6
+
7
+ def create_keypair(seed)
8
+ raise ArgumentError, "seed must be 32 bytes long" unless seed.length == 32
9
+
10
+ verify_key = org.red25519.ed25519.publickey(seed.to_java_bytes)
11
+ verify_key = String.from_java_bytes(verify_key)
12
+ [verify_key, seed + verify_key]
13
+ end
14
+
15
+ def sign(signing_key, message)
16
+ verify_key = signing_key[32...64].to_java_bytes
17
+ signing_key = signing_key[0...32].to_java_bytes
18
+
19
+ signature = org.red25519.ed25519.signature(message.to_java_bytes, signing_key, verify_key)
20
+ String.from_java_bytes(signature)
21
+ end
22
+
23
+ def verify(verify_key, signature, message)
24
+ org.red25519.ed25519.checkvalid(signature.to_java_bytes, message.to_java_bytes, verify_key.to_java_bytes)
25
+ end
26
+ end
27
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Ed25519
2
+ VERSION = "1.1.0"
3
+ end
data/lib/red25519.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'red25519/version'
2
+ require 'red25519_engine'
3
+ require 'red25519/keys'
4
+ require 'red25519/jruby_engine' if defined? JRUBY_VERSION
5
+
6
+ module Ed25519
7
+ SECRET_KEY_BYTES = 32
8
+ PUBLIC_KEY_BYTES = 32
9
+ SIGNATURE_BYTES = 64
10
+
11
+ class SelfTestFailure < StandardError; end
12
+
13
+ def self.test
14
+ signature_key = Ed25519::SigningKey.new("A" * 32)
15
+
16
+ unless signature_key.verify_key.to_hex == 'db995fe25169d141cab9bbba92baa01f9f2e1ece7df4cb2ac05190f37fcc1f9d'
17
+ raise SelfTestFailure, "failed to generate verify key correctly"
18
+ end
19
+
20
+ message = "crypto libraries should self-test on boot"
21
+ signature = signature_key.sign(message)
22
+ unless signature.unpack("H*").first == 'c62c12a3a6cbfa04800d4be81468ef8aecd152a6a26a81d91257baecef13ba209531fe905a843e833c8b71cee04400fa2af3a29fef1152ece470421848758d0a'
23
+ raise SelfTestFailure, "failed to generate correct signature"
24
+ end
25
+
26
+ verify_key = signature_key.verify_key
27
+ unless verify_key.verify(signature, message)
28
+ raise SelfTestFailure, "failed to verify a valid signature"
29
+ end
30
+
31
+ bad_signature = signature[0...63] + 'X'
32
+ unless verify_key.verify(bad_signature, message) == false
33
+ raise SelfTestFailure, "failed to detect an invalid signature"
34
+ end
35
+ end
36
+ end
37
+
38
+ Ed25519.test
39
+
40
+ # TIMTOWTDI!!!
41
+ Red25519 = Ed25519
Binary file
data/red25519.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/red25519/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Tony Arcieri"]
6
+ gem.email = ["tony.arcieri@gmail.com"]
7
+ gem.description = "Ruby wrappers for the Ed25519 public key signature system"
8
+ gem.summary = "Red25519 provides both C and Java bindings to the Ed25519 public key signature system"
9
+ gem.homepage = "https://github.com/tarcieri/red25519"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.files << "lib/red25519_engine.jar" if defined? JRUBY_VERSION
13
+
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.name = "red25519"
17
+ gem.require_paths = ["lib"]
18
+ gem.version = Ed25519::VERSION
19
+
20
+ if defined? JRUBY_VERSION
21
+ gem.platform = "jruby"
22
+ else
23
+ gem.extensions = "ext/red25519/extconf.rb"
24
+ end
25
+
26
+ gem.add_runtime_dependency "hkdf"
27
+
28
+ gem.add_development_dependency "rake-compiler"
29
+ gem.add_development_dependency "rake"
30
+ gem.add_development_dependency "rspec"
31
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ed25519::Engine do
4
+ let(:seed_length) { Ed25519::SECRET_KEY_BYTES }
5
+ let(:message) { 'foobar' }
6
+
7
+ it "generates keypairs" do
8
+ ary = Ed25519::Engine.create_keypair("A" * seed_length)
9
+
10
+ ary.length.should eq 2
11
+ pubkey, privkey = ary
12
+
13
+ pubkey.should be_a String
14
+ pubkey.length.should eq Ed25519::PUBLIC_KEY_BYTES
15
+
16
+ privkey.should be_a String
17
+ privkey.length.should eq Ed25519::SECRET_KEY_BYTES * 2
18
+ end
19
+
20
+ it "raises ArgumentError if the seed is not #{Ed25519::SECRET_KEY_BYTES} bytes long" do
21
+ expect { Ed25519::Engine.create_keypair("A" * (seed_length - 1)) }.to raise_exception ArgumentError
22
+ expect { Ed25519::Engine.create_keypair("A" * (seed_length + 1)) }.to raise_exception ArgumentError
23
+ end
24
+
25
+ it "signs and verifies messages" do
26
+ verify_key, signing_key = Ed25519::Engine.create_keypair("A" * seed_length)
27
+ signature = Ed25519::Engine.sign(signing_key, message)
28
+ Ed25519::Engine.verify(verify_key, signature, message).should be_true
29
+
30
+ bad_signature = signature[0...63] + "X"
31
+ Ed25519::Engine.verify(verify_key, bad_signature, message).should be_false
32
+ end
33
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ed25519::SigningKey do
4
+ let(:key) { Ed25519::SigningKey.generate }
5
+ let(:message) { "example message" }
6
+
7
+ it "generates keypairs" do
8
+ key.should be_a Ed25519::SigningKey
9
+ key.verify_key.should be_a Ed25519::VerifyKey
10
+ end
11
+
12
+ it "signs messages" do
13
+ key.sign(message).should be_a String
14
+ end
15
+
16
+ it "serializes to bytes" do
17
+ bytes = key.to_bytes
18
+ bytes.should be_a String
19
+ bytes.length.should eq 32
20
+ end
21
+
22
+ it "serializes to hex" do
23
+ hex = key.to_hex
24
+ hex.should be_a String
25
+ hex.length.should eq 64
26
+ end
27
+
28
+ it "initializes from hex" do
29
+ hex = key.to_hex
30
+ new_key = Ed25519::SigningKey.new(hex)
31
+ key.to_bytes.should == new_key.to_bytes
32
+ end
33
+ end
34
+
35
+ describe Ed25519::VerifyKey do
36
+ let(:signing_key) { Ed25519::SigningKey.generate }
37
+ let(:verify_key) { signing_key.verify_key }
38
+ let(:message) { "example message" }
39
+
40
+ it "verifies messages" do
41
+ signature = signing_key.sign(message)
42
+ verify_key.verify(signature, message).should be_true
43
+
44
+ bad_signature = signature[0...63] + "X"
45
+ verify_key.verify(bad_signature, message).should be_false
46
+ end
47
+
48
+ it "serializes to bytes" do
49
+ bytes = verify_key.to_bytes
50
+ bytes.should be_a String
51
+ bytes.length.should eq 32
52
+ end
53
+
54
+ it "serializes to hex" do
55
+ hex = verify_key.to_hex
56
+ hex.should be_a String
57
+ hex.length.should eq 64
58
+ end
59
+
60
+ it "initializes from hex" do
61
+ hex = verify_key.to_hex
62
+ new_key = Ed25519::VerifyKey.new(hex)
63
+ verify_key.to_bytes.should == new_key.to_bytes
64
+ end
65
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'red25519'
@@ -0,0 +1,12 @@
1
+ if defined? JRUBY_VERSION
2
+ require 'rake/javaextensiontask'
3
+ Rake::JavaExtensionTask.new('red25519_engine') do |ext|
4
+ ext.ext_dir = 'ext/red25519'
5
+ end
6
+ else
7
+ require 'rake/extensiontask'
8
+
9
+ Rake::ExtensionTask.new('red25519_engine') do |ext|
10
+ ext.ext_dir = 'ext/red25519'
11
+ end
12
+ end
data/tasks/rspec.rake ADDED
@@ -0,0 +1,7 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new
4
+
5
+ RSpec::Core::RakeTask.new(:rcov) do |task|
6
+ task.rcov = true
7
+ end