ruby-chacha20 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|