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
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
|