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