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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ae76267b5d649d710b44082de368560526d391089b1fc5d2886c28918b03e074
4
+ data.tar.gz: 6c872222bbacc21de3ddbf7cb96128da56017919b0814b75820dbb8d708f2243
5
+ SHA512:
6
+ metadata.gz: d7349ea022faa1f730d22323d7235fdc7c6d565e72ac462a5b06731623b0b0375f963d0510baac2818ec3557231e32046cb1e8a954c07a6d721cde3e1e82c6d5
7
+ data.tar.gz: d0b6984205b4ea31b237686ac722a060b3c02bdc5e8bcb8bda286107a84498e7141ed14b2c109fde841b6126796fd537ab0da1e99494d5b8f3b49406f2f8a5d2
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Alexander Gitter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # ChaCha20
2
+
3
+ A Ruby wrapper for DJBs ChaCha20 implementation (C code in the `/ext` folder). Based off/inspired by
4
+ https://github.com/dubek/salsa20-ruby. Supports arbitrary seeking inside the keystream.
5
+
6
+ **NOTE**: This is not intended to be used in production software. Use for hobby projects only. This Gem does encryption
7
+ only, it does not provide any kind of message authentication or integrity checking.
8
+
9
+ ## Installation
10
+
11
+ For the time being, this is not on rubygems.org. Point your Gemfile to this repository.
12
+
13
+ ## Usage
14
+
15
+ Initialize a new cipher with a 32-byte key and an 8-byte nonce (both bytestrings of class `String`):
16
+
17
+ ```ruby
18
+ cipher = ChaCha20.new(key, nonce)
19
+ ```
20
+
21
+ Alternatively, you can set the nonce at a later point in time:
22
+
23
+ ```ruby
24
+ cipher = ChaCha20.new(key)
25
+ cipher.init_nonce(nonce) # Returns the ChaCha20 object itself
26
+ # It will raise if nonce has already been set
27
+ ```
28
+
29
+ **Warning**: Do not reuse the nonce value, since this will compromise the security of the encryption. If you need to encrypt
30
+ multiple messages, use a different nonce for each message.
31
+
32
+ You can then encrypt or decrypt data with the `encrypt` and `decrypt` methods:
33
+
34
+ ```ruby
35
+ ciphertext = cipher.encrypt(plaintext)
36
+ plaintext = cipher.decrypt(ciphertext)
37
+ ```
38
+
39
+ Note that these methods advance the internal position inside the key stream, so you can keep calling them for chunk-wise
40
+ de-/encryption. If you want to jump to a specific byte-position in the key stream, you can use the `seek` method:
41
+
42
+ ```ruby
43
+ cipher.seek(4711)
44
+ ```
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/extensiontask"
3
+ require "minitest/test_task"
4
+
5
+ Rake::ExtensionTask.new "chacha20_bindings" do |ext|
6
+ ext.ext_dir = "ext/chacha20"
7
+ end
8
+ Minitest::TestTask.create
9
+ task test: :compile
10
+
11
+ task default: :test
12
+
13
+ task benchmark: :compile do
14
+ $LOAD_PATH.unshift File.expand_path("lib", __dir__)
15
+ require "benchmark"
16
+ require "ruby-chacha20"
17
+
18
+ def read_hex(inp)
19
+ [inp.gsub(/\s+/, "")].pack("H*")
20
+ end
21
+
22
+ key = read_hex("0000000000000000000000000000000000000000000000000000000000000000")
23
+ nonce = read_hex("0000000000000000")
24
+ bytesize = 1024 * 1024 * 1024
25
+ puts "Benchmark to encrypt 1 GB of data"
26
+
27
+ Benchmark.bm do |bm|
28
+ bm.report("ChaCha20#encrypt") { ChaCha20.new(key, nonce).encrypt("\x00".b * bytesize) }
29
+ end
30
+ end
@@ -0,0 +1,201 @@
1
+ /*
2
+ chacha-merged.c version 20080118
3
+ D. J. Bernstein
4
+ Public domain.
5
+ */
6
+
7
+ #include "ecrypt-sync.h"
8
+
9
+ #define ROTATE(v,c) (ROTL32(v,c))
10
+ #define XOR(v,w) ((v) ^ (w))
11
+ #define PLUS(v,w) (U32V((v) + (w)))
12
+ #define PLUSONE(v) (PLUS((v),1))
13
+
14
+ #define QUARTERROUND(a,b,c,d) \
15
+ a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
16
+ c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
17
+ a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
18
+ c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
19
+
20
+ void ECRYPT_init(void)
21
+ {
22
+ return;
23
+ }
24
+
25
+ static const char sigma[16] = "expand 32-byte k";
26
+ static const char tau[16] = "expand 16-byte k";
27
+
28
+ void ECRYPT_keysetup(ECRYPT_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
29
+ {
30
+ const char *constants;
31
+
32
+ x->input[4] = U8TO32_LITTLE(k + 0);
33
+ x->input[5] = U8TO32_LITTLE(k + 4);
34
+ x->input[6] = U8TO32_LITTLE(k + 8);
35
+ x->input[7] = U8TO32_LITTLE(k + 12);
36
+ if (kbits == 256) { /* recommended */
37
+ k += 16;
38
+ constants = sigma;
39
+ } else { /* kbits == 128 */
40
+ constants = tau;
41
+ }
42
+ x->input[8] = U8TO32_LITTLE(k + 0);
43
+ x->input[9] = U8TO32_LITTLE(k + 4);
44
+ x->input[10] = U8TO32_LITTLE(k + 8);
45
+ x->input[11] = U8TO32_LITTLE(k + 12);
46
+ x->input[0] = U8TO32_LITTLE(constants + 0);
47
+ x->input[1] = U8TO32_LITTLE(constants + 4);
48
+ x->input[2] = U8TO32_LITTLE(constants + 8);
49
+ x->input[3] = U8TO32_LITTLE(constants + 12);
50
+ }
51
+
52
+ void ECRYPT_ivsetup(ECRYPT_ctx *x,const u8 *iv)
53
+ {
54
+ x->input[12] = 0;
55
+ x->input[13] = 0;
56
+ x->input[14] = U8TO32_LITTLE(iv + 0);
57
+ x->input[15] = U8TO32_LITTLE(iv + 4);
58
+ }
59
+
60
+ void ECRYPT_encrypt_bytes(ECRYPT_ctx *x,const u8 *m,u8 *c,u32 bytes)
61
+ {
62
+ u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
63
+ u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
64
+ u8 *ctarget;
65
+ u8 tmp[64];
66
+ int i;
67
+
68
+ if (!bytes) return;
69
+
70
+ j0 = x->input[0];
71
+ j1 = x->input[1];
72
+ j2 = x->input[2];
73
+ j3 = x->input[3];
74
+ j4 = x->input[4];
75
+ j5 = x->input[5];
76
+ j6 = x->input[6];
77
+ j7 = x->input[7];
78
+ j8 = x->input[8];
79
+ j9 = x->input[9];
80
+ j10 = x->input[10];
81
+ j11 = x->input[11];
82
+ j12 = x->input[12];
83
+ j13 = x->input[13];
84
+ j14 = x->input[14];
85
+ j15 = x->input[15];
86
+
87
+ for (;;) {
88
+ if (bytes < 64) {
89
+ for (i = 0;i < bytes;++i) tmp[i] = m[i];
90
+ m = tmp;
91
+ ctarget = c;
92
+ c = tmp;
93
+ }
94
+ x0 = j0;
95
+ x1 = j1;
96
+ x2 = j2;
97
+ x3 = j3;
98
+ x4 = j4;
99
+ x5 = j5;
100
+ x6 = j6;
101
+ x7 = j7;
102
+ x8 = j8;
103
+ x9 = j9;
104
+ x10 = j10;
105
+ x11 = j11;
106
+ x12 = j12;
107
+ x13 = j13;
108
+ x14 = j14;
109
+ x15 = j15;
110
+ for (i = 20;i > 0;i -= 2) {
111
+ QUARTERROUND( x0, x4, x8,x12)
112
+ QUARTERROUND( x1, x5, x9,x13)
113
+ QUARTERROUND( x2, x6,x10,x14)
114
+ QUARTERROUND( x3, x7,x11,x15)
115
+ QUARTERROUND( x0, x5,x10,x15)
116
+ QUARTERROUND( x1, x6,x11,x12)
117
+ QUARTERROUND( x2, x7, x8,x13)
118
+ QUARTERROUND( x3, x4, x9,x14)
119
+ }
120
+ x0 = PLUS(x0,j0);
121
+ x1 = PLUS(x1,j1);
122
+ x2 = PLUS(x2,j2);
123
+ x3 = PLUS(x3,j3);
124
+ x4 = PLUS(x4,j4);
125
+ x5 = PLUS(x5,j5);
126
+ x6 = PLUS(x6,j6);
127
+ x7 = PLUS(x7,j7);
128
+ x8 = PLUS(x8,j8);
129
+ x9 = PLUS(x9,j9);
130
+ x10 = PLUS(x10,j10);
131
+ x11 = PLUS(x11,j11);
132
+ x12 = PLUS(x12,j12);
133
+ x13 = PLUS(x13,j13);
134
+ x14 = PLUS(x14,j14);
135
+ x15 = PLUS(x15,j15);
136
+
137
+ x0 = XOR(x0,U8TO32_LITTLE(m + 0));
138
+ x1 = XOR(x1,U8TO32_LITTLE(m + 4));
139
+ x2 = XOR(x2,U8TO32_LITTLE(m + 8));
140
+ x3 = XOR(x3,U8TO32_LITTLE(m + 12));
141
+ x4 = XOR(x4,U8TO32_LITTLE(m + 16));
142
+ x5 = XOR(x5,U8TO32_LITTLE(m + 20));
143
+ x6 = XOR(x6,U8TO32_LITTLE(m + 24));
144
+ x7 = XOR(x7,U8TO32_LITTLE(m + 28));
145
+ x8 = XOR(x8,U8TO32_LITTLE(m + 32));
146
+ x9 = XOR(x9,U8TO32_LITTLE(m + 36));
147
+ x10 = XOR(x10,U8TO32_LITTLE(m + 40));
148
+ x11 = XOR(x11,U8TO32_LITTLE(m + 44));
149
+ x12 = XOR(x12,U8TO32_LITTLE(m + 48));
150
+ x13 = XOR(x13,U8TO32_LITTLE(m + 52));
151
+ x14 = XOR(x14,U8TO32_LITTLE(m + 56));
152
+ x15 = XOR(x15,U8TO32_LITTLE(m + 60));
153
+
154
+ j12 = PLUSONE(j12);
155
+ if (!j12) {
156
+ j13 = PLUSONE(j13);
157
+ /* stopping at 2^70 bytes per nonce is user's responsibility */
158
+ }
159
+
160
+ U32TO8_LITTLE(c + 0,x0);
161
+ U32TO8_LITTLE(c + 4,x1);
162
+ U32TO8_LITTLE(c + 8,x2);
163
+ U32TO8_LITTLE(c + 12,x3);
164
+ U32TO8_LITTLE(c + 16,x4);
165
+ U32TO8_LITTLE(c + 20,x5);
166
+ U32TO8_LITTLE(c + 24,x6);
167
+ U32TO8_LITTLE(c + 28,x7);
168
+ U32TO8_LITTLE(c + 32,x8);
169
+ U32TO8_LITTLE(c + 36,x9);
170
+ U32TO8_LITTLE(c + 40,x10);
171
+ U32TO8_LITTLE(c + 44,x11);
172
+ U32TO8_LITTLE(c + 48,x12);
173
+ U32TO8_LITTLE(c + 52,x13);
174
+ U32TO8_LITTLE(c + 56,x14);
175
+ U32TO8_LITTLE(c + 60,x15);
176
+
177
+ if (bytes <= 64) {
178
+ if (bytes < 64) {
179
+ for (i = 0;i < bytes;++i) ctarget[i] = c[i];
180
+ }
181
+ x->input[12] = j12;
182
+ x->input[13] = j13;
183
+ return;
184
+ }
185
+ bytes -= 64;
186
+ c += 64;
187
+ m += 64;
188
+ }
189
+ }
190
+
191
+ void ECRYPT_decrypt_bytes(ECRYPT_ctx *x,const u8 *c,u8 *m,u32 bytes)
192
+ {
193
+ ECRYPT_encrypt_bytes(x,c,m,bytes);
194
+ }
195
+
196
+ void ECRYPT_keystream_bytes(ECRYPT_ctx *x,u8 *stream,u32 bytes)
197
+ {
198
+ u32 i;
199
+ for (i = 0;i < bytes;++i) stream[i] = 0;
200
+ ECRYPT_encrypt_bytes(x,stream,stream,bytes);
201
+ }
@@ -0,0 +1,99 @@
1
+ #include <ruby.h>
2
+ #include "ecrypt-sync.h"
3
+
4
+ static VALUE cChaCha20;
5
+
6
+ static VALUE rb_chacha20_alloc(VALUE klass) {
7
+ VALUE obj;
8
+ ECRYPT_ctx *ctx;
9
+
10
+ obj = Data_Make_Struct(klass, ECRYPT_ctx, 0, 0, ctx);
11
+ return obj;
12
+ }
13
+
14
+ static VALUE rb_chacha20_init_context(VALUE self, VALUE key, VALUE nonce) {
15
+ ECRYPT_ctx *ctx;
16
+
17
+ Check_Type(key, RUBY_T_STRING);
18
+ Check_Type(nonce, RUBY_T_STRING);
19
+
20
+ Data_Get_Struct(self, ECRYPT_ctx, ctx);
21
+
22
+ ECRYPT_keysetup(ctx, (const unsigned char*)RSTRING_PTR(key), (unsigned int)RSTRING_LEN(key) * 8, 64);
23
+ ECRYPT_ivsetup(ctx, (const unsigned char*)RSTRING_PTR(nonce));
24
+
25
+ return self;
26
+ }
27
+
28
+ static VALUE rb_chacha20_set_nonce(VALUE self, VALUE nonce) {
29
+ ECRYPT_ctx *ctx;
30
+
31
+ Check_Type(nonce, RUBY_T_STRING);
32
+
33
+ Data_Get_Struct(self, ECRYPT_ctx, ctx);
34
+
35
+ ECRYPT_ivsetup(ctx, (const unsigned char*)RSTRING_PTR(nonce));
36
+
37
+ return self;
38
+ }
39
+
40
+ static VALUE rb_chacha20_get_nonce(VALUE self) {
41
+ VALUE output;
42
+ ECRYPT_ctx *ctx;
43
+
44
+ Data_Get_Struct(self, ECRYPT_ctx, ctx);
45
+
46
+ output = rb_str_new(0, 8);
47
+ memcpy(RSTRING_PTR(output), &ctx->input[14], 8);
48
+
49
+ return output;
50
+ }
51
+
52
+ static VALUE rb_chacha20_set_counter(VALUE self, VALUE counter) {
53
+ ECRYPT_ctx *ctx;
54
+
55
+ Check_Type(counter, RUBY_T_FIXNUM);
56
+
57
+ Data_Get_Struct(self, ECRYPT_ctx, ctx);
58
+
59
+ unsigned long long counter_ull = NUM2ULL(counter);
60
+ ctx->input[12] = (u32)counter_ull;
61
+ ctx->input[13] = (u32)(counter_ull >> 32);
62
+
63
+ return Qnil;
64
+ }
65
+
66
+ static VALUE rb_chacha20_get_counter(VALUE self) {
67
+ ECRYPT_ctx *ctx;
68
+
69
+ Data_Get_Struct(self, ECRYPT_ctx, ctx);
70
+
71
+ return rb_ull2inum(((unsigned LONG_LONG)(ctx->input[13]) << 32) | (unsigned LONG_LONG)(ctx->input[12]));
72
+ }
73
+
74
+ static VALUE rb_chacha20_encrypt_or_decrypt(VALUE self, VALUE input) {
75
+ VALUE output;
76
+ ECRYPT_ctx *ctx;
77
+
78
+ Check_Type(input, RUBY_T_STRING);
79
+
80
+ Data_Get_Struct(self, ECRYPT_ctx, ctx);
81
+
82
+ output = rb_str_new(0, RSTRING_LEN(input));
83
+ ECRYPT_encrypt_bytes(ctx, (const unsigned char*)RSTRING_PTR(input), (unsigned char*)RSTRING_PTR(output), (unsigned int)RSTRING_LEN(input));
84
+
85
+ return output;
86
+ }
87
+
88
+ void Init_chacha20_bindings() {
89
+ cChaCha20 = rb_define_class("ChaCha20", rb_cObject);
90
+
91
+ rb_define_alloc_func(cChaCha20, rb_chacha20_alloc);
92
+
93
+ rb_define_private_method(cChaCha20, "init_context", rb_chacha20_init_context, 2);
94
+ rb_define_private_method(cChaCha20, "set_nonce", rb_chacha20_set_nonce, 1);
95
+ rb_define_private_method(cChaCha20, "get_nonce", rb_chacha20_get_nonce, 0);
96
+ rb_define_private_method(cChaCha20, "set_counter", rb_chacha20_set_counter, 1);
97
+ rb_define_private_method(cChaCha20, "get_counter", rb_chacha20_get_counter, 0);
98
+ rb_define_private_method(cChaCha20, "encrypt_or_decrypt", rb_chacha20_encrypt_or_decrypt, 1);
99
+ }
@@ -0,0 +1,272 @@
1
+ /* ecrypt-config.h */
2
+
3
+ /* *** Normally, it should not be necessary to edit this file. *** */
4
+
5
+ #ifndef ECRYPT_CONFIG
6
+ #define ECRYPT_CONFIG
7
+
8
+ /* ------------------------------------------------------------------------- */
9
+
10
+ /* Guess the endianness of the target architecture. */
11
+
12
+ /*
13
+ * The LITTLE endian machines:
14
+ */
15
+ #if defined(__ultrix) /* Older MIPS */
16
+ #define ECRYPT_LITTLE_ENDIAN
17
+ #elif defined(__alpha) /* Alpha */
18
+ #define ECRYPT_LITTLE_ENDIAN
19
+ #elif defined(i386) /* x86 (gcc) */
20
+ #define ECRYPT_LITTLE_ENDIAN
21
+ #elif defined(__i386) /* x86 (gcc) */
22
+ #define ECRYPT_LITTLE_ENDIAN
23
+ #elif defined(_M_IX86) /* x86 (MSC, Borland) */
24
+ #define ECRYPT_LITTLE_ENDIAN
25
+ #elif defined(_MSC_VER) /* x86 (surely MSC) */
26
+ #define ECRYPT_LITTLE_ENDIAN
27
+ #elif defined(__INTEL_COMPILER) /* x86 (surely Intel compiler icl.exe) */
28
+ #define ECRYPT_LITTLE_ENDIAN
29
+
30
+ /*
31
+ * The BIG endian machines:
32
+ */
33
+ #elif defined(sun) /* Newer Sparc's */
34
+ #define ECRYPT_BIG_ENDIAN
35
+ #elif defined(__ppc__) /* PowerPC */
36
+ #define ECRYPT_BIG_ENDIAN
37
+
38
+ /*
39
+ * Finally machines with UNKNOWN endianness:
40
+ */
41
+ #elif defined (_AIX) /* RS6000 */
42
+ #define ECRYPT_UNKNOWN
43
+ #elif defined(__hpux) /* HP-PA */
44
+ #define ECRYPT_UNKNOWN
45
+ #elif defined(__aux) /* 68K */
46
+ #define ECRYPT_UNKNOWN
47
+ #elif defined(__dgux) /* 88K (but P6 in latest boxes) */
48
+ #define ECRYPT_UNKNOWN
49
+ #elif defined(__sgi) /* Newer MIPS */
50
+ #define ECRYPT_UNKNOWN
51
+ #else /* Any other processor */
52
+ #define ECRYPT_UNKNOWN
53
+ #endif
54
+
55
+ /* ------------------------------------------------------------------------- */
56
+
57
+ /*
58
+ * Find minimal-width types to store 8-bit, 16-bit, 32-bit, and 64-bit
59
+ * integers.
60
+ *
61
+ * Note: to enable 64-bit types on 32-bit compilers, it might be
62
+ * necessary to switch from ISO C90 mode to ISO C99 mode (e.g., gcc
63
+ * -std=c99).
64
+ */
65
+
66
+ #include <limits.h>
67
+
68
+ /* --- check char --- */
69
+
70
+ #if (UCHAR_MAX / 0xFU > 0xFU)
71
+ #ifndef I8T
72
+ #define I8T char
73
+ #define U8C(v) (v##U)
74
+
75
+ #if (UCHAR_MAX == 0xFFU)
76
+ #define ECRYPT_I8T_IS_BYTE
77
+ #endif
78
+
79
+ #endif
80
+
81
+ #if (UCHAR_MAX / 0xFFU > 0xFFU)
82
+ #ifndef I16T
83
+ #define I16T char
84
+ #define U16C(v) (v##U)
85
+ #endif
86
+
87
+ #if (UCHAR_MAX / 0xFFFFU > 0xFFFFU)
88
+ #ifndef I32T
89
+ #define I32T char
90
+ #define U32C(v) (v##U)
91
+ #endif
92
+
93
+ #if (UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
94
+ #ifndef I64T
95
+ #define I64T char
96
+ #define U64C(v) (v##U)
97
+ #define ECRYPT_NATIVE64
98
+ #endif
99
+
100
+ #endif
101
+ #endif
102
+ #endif
103
+ #endif
104
+
105
+ /* --- check short --- */
106
+
107
+ #if (USHRT_MAX / 0xFU > 0xFU)
108
+ #ifndef I8T
109
+ #define I8T short
110
+ #define U8C(v) (v##U)
111
+
112
+ #if (USHRT_MAX == 0xFFU)
113
+ #define ECRYPT_I8T_IS_BYTE
114
+ #endif
115
+
116
+ #endif
117
+
118
+ #if (USHRT_MAX / 0xFFU > 0xFFU)
119
+ #ifndef I16T
120
+ #define I16T short
121
+ #define U16C(v) (v##U)
122
+ #endif
123
+
124
+ #if (USHRT_MAX / 0xFFFFU > 0xFFFFU)
125
+ #ifndef I32T
126
+ #define I32T short
127
+ #define U32C(v) (v##U)
128
+ #endif
129
+
130
+ #if (USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
131
+ #ifndef I64T
132
+ #define I64T short
133
+ #define U64C(v) (v##U)
134
+ #define ECRYPT_NATIVE64
135
+ #endif
136
+
137
+ #endif
138
+ #endif
139
+ #endif
140
+ #endif
141
+
142
+ /* --- check int --- */
143
+
144
+ #if (UINT_MAX / 0xFU > 0xFU)
145
+ #ifndef I8T
146
+ #define I8T int
147
+ #define U8C(v) (v##U)
148
+
149
+ #if (ULONG_MAX == 0xFFU)
150
+ #define ECRYPT_I8T_IS_BYTE
151
+ #endif
152
+
153
+ #endif
154
+
155
+ #if (UINT_MAX / 0xFFU > 0xFFU)
156
+ #ifndef I16T
157
+ #define I16T int
158
+ #define U16C(v) (v##U)
159
+ #endif
160
+
161
+ #if (UINT_MAX / 0xFFFFU > 0xFFFFU)
162
+ #ifndef I32T
163
+ #define I32T int
164
+ #define U32C(v) (v##U)
165
+ #endif
166
+
167
+ #if (UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
168
+ #ifndef I64T
169
+ #define I64T int
170
+ #define U64C(v) (v##U)
171
+ #define ECRYPT_NATIVE64
172
+ #endif
173
+
174
+ #endif
175
+ #endif
176
+ #endif
177
+ #endif
178
+
179
+ /* --- check long --- */
180
+
181
+ #if (ULONG_MAX / 0xFUL > 0xFUL)
182
+ #ifndef I8T
183
+ #define I8T long
184
+ #define U8C(v) (v##UL)
185
+
186
+ #if (ULONG_MAX == 0xFFUL)
187
+ #define ECRYPT_I8T_IS_BYTE
188
+ #endif
189
+
190
+ #endif
191
+
192
+ #if (ULONG_MAX / 0xFFUL > 0xFFUL)
193
+ #ifndef I16T
194
+ #define I16T long
195
+ #define U16C(v) (v##UL)
196
+ #endif
197
+
198
+ #if (ULONG_MAX / 0xFFFFUL > 0xFFFFUL)
199
+ #ifndef I32T
200
+ #define I32T long
201
+ #define U32C(v) (v##UL)
202
+ #endif
203
+
204
+ #if (ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL)
205
+ #ifndef I64T
206
+ #define I64T long
207
+ #define U64C(v) (v##UL)
208
+ #define ECRYPT_NATIVE64
209
+ #endif
210
+
211
+ #endif
212
+ #endif
213
+ #endif
214
+ #endif
215
+
216
+ /* --- check long long --- */
217
+
218
+ #ifdef ULLONG_MAX
219
+
220
+ #if (ULLONG_MAX / 0xFULL > 0xFULL)
221
+ #ifndef I8T
222
+ #define I8T long long
223
+ #define U8C(v) (v##ULL)
224
+
225
+ #if (ULLONG_MAX == 0xFFULL)
226
+ #define ECRYPT_I8T_IS_BYTE
227
+ #endif
228
+
229
+ #endif
230
+
231
+ #if (ULLONG_MAX / 0xFFULL > 0xFFULL)
232
+ #ifndef I16T
233
+ #define I16T long long
234
+ #define U16C(v) (v##ULL)
235
+ #endif
236
+
237
+ #if (ULLONG_MAX / 0xFFFFULL > 0xFFFFULL)
238
+ #ifndef I32T
239
+ #define I32T long long
240
+ #define U32C(v) (v##ULL)
241
+ #endif
242
+
243
+ #if (ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL)
244
+ #ifndef I64T
245
+ #define I64T long long
246
+ #define U64C(v) (v##ULL)
247
+ #endif
248
+
249
+ #endif
250
+ #endif
251
+ #endif
252
+ #endif
253
+
254
+ #endif
255
+
256
+ /* --- check __int64 --- */
257
+
258
+ #ifdef _UI64_MAX
259
+
260
+ #if (_UI64_MAX / 0xFFFFFFFFui64 > 0xFFFFFFFFui64)
261
+ #ifndef I64T
262
+ #define I64T __int64
263
+ #define U64C(v) (v##ui64)
264
+ #endif
265
+
266
+ #endif
267
+
268
+ #endif
269
+
270
+ /* ------------------------------------------------------------------------- */
271
+
272
+ #endif