ruby-chacha20 0.1.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.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +30 -0
- data/ext/chacha20/chacha20-merged.c +201 -0
- data/ext/chacha20/chacha20_bindings.c +99 -0
- data/ext/chacha20/ecrypt-config.h +272 -0
- data/ext/chacha20/ecrypt-machine.h +46 -0
- data/ext/chacha20/ecrypt-portable.h +303 -0
- data/ext/chacha20/ecrypt-sync.h +279 -0
- data/ext/chacha20/extconf.rb +6 -0
- data/lib/chacha20/chacha20.rb +64 -0
- data/lib/ruby-chacha20.rb +2 -0
- metadata +100 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
/* ecrypt-machine.h */
|
2
|
+
|
3
|
+
/*
|
4
|
+
* This file is included by 'ecrypt-portable.h'. It allows to override
|
5
|
+
* the default macros for specific platforms. Please carefully check
|
6
|
+
* the machine code generated by your compiler (with optimisations
|
7
|
+
* turned on) before deciding to edit this file.
|
8
|
+
*/
|
9
|
+
|
10
|
+
/* ------------------------------------------------------------------------- */
|
11
|
+
|
12
|
+
#if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT))
|
13
|
+
|
14
|
+
#define ECRYPT_MACHINE_ROT
|
15
|
+
|
16
|
+
#if (defined(WIN32) && defined(_MSC_VER))
|
17
|
+
|
18
|
+
#undef ROTL32
|
19
|
+
#undef ROTR32
|
20
|
+
#undef ROTL64
|
21
|
+
#undef ROTR64
|
22
|
+
|
23
|
+
#include <stdlib.h>
|
24
|
+
|
25
|
+
#define ROTL32(v, n) _lrotl(v, n)
|
26
|
+
#define ROTR32(v, n) _lrotr(v, n)
|
27
|
+
#define ROTL64(v, n) _rotl64(v, n)
|
28
|
+
#define ROTR64(v, n) _rotr64(v, n)
|
29
|
+
|
30
|
+
#endif
|
31
|
+
|
32
|
+
#endif
|
33
|
+
|
34
|
+
/* ------------------------------------------------------------------------- */
|
35
|
+
|
36
|
+
#if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP))
|
37
|
+
|
38
|
+
#define ECRYPT_MACHINE_SWAP
|
39
|
+
|
40
|
+
/*
|
41
|
+
* If you want to overwrite the default swap macros, put it here. And so on.
|
42
|
+
*/
|
43
|
+
|
44
|
+
#endif
|
45
|
+
|
46
|
+
/* ------------------------------------------------------------------------- */
|
@@ -0,0 +1,303 @@
|
|
1
|
+
/* ecrypt-portable.h */
|
2
|
+
|
3
|
+
/*
|
4
|
+
* WARNING: the conversions defined below are implemented as macros,
|
5
|
+
* and should be used carefully. They should NOT be used with
|
6
|
+
* parameters which perform some action. E.g., the following two lines
|
7
|
+
* are not equivalent:
|
8
|
+
*
|
9
|
+
* 1) ++x; y = ROTL32(x, n);
|
10
|
+
* 2) y = ROTL32(++x, n);
|
11
|
+
*/
|
12
|
+
|
13
|
+
/*
|
14
|
+
* *** Please do not edit this file. ***
|
15
|
+
*
|
16
|
+
* The default macros can be overridden for specific architectures by
|
17
|
+
* editing 'ecrypt-machine.h'.
|
18
|
+
*/
|
19
|
+
|
20
|
+
#ifndef ECRYPT_PORTABLE
|
21
|
+
#define ECRYPT_PORTABLE
|
22
|
+
|
23
|
+
#include "ecrypt-config.h"
|
24
|
+
|
25
|
+
/* ------------------------------------------------------------------------- */
|
26
|
+
|
27
|
+
/*
|
28
|
+
* The following types are defined (if available):
|
29
|
+
*
|
30
|
+
* u8: unsigned integer type, at least 8 bits
|
31
|
+
* u16: unsigned integer type, at least 16 bits
|
32
|
+
* u32: unsigned integer type, at least 32 bits
|
33
|
+
* u64: unsigned integer type, at least 64 bits
|
34
|
+
*
|
35
|
+
* s8, s16, s32, s64 -> signed counterparts of u8, u16, u32, u64
|
36
|
+
*
|
37
|
+
* The selection of minimum-width integer types is taken care of by
|
38
|
+
* 'ecrypt-config.h'. Note: to enable 64-bit types on 32-bit
|
39
|
+
* compilers, it might be necessary to switch from ISO C90 mode to ISO
|
40
|
+
* C99 mode (e.g., gcc -std=c99).
|
41
|
+
*/
|
42
|
+
|
43
|
+
#ifdef I8T
|
44
|
+
typedef signed I8T s8;
|
45
|
+
typedef unsigned I8T u8;
|
46
|
+
#endif
|
47
|
+
|
48
|
+
#ifdef I16T
|
49
|
+
typedef signed I16T s16;
|
50
|
+
typedef unsigned I16T u16;
|
51
|
+
#endif
|
52
|
+
|
53
|
+
#ifdef I32T
|
54
|
+
typedef signed I32T s32;
|
55
|
+
typedef unsigned I32T u32;
|
56
|
+
#endif
|
57
|
+
|
58
|
+
#ifdef I64T
|
59
|
+
typedef signed I64T s64;
|
60
|
+
typedef unsigned I64T u64;
|
61
|
+
#endif
|
62
|
+
|
63
|
+
/*
|
64
|
+
* The following macros are used to obtain exact-width results.
|
65
|
+
*/
|
66
|
+
|
67
|
+
#define U8V(v) ((u8)(v) & U8C(0xFF))
|
68
|
+
#define U16V(v) ((u16)(v) & U16C(0xFFFF))
|
69
|
+
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
|
70
|
+
#define U64V(v) ((u64)(v) & U64C(0xFFFFFFFFFFFFFFFF))
|
71
|
+
|
72
|
+
/* ------------------------------------------------------------------------- */
|
73
|
+
|
74
|
+
/*
|
75
|
+
* The following macros return words with their bits rotated over n
|
76
|
+
* positions to the left/right.
|
77
|
+
*/
|
78
|
+
|
79
|
+
#define ECRYPT_DEFAULT_ROT
|
80
|
+
|
81
|
+
#define ROTL8(v, n) \
|
82
|
+
(U8V((v) << (n)) | ((v) >> (8 - (n))))
|
83
|
+
|
84
|
+
#define ROTL16(v, n) \
|
85
|
+
(U16V((v) << (n)) | ((v) >> (16 - (n))))
|
86
|
+
|
87
|
+
#define ROTL32(v, n) \
|
88
|
+
(U32V((v) << (n)) | ((v) >> (32 - (n))))
|
89
|
+
|
90
|
+
#define ROTL64(v, n) \
|
91
|
+
(U64V((v) << (n)) | ((v) >> (64 - (n))))
|
92
|
+
|
93
|
+
#define ROTR8(v, n) ROTL8(v, 8 - (n))
|
94
|
+
#define ROTR16(v, n) ROTL16(v, 16 - (n))
|
95
|
+
#define ROTR32(v, n) ROTL32(v, 32 - (n))
|
96
|
+
#define ROTR64(v, n) ROTL64(v, 64 - (n))
|
97
|
+
|
98
|
+
#include "ecrypt-machine.h"
|
99
|
+
|
100
|
+
/* ------------------------------------------------------------------------- */
|
101
|
+
|
102
|
+
/*
|
103
|
+
* The following macros return a word with bytes in reverse order.
|
104
|
+
*/
|
105
|
+
|
106
|
+
#define ECRYPT_DEFAULT_SWAP
|
107
|
+
|
108
|
+
#define SWAP16(v) \
|
109
|
+
ROTL16(v, 8)
|
110
|
+
|
111
|
+
#define SWAP32(v) \
|
112
|
+
((ROTL32(v, 8) & U32C(0x00FF00FF)) | \
|
113
|
+
(ROTL32(v, 24) & U32C(0xFF00FF00)))
|
114
|
+
|
115
|
+
#ifdef ECRYPT_NATIVE64
|
116
|
+
#define SWAP64(v) \
|
117
|
+
((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | \
|
118
|
+
(ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \
|
119
|
+
(ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | \
|
120
|
+
(ROTL64(v, 56) & U64C(0xFF000000FF000000)))
|
121
|
+
#else
|
122
|
+
#define SWAP64(v) \
|
123
|
+
(((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32)))
|
124
|
+
#endif
|
125
|
+
|
126
|
+
#include "ecrypt-machine.h"
|
127
|
+
|
128
|
+
#define ECRYPT_DEFAULT_WTOW
|
129
|
+
|
130
|
+
#ifdef ECRYPT_LITTLE_ENDIAN
|
131
|
+
#define U16TO16_LITTLE(v) (v)
|
132
|
+
#define U32TO32_LITTLE(v) (v)
|
133
|
+
#define U64TO64_LITTLE(v) (v)
|
134
|
+
|
135
|
+
#define U16TO16_BIG(v) SWAP16(v)
|
136
|
+
#define U32TO32_BIG(v) SWAP32(v)
|
137
|
+
#define U64TO64_BIG(v) SWAP64(v)
|
138
|
+
#endif
|
139
|
+
|
140
|
+
#ifdef ECRYPT_BIG_ENDIAN
|
141
|
+
#define U16TO16_LITTLE(v) SWAP16(v)
|
142
|
+
#define U32TO32_LITTLE(v) SWAP32(v)
|
143
|
+
#define U64TO64_LITTLE(v) SWAP64(v)
|
144
|
+
|
145
|
+
#define U16TO16_BIG(v) (v)
|
146
|
+
#define U32TO32_BIG(v) (v)
|
147
|
+
#define U64TO64_BIG(v) (v)
|
148
|
+
#endif
|
149
|
+
|
150
|
+
#include "ecrypt-machine.h"
|
151
|
+
|
152
|
+
/*
|
153
|
+
* The following macros load words from an array of bytes with
|
154
|
+
* different types of endianness, and vice versa.
|
155
|
+
*/
|
156
|
+
|
157
|
+
#define ECRYPT_DEFAULT_BTOW
|
158
|
+
|
159
|
+
#if (!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE))
|
160
|
+
|
161
|
+
#define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0])
|
162
|
+
#define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0])
|
163
|
+
#define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0])
|
164
|
+
|
165
|
+
#define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0])
|
166
|
+
#define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0])
|
167
|
+
#define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0])
|
168
|
+
|
169
|
+
#define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v))
|
170
|
+
#define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v))
|
171
|
+
#define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v))
|
172
|
+
|
173
|
+
#define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v))
|
174
|
+
#define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v))
|
175
|
+
#define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v))
|
176
|
+
|
177
|
+
#else
|
178
|
+
|
179
|
+
#define U8TO16_LITTLE(p) \
|
180
|
+
(((u16)((p)[0]) ) | \
|
181
|
+
((u16)((p)[1]) << 8))
|
182
|
+
|
183
|
+
#define U8TO32_LITTLE(p) \
|
184
|
+
(((u32)((p)[0]) ) | \
|
185
|
+
((u32)((p)[1]) << 8) | \
|
186
|
+
((u32)((p)[2]) << 16) | \
|
187
|
+
((u32)((p)[3]) << 24))
|
188
|
+
|
189
|
+
#ifdef ECRYPT_NATIVE64
|
190
|
+
#define U8TO64_LITTLE(p) \
|
191
|
+
(((u64)((p)[0]) ) | \
|
192
|
+
((u64)((p)[1]) << 8) | \
|
193
|
+
((u64)((p)[2]) << 16) | \
|
194
|
+
((u64)((p)[3]) << 24) | \
|
195
|
+
((u64)((p)[4]) << 32) | \
|
196
|
+
((u64)((p)[5]) << 40) | \
|
197
|
+
((u64)((p)[6]) << 48) | \
|
198
|
+
((u64)((p)[7]) << 56))
|
199
|
+
#else
|
200
|
+
#define U8TO64_LITTLE(p) \
|
201
|
+
((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32))
|
202
|
+
#endif
|
203
|
+
|
204
|
+
#define U8TO16_BIG(p) \
|
205
|
+
(((u16)((p)[0]) << 8) | \
|
206
|
+
((u16)((p)[1]) ))
|
207
|
+
|
208
|
+
#define U8TO32_BIG(p) \
|
209
|
+
(((u32)((p)[0]) << 24) | \
|
210
|
+
((u32)((p)[1]) << 16) | \
|
211
|
+
((u32)((p)[2]) << 8) | \
|
212
|
+
((u32)((p)[3]) ))
|
213
|
+
|
214
|
+
#ifdef ECRYPT_NATIVE64
|
215
|
+
#define U8TO64_BIG(p) \
|
216
|
+
(((u64)((p)[0]) << 56) | \
|
217
|
+
((u64)((p)[1]) << 48) | \
|
218
|
+
((u64)((p)[2]) << 40) | \
|
219
|
+
((u64)((p)[3]) << 32) | \
|
220
|
+
((u64)((p)[4]) << 24) | \
|
221
|
+
((u64)((p)[5]) << 16) | \
|
222
|
+
((u64)((p)[6]) << 8) | \
|
223
|
+
((u64)((p)[7]) ))
|
224
|
+
#else
|
225
|
+
#define U8TO64_BIG(p) \
|
226
|
+
(((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4))
|
227
|
+
#endif
|
228
|
+
|
229
|
+
#define U16TO8_LITTLE(p, v) \
|
230
|
+
do { \
|
231
|
+
(p)[0] = U8V((v) ); \
|
232
|
+
(p)[1] = U8V((v) >> 8); \
|
233
|
+
} while (0)
|
234
|
+
|
235
|
+
#define U32TO8_LITTLE(p, v) \
|
236
|
+
do { \
|
237
|
+
(p)[0] = U8V((v) ); \
|
238
|
+
(p)[1] = U8V((v) >> 8); \
|
239
|
+
(p)[2] = U8V((v) >> 16); \
|
240
|
+
(p)[3] = U8V((v) >> 24); \
|
241
|
+
} while (0)
|
242
|
+
|
243
|
+
#ifdef ECRYPT_NATIVE64
|
244
|
+
#define U64TO8_LITTLE(p, v) \
|
245
|
+
do { \
|
246
|
+
(p)[0] = U8V((v) ); \
|
247
|
+
(p)[1] = U8V((v) >> 8); \
|
248
|
+
(p)[2] = U8V((v) >> 16); \
|
249
|
+
(p)[3] = U8V((v) >> 24); \
|
250
|
+
(p)[4] = U8V((v) >> 32); \
|
251
|
+
(p)[5] = U8V((v) >> 40); \
|
252
|
+
(p)[6] = U8V((v) >> 48); \
|
253
|
+
(p)[7] = U8V((v) >> 56); \
|
254
|
+
} while (0)
|
255
|
+
#else
|
256
|
+
#define U64TO8_LITTLE(p, v) \
|
257
|
+
do { \
|
258
|
+
U32TO8_LITTLE((p), U32V((v) )); \
|
259
|
+
U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \
|
260
|
+
} while (0)
|
261
|
+
#endif
|
262
|
+
|
263
|
+
#define U16TO8_BIG(p, v) \
|
264
|
+
do { \
|
265
|
+
(p)[0] = U8V((v) ); \
|
266
|
+
(p)[1] = U8V((v) >> 8); \
|
267
|
+
} while (0)
|
268
|
+
|
269
|
+
#define U32TO8_BIG(p, v) \
|
270
|
+
do { \
|
271
|
+
(p)[0] = U8V((v) >> 24); \
|
272
|
+
(p)[1] = U8V((v) >> 16); \
|
273
|
+
(p)[2] = U8V((v) >> 8); \
|
274
|
+
(p)[3] = U8V((v) ); \
|
275
|
+
} while (0)
|
276
|
+
|
277
|
+
#ifdef ECRYPT_NATIVE64
|
278
|
+
#define U64TO8_BIG(p, v) \
|
279
|
+
do { \
|
280
|
+
(p)[0] = U8V((v) >> 56); \
|
281
|
+
(p)[1] = U8V((v) >> 48); \
|
282
|
+
(p)[2] = U8V((v) >> 40); \
|
283
|
+
(p)[3] = U8V((v) >> 32); \
|
284
|
+
(p)[4] = U8V((v) >> 24); \
|
285
|
+
(p)[5] = U8V((v) >> 16); \
|
286
|
+
(p)[6] = U8V((v) >> 8); \
|
287
|
+
(p)[7] = U8V((v) ); \
|
288
|
+
} while (0)
|
289
|
+
#else
|
290
|
+
#define U64TO8_BIG(p, v) \
|
291
|
+
do { \
|
292
|
+
U32TO8_BIG((p), U32V((v) >> 32)); \
|
293
|
+
U32TO8_BIG((p) + 4, U32V((v) )); \
|
294
|
+
} while (0)
|
295
|
+
#endif
|
296
|
+
|
297
|
+
#endif
|
298
|
+
|
299
|
+
#include "ecrypt-machine.h"
|
300
|
+
|
301
|
+
/* ------------------------------------------------------------------------- */
|
302
|
+
|
303
|
+
#endif
|
@@ -0,0 +1,279 @@
|
|
1
|
+
/* ecrypt-sync.h */
|
2
|
+
|
3
|
+
/*
|
4
|
+
* Header file for synchronous stream ciphers without authentication
|
5
|
+
* mechanism.
|
6
|
+
*
|
7
|
+
* *** Please only edit parts marked with "[edit]". ***
|
8
|
+
*/
|
9
|
+
|
10
|
+
#ifndef ECRYPT_SYNC
|
11
|
+
#define ECRYPT_SYNC
|
12
|
+
|
13
|
+
#include "ecrypt-portable.h"
|
14
|
+
|
15
|
+
/* ------------------------------------------------------------------------- */
|
16
|
+
|
17
|
+
/* Cipher parameters */
|
18
|
+
|
19
|
+
/*
|
20
|
+
* The name of your cipher.
|
21
|
+
*/
|
22
|
+
#define ECRYPT_NAME "ChaCha8"
|
23
|
+
#define ECRYPT_PROFILE "_____"
|
24
|
+
|
25
|
+
/*
|
26
|
+
* Specify which key and IV sizes are supported by your cipher. A user
|
27
|
+
* should be able to enumerate the supported sizes by running the
|
28
|
+
* following code:
|
29
|
+
*
|
30
|
+
* for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i)
|
31
|
+
* {
|
32
|
+
* keysize = ECRYPT_KEYSIZE(i);
|
33
|
+
*
|
34
|
+
* ...
|
35
|
+
* }
|
36
|
+
*
|
37
|
+
* All sizes are in bits.
|
38
|
+
*/
|
39
|
+
|
40
|
+
#define ECRYPT_MAXKEYSIZE 256 /* [edit] */
|
41
|
+
#define ECRYPT_KEYSIZE(i) (128 + (i)*128) /* [edit] */
|
42
|
+
|
43
|
+
#define ECRYPT_MAXIVSIZE 64 /* [edit] */
|
44
|
+
#define ECRYPT_IVSIZE(i) (64 + (i)*64) /* [edit] */
|
45
|
+
|
46
|
+
/* ------------------------------------------------------------------------- */
|
47
|
+
|
48
|
+
/* Data structures */
|
49
|
+
|
50
|
+
/*
|
51
|
+
* ECRYPT_ctx is the structure containing the representation of the
|
52
|
+
* internal state of your cipher.
|
53
|
+
*/
|
54
|
+
|
55
|
+
typedef struct
|
56
|
+
{
|
57
|
+
u32 input[16]; /* could be compressed */
|
58
|
+
/*
|
59
|
+
* [edit]
|
60
|
+
*
|
61
|
+
* Put here all state variable needed during the encryption process.
|
62
|
+
*/
|
63
|
+
} ECRYPT_ctx;
|
64
|
+
|
65
|
+
/* ------------------------------------------------------------------------- */
|
66
|
+
|
67
|
+
/* Mandatory functions */
|
68
|
+
|
69
|
+
/*
|
70
|
+
* Key and message independent initialization. This function will be
|
71
|
+
* called once when the program starts (e.g., to build expanded S-box
|
72
|
+
* tables).
|
73
|
+
*/
|
74
|
+
void ECRYPT_init();
|
75
|
+
|
76
|
+
/*
|
77
|
+
* Key setup. It is the user's responsibility to select the values of
|
78
|
+
* keysize and ivsize from the set of supported values specified
|
79
|
+
* above.
|
80
|
+
*/
|
81
|
+
void ECRYPT_keysetup(
|
82
|
+
ECRYPT_ctx* ctx,
|
83
|
+
const u8* key,
|
84
|
+
u32 keysize, /* Key size in bits. */
|
85
|
+
u32 ivsize); /* IV size in bits. */
|
86
|
+
|
87
|
+
/*
|
88
|
+
* IV setup. After having called ECRYPT_keysetup(), the user is
|
89
|
+
* allowed to call ECRYPT_ivsetup() different times in order to
|
90
|
+
* encrypt/decrypt different messages with the same key but different
|
91
|
+
* IV's.
|
92
|
+
*/
|
93
|
+
void ECRYPT_ivsetup(
|
94
|
+
ECRYPT_ctx* ctx,
|
95
|
+
const u8* iv);
|
96
|
+
|
97
|
+
/*
|
98
|
+
* Encryption/decryption of arbitrary length messages.
|
99
|
+
*
|
100
|
+
* For efficiency reasons, the API provides two types of
|
101
|
+
* encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function
|
102
|
+
* (declared here) encrypts byte strings of arbitrary length, while
|
103
|
+
* the ECRYPT_encrypt_blocks() function (defined later) only accepts
|
104
|
+
* lengths which are multiples of ECRYPT_BLOCKLENGTH.
|
105
|
+
*
|
106
|
+
* The user is allowed to make multiple calls to
|
107
|
+
* ECRYPT_encrypt_blocks() to incrementally encrypt a long message,
|
108
|
+
* but he is NOT allowed to make additional encryption calls once he
|
109
|
+
* has called ECRYPT_encrypt_bytes() (unless he starts a new message
|
110
|
+
* of course). For example, this sequence of calls is acceptable:
|
111
|
+
*
|
112
|
+
* ECRYPT_keysetup();
|
113
|
+
*
|
114
|
+
* ECRYPT_ivsetup();
|
115
|
+
* ECRYPT_encrypt_blocks();
|
116
|
+
* ECRYPT_encrypt_blocks();
|
117
|
+
* ECRYPT_encrypt_bytes();
|
118
|
+
*
|
119
|
+
* ECRYPT_ivsetup();
|
120
|
+
* ECRYPT_encrypt_blocks();
|
121
|
+
* ECRYPT_encrypt_blocks();
|
122
|
+
*
|
123
|
+
* ECRYPT_ivsetup();
|
124
|
+
* ECRYPT_encrypt_bytes();
|
125
|
+
*
|
126
|
+
* The following sequence is not:
|
127
|
+
*
|
128
|
+
* ECRYPT_keysetup();
|
129
|
+
* ECRYPT_ivsetup();
|
130
|
+
* ECRYPT_encrypt_blocks();
|
131
|
+
* ECRYPT_encrypt_bytes();
|
132
|
+
* ECRYPT_encrypt_blocks();
|
133
|
+
*/
|
134
|
+
|
135
|
+
void ECRYPT_encrypt_bytes(
|
136
|
+
ECRYPT_ctx* ctx,
|
137
|
+
const u8* plaintext,
|
138
|
+
u8* ciphertext,
|
139
|
+
u32 msglen); /* Message length in bytes. */
|
140
|
+
|
141
|
+
void ECRYPT_decrypt_bytes(
|
142
|
+
ECRYPT_ctx* ctx,
|
143
|
+
const u8* ciphertext,
|
144
|
+
u8* plaintext,
|
145
|
+
u32 msglen); /* Message length in bytes. */
|
146
|
+
|
147
|
+
/* ------------------------------------------------------------------------- */
|
148
|
+
|
149
|
+
/* Optional features */
|
150
|
+
|
151
|
+
/*
|
152
|
+
* For testing purposes it can sometimes be useful to have a function
|
153
|
+
* which immediately generates keystream without having to provide it
|
154
|
+
* with a zero plaintext. If your cipher cannot provide this function
|
155
|
+
* (e.g., because it is not strictly a synchronous cipher), please
|
156
|
+
* reset the ECRYPT_GENERATES_KEYSTREAM flag.
|
157
|
+
*/
|
158
|
+
|
159
|
+
#define ECRYPT_GENERATES_KEYSTREAM
|
160
|
+
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
161
|
+
|
162
|
+
void ECRYPT_keystream_bytes(
|
163
|
+
ECRYPT_ctx* ctx,
|
164
|
+
u8* keystream,
|
165
|
+
u32 length); /* Length of keystream in bytes. */
|
166
|
+
|
167
|
+
#endif
|
168
|
+
|
169
|
+
/* ------------------------------------------------------------------------- */
|
170
|
+
|
171
|
+
/* Optional optimizations */
|
172
|
+
|
173
|
+
/*
|
174
|
+
* By default, the functions in this section are implemented using
|
175
|
+
* calls to functions declared above. However, you might want to
|
176
|
+
* implement them differently for performance reasons.
|
177
|
+
*/
|
178
|
+
|
179
|
+
/*
|
180
|
+
* All-in-one encryption/decryption of (short) packets.
|
181
|
+
*
|
182
|
+
* The default definitions of these functions can be found in
|
183
|
+
* "ecrypt-sync.c". If you want to implement them differently, please
|
184
|
+
* undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag.
|
185
|
+
*/
|
186
|
+
#define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */
|
187
|
+
|
188
|
+
void ECRYPT_encrypt_packet(
|
189
|
+
ECRYPT_ctx* ctx,
|
190
|
+
const u8* iv,
|
191
|
+
const u8* plaintext,
|
192
|
+
u8* ciphertext,
|
193
|
+
u32 msglen);
|
194
|
+
|
195
|
+
void ECRYPT_decrypt_packet(
|
196
|
+
ECRYPT_ctx* ctx,
|
197
|
+
const u8* iv,
|
198
|
+
const u8* ciphertext,
|
199
|
+
u8* plaintext,
|
200
|
+
u32 msglen);
|
201
|
+
|
202
|
+
/*
|
203
|
+
* Encryption/decryption of blocks.
|
204
|
+
*
|
205
|
+
* By default, these functions are defined as macros. If you want to
|
206
|
+
* provide a different implementation, please undef the
|
207
|
+
* ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions
|
208
|
+
* declared below.
|
209
|
+
*/
|
210
|
+
|
211
|
+
#define ECRYPT_BLOCKLENGTH 64 /* [edit] */
|
212
|
+
|
213
|
+
#define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */
|
214
|
+
#ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS
|
215
|
+
|
216
|
+
#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \
|
217
|
+
ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, \
|
218
|
+
(blocks) * ECRYPT_BLOCKLENGTH)
|
219
|
+
|
220
|
+
#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \
|
221
|
+
ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, \
|
222
|
+
(blocks) * ECRYPT_BLOCKLENGTH)
|
223
|
+
|
224
|
+
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
225
|
+
|
226
|
+
#define ECRYPT_keystream_blocks(ctx, keystream, blocks) \
|
227
|
+
ECRYPT_keystream_bytes(ctx, keystream, \
|
228
|
+
(blocks) * ECRYPT_BLOCKLENGTH)
|
229
|
+
|
230
|
+
#endif
|
231
|
+
|
232
|
+
#else
|
233
|
+
|
234
|
+
void ECRYPT_encrypt_blocks(
|
235
|
+
ECRYPT_ctx* ctx,
|
236
|
+
const u8* plaintext,
|
237
|
+
u8* ciphertext,
|
238
|
+
u32 blocks); /* Message length in blocks. */
|
239
|
+
|
240
|
+
void ECRYPT_decrypt_blocks(
|
241
|
+
ECRYPT_ctx* ctx,
|
242
|
+
const u8* ciphertext,
|
243
|
+
u8* plaintext,
|
244
|
+
u32 blocks); /* Message length in blocks. */
|
245
|
+
|
246
|
+
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
247
|
+
|
248
|
+
void ECRYPT_keystream_blocks(
|
249
|
+
ECRYPT_ctx* ctx,
|
250
|
+
const u8* keystream,
|
251
|
+
u32 blocks); /* Keystream length in blocks. */
|
252
|
+
|
253
|
+
#endif
|
254
|
+
|
255
|
+
#endif
|
256
|
+
|
257
|
+
/*
|
258
|
+
* If your cipher can be implemented in different ways, you can use
|
259
|
+
* the ECRYPT_VARIANT parameter to allow the user to choose between
|
260
|
+
* them at compile time (e.g., gcc -DECRYPT_VARIANT=3 ...). Please
|
261
|
+
* only use this possibility if you really think it could make a
|
262
|
+
* significant difference and keep the number of variants
|
263
|
+
* (ECRYPT_MAXVARIANT) as small as possible (definitely not more than
|
264
|
+
* 10). Note also that all variants should have exactly the same
|
265
|
+
* external interface (i.e., the same ECRYPT_BLOCKLENGTH, etc.).
|
266
|
+
*/
|
267
|
+
#define ECRYPT_MAXVARIANT 1 /* [edit] */
|
268
|
+
|
269
|
+
#ifndef ECRYPT_VARIANT
|
270
|
+
#define ECRYPT_VARIANT 1
|
271
|
+
#endif
|
272
|
+
|
273
|
+
#if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT)
|
274
|
+
#error this variant does not exist
|
275
|
+
#endif
|
276
|
+
|
277
|
+
/* ------------------------------------------------------------------------- */
|
278
|
+
|
279
|
+
#endif
|
@@ -0,0 +1,64 @@
|
|
1
|
+
class ChaCha20
|
2
|
+
def initialize(key, nonce = nil)
|
3
|
+
if nonce.nil?
|
4
|
+
@nonce_initialized = false
|
5
|
+
nonce = "\x00".b * 8
|
6
|
+
else
|
7
|
+
@nonce_initialized = true
|
8
|
+
end
|
9
|
+
|
10
|
+
raise TypeError, "key must be a String" unless key.is_a? String
|
11
|
+
raise TypeError, "nonce must be a String" unless nonce.is_a? String
|
12
|
+
|
13
|
+
raise ArgumentError, "key must be 32 bytes" unless key.bytesize == 32
|
14
|
+
raise ArgumentError, "nonce must be 8 bytes" unless nonce.bytesize == 8
|
15
|
+
|
16
|
+
@block_offset = 0
|
17
|
+
|
18
|
+
init_context(key, nonce)
|
19
|
+
end
|
20
|
+
|
21
|
+
def init_nonce(nonce)
|
22
|
+
raise "nonce has already been initialized" if @nonce_initialized
|
23
|
+
raise TypeError, "nonce must be a String" unless nonce.is_a? String
|
24
|
+
raise ArgumentError, "nonce must be 8 bytes" unless nonce.bytesize == 8
|
25
|
+
|
26
|
+
@nonce_initialized = true
|
27
|
+
set_nonce(nonce)
|
28
|
+
end
|
29
|
+
|
30
|
+
def nonce
|
31
|
+
raise "nonce has not been initialized" unless @nonce_initialized
|
32
|
+
get_nonce
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialized?
|
36
|
+
@nonce_initialized
|
37
|
+
end
|
38
|
+
|
39
|
+
def seek(position)
|
40
|
+
raise "nonce has not been initialized" unless @nonce_initialized
|
41
|
+
raise ArgumentError, "position must be a non-negative integer" unless position.is_a?(Integer) && position >= 0
|
42
|
+
|
43
|
+
set_counter(position / 64)
|
44
|
+
@block_offset = position % 64
|
45
|
+
end
|
46
|
+
|
47
|
+
def encrypt(input)
|
48
|
+
raise "nonce has not been initialized" unless @nonce_initialized
|
49
|
+
raise ArgumentError, "plaintext must be a string" unless input.is_a?(String)
|
50
|
+
|
51
|
+
length = input.bytesize
|
52
|
+
|
53
|
+
result = "\x00".b * @block_offset + input
|
54
|
+
result = encrypt_or_decrypt(result)
|
55
|
+
result = result.slice(@block_offset, length)
|
56
|
+
|
57
|
+
@block_offset = (@block_offset + length) % 64
|
58
|
+
set_counter(get_counter - 1) unless @block_offset.zero?
|
59
|
+
|
60
|
+
result
|
61
|
+
end
|
62
|
+
|
63
|
+
alias_method :decrypt, :encrypt
|
64
|
+
end
|