ruby-chacha20 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,6 @@
1
+ require "mkmf"
2
+
3
+ $CFLAGS << " -Wall -funroll-loops"
4
+ $CFLAGS << " -Wextra -O0 -ggdb3" if ENV["DEBUG"]
5
+
6
+ create_makefile("chacha20_bindings")
@@ -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
@@ -0,0 +1,2 @@
1
+ require "chacha20_bindings"
2
+ require_relative "chacha20/chacha20"