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.
- data/.gitignore +18 -0
- data/.rspec +4 -0
- data/.travis.yml +14 -0
- data/CHANGES.md +3 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +122 -0
- data/Rakefile +9 -0
- data/ext/red25519/api.h +4 -0
- data/ext/red25519/crypto_int32.h +6 -0
- data/ext/red25519/crypto_sign.h +13 -0
- data/ext/red25519/crypto_uint32.h +6 -0
- data/ext/red25519/crypto_verify_32.h +7 -0
- data/ext/red25519/ed25519.c +136 -0
- data/ext/red25519/extconf.rb +4 -0
- data/ext/red25519/fe25519.c +326 -0
- data/ext/red25519/fe25519.h +63 -0
- data/ext/red25519/ge25519.c +311 -0
- data/ext/red25519/ge25519.h +35 -0
- data/ext/red25519/ge25519_base.data +850 -0
- data/ext/red25519/red25519_engine.c +82 -0
- data/ext/red25519/sc25519.c +298 -0
- data/ext/red25519/sc25519.h +73 -0
- data/ext/red25519/sha512-blocks.c +239 -0
- data/ext/red25519/sha512-hash.c +72 -0
- data/ext/red25519/sha512.h +4 -0
- data/ext/red25519/verify.c +40 -0
- data/lib/red25519.rb +40 -0
- data/lib/red25519/keys.rb +73 -0
- data/lib/red25519/version.rb +3 -0
- data/red25519.gemspec +25 -0
- data/spec/red25519/engine_spec.rb +33 -0
- data/spec/red25519/keys_spec.rb +65 -0
- data/spec/spec_helper.rb +3 -0
- data/tasks/extension.rake +5 -0
- data/tasks/rspec.rake +7 -0
- metadata +130 -0
@@ -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,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
|