ffi-hydrogen 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/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +30 -0
- data/.travis.yml +10 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +72 -0
- data/Rakefile +46 -0
- data/bench/both.rb +86 -0
- data/bench/encode.rb +57 -0
- data/bench/encrypt.rb +80 -0
- data/bench/init.rb +5 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ffi-hydrogen.gemspec +31 -0
- data/lib/ffi/hydrogen.rb +216 -0
- data/vendor/.clang-format +2 -0
- data/vendor/.gitignore +3 -0
- data/vendor/README.md +2 -0
- data/vendor/libhydrogen/.clang-format +95 -0
- data/vendor/libhydrogen/.gitignore +32 -0
- data/vendor/libhydrogen/.travis.yml +22 -0
- data/vendor/libhydrogen/LICENSE +18 -0
- data/vendor/libhydrogen/Makefile +61 -0
- data/vendor/libhydrogen/Makefile.arduino +51 -0
- data/vendor/libhydrogen/README.md +29 -0
- data/vendor/libhydrogen/hydrogen.c +18 -0
- data/vendor/libhydrogen/hydrogen.h +317 -0
- data/vendor/libhydrogen/impl/common.h +316 -0
- data/vendor/libhydrogen/impl/core.h +220 -0
- data/vendor/libhydrogen/impl/gimli-core/portable.h +39 -0
- data/vendor/libhydrogen/impl/gimli-core/sse2.h +97 -0
- data/vendor/libhydrogen/impl/gimli-core.h +25 -0
- data/vendor/libhydrogen/impl/hash.h +138 -0
- data/vendor/libhydrogen/impl/hydrogen_p.h +83 -0
- data/vendor/libhydrogen/impl/kdf.h +20 -0
- data/vendor/libhydrogen/impl/kx.h +441 -0
- data/vendor/libhydrogen/impl/pwhash.h +281 -0
- data/vendor/libhydrogen/impl/random.h +376 -0
- data/vendor/libhydrogen/impl/secretbox.h +236 -0
- data/vendor/libhydrogen/impl/sign.h +207 -0
- data/vendor/libhydrogen/impl/x25519.h +383 -0
- data/vendor/libhydrogen/library.properties +10 -0
- data/vendor/libhydrogen/logo.png +0 -0
- data/vendor/libhydrogen/tests/tests.c +431 -0
- data/vendor/main.c +140 -0
- data/vendor/stringencoders/.gitignore +25 -0
- data/vendor/stringencoders/.travis.yml +13 -0
- data/vendor/stringencoders/AUTHORS +1 -0
- data/vendor/stringencoders/COPYING +2 -0
- data/vendor/stringencoders/ChangeLog +170 -0
- data/vendor/stringencoders/Doxyfile +276 -0
- data/vendor/stringencoders/INSTALL +119 -0
- data/vendor/stringencoders/LICENSE +22 -0
- data/vendor/stringencoders/Makefile.am +3 -0
- data/vendor/stringencoders/NEWS +3 -0
- data/vendor/stringencoders/README +2 -0
- data/vendor/stringencoders/README.md +32 -0
- data/vendor/stringencoders/bootstrap.sh +3 -0
- data/vendor/stringencoders/configure-gcc-hardened.sh +16 -0
- data/vendor/stringencoders/configure.ac +44 -0
- data/vendor/stringencoders/doxy/footer.html +34 -0
- data/vendor/stringencoders/doxy/header.html +85 -0
- data/vendor/stringencoders/indent.sh +9 -0
- data/vendor/stringencoders/javascript/base64-speed.html +43 -0
- data/vendor/stringencoders/javascript/base64-test.html +209 -0
- data/vendor/stringencoders/javascript/base64.html +18 -0
- data/vendor/stringencoders/javascript/base64.js +176 -0
- data/vendor/stringencoders/javascript/qunit.css +119 -0
- data/vendor/stringencoders/javascript/qunit.js +1062 -0
- data/vendor/stringencoders/javascript/urlparse-test.html +367 -0
- data/vendor/stringencoders/javascript/urlparse.js +328 -0
- data/vendor/stringencoders/make-ci.sh +13 -0
- data/vendor/stringencoders/makerelease.sh +16 -0
- data/vendor/stringencoders/python/b85.py +176 -0
- data/vendor/stringencoders/src/Makefile.am +134 -0
- data/vendor/stringencoders/src/arraytoc.c +85 -0
- data/vendor/stringencoders/src/arraytoc.h +43 -0
- data/vendor/stringencoders/src/extern_c_begin.h +3 -0
- data/vendor/stringencoders/src/extern_c_end.h +3 -0
- data/vendor/stringencoders/src/html_named_entities_generator.py +203 -0
- data/vendor/stringencoders/src/modp_ascii.c +159 -0
- data/vendor/stringencoders/src/modp_ascii.h +162 -0
- data/vendor/stringencoders/src/modp_ascii_data.h +84 -0
- data/vendor/stringencoders/src/modp_ascii_gen.c +55 -0
- data/vendor/stringencoders/src/modp_b16.c +125 -0
- data/vendor/stringencoders/src/modp_b16.h +148 -0
- data/vendor/stringencoders/src/modp_b16_data.h +104 -0
- data/vendor/stringencoders/src/modp_b16_gen.c +65 -0
- data/vendor/stringencoders/src/modp_b2.c +69 -0
- data/vendor/stringencoders/src/modp_b2.h +130 -0
- data/vendor/stringencoders/src/modp_b2_data.h +44 -0
- data/vendor/stringencoders/src/modp_b2_gen.c +36 -0
- data/vendor/stringencoders/src/modp_b36.c +108 -0
- data/vendor/stringencoders/src/modp_b36.h +170 -0
- data/vendor/stringencoders/src/modp_b64.c +254 -0
- data/vendor/stringencoders/src/modp_b64.h +236 -0
- data/vendor/stringencoders/src/modp_b64_data.h +477 -0
- data/vendor/stringencoders/src/modp_b64_gen.c +168 -0
- data/vendor/stringencoders/src/modp_b64r.c +254 -0
- data/vendor/stringencoders/src/modp_b64r.h +242 -0
- data/vendor/stringencoders/src/modp_b64r_data.h +477 -0
- data/vendor/stringencoders/src/modp_b64w.c +254 -0
- data/vendor/stringencoders/src/modp_b64w.h +231 -0
- data/vendor/stringencoders/src/modp_b64w_data.h +477 -0
- data/vendor/stringencoders/src/modp_b85.c +109 -0
- data/vendor/stringencoders/src/modp_b85.h +171 -0
- data/vendor/stringencoders/src/modp_b85_data.h +36 -0
- data/vendor/stringencoders/src/modp_b85_gen.c +65 -0
- data/vendor/stringencoders/src/modp_bjavascript.c +65 -0
- data/vendor/stringencoders/src/modp_bjavascript.h +105 -0
- data/vendor/stringencoders/src/modp_bjavascript_data.h +84 -0
- data/vendor/stringencoders/src/modp_bjavascript_gen.c +58 -0
- data/vendor/stringencoders/src/modp_burl.c +228 -0
- data/vendor/stringencoders/src/modp_burl.h +259 -0
- data/vendor/stringencoders/src/modp_burl_data.h +136 -0
- data/vendor/stringencoders/src/modp_burl_gen.c +121 -0
- data/vendor/stringencoders/src/modp_html.c +128 -0
- data/vendor/stringencoders/src/modp_html.h +53 -0
- data/vendor/stringencoders/src/modp_html_named_entities.h +9910 -0
- data/vendor/stringencoders/src/modp_json.c +315 -0
- data/vendor/stringencoders/src/modp_json.h +103 -0
- data/vendor/stringencoders/src/modp_json_data.h +57 -0
- data/vendor/stringencoders/src/modp_json_gen.py +60 -0
- data/vendor/stringencoders/src/modp_mainpage.h +120 -0
- data/vendor/stringencoders/src/modp_numtoa.c +350 -0
- data/vendor/stringencoders/src/modp_numtoa.h +100 -0
- data/vendor/stringencoders/src/modp_qsiter.c +76 -0
- data/vendor/stringencoders/src/modp_qsiter.h +71 -0
- data/vendor/stringencoders/src/modp_stdint.h +43 -0
- data/vendor/stringencoders/src/modp_utf8.c +88 -0
- data/vendor/stringencoders/src/modp_utf8.h +38 -0
- data/vendor/stringencoders/src/modp_xml.c +311 -0
- data/vendor/stringencoders/src/modp_xml.h +166 -0
- data/vendor/stringencoders/src/stringencoders.pc +10 -0
- data/vendor/stringencoders/src/stringencoders.pc.in +10 -0
- data/vendor/stringencoders/test/Makefile.am +113 -0
- data/vendor/stringencoders/test/apr_base64.c +262 -0
- data/vendor/stringencoders/test/apr_base64.h +120 -0
- data/vendor/stringencoders/test/cxx_test.cc +482 -0
- data/vendor/stringencoders/test/minunit.h +82 -0
- data/vendor/stringencoders/test/modp_ascii_test.c +281 -0
- data/vendor/stringencoders/test/modp_b16_test.c +288 -0
- data/vendor/stringencoders/test/modp_b2_test.c +250 -0
- data/vendor/stringencoders/test/modp_b64_test.c +266 -0
- data/vendor/stringencoders/test/modp_b85_test.c +130 -0
- data/vendor/stringencoders/test/modp_bjavascript_test.c +137 -0
- data/vendor/stringencoders/test/modp_burl_test.c +423 -0
- data/vendor/stringencoders/test/modp_html_test.c +296 -0
- data/vendor/stringencoders/test/modp_json_test.c +336 -0
- data/vendor/stringencoders/test/modp_numtoa_test.c +545 -0
- data/vendor/stringencoders/test/modp_qsiter_test.c +280 -0
- data/vendor/stringencoders/test/modp_utf8_test.c +188 -0
- data/vendor/stringencoders/test/modp_xml_test.c +339 -0
- data/vendor/stringencoders/test/speedtest.c +241 -0
- data/vendor/stringencoders/test/speedtest_ascii.c +345 -0
- data/vendor/stringencoders/test/speedtest_msg.c +78 -0
- data/vendor/stringencoders/test/speedtest_numtoa.c +276 -0
- metadata +314 -0
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
#include <assert.h>
|
|
2
|
+
#include <stdio.h>
|
|
3
|
+
#include <string.h>
|
|
4
|
+
|
|
5
|
+
#include "../hydrogen.h"
|
|
6
|
+
|
|
7
|
+
static const char *ctx = "libtests";
|
|
8
|
+
|
|
9
|
+
static int
|
|
10
|
+
streq(const char *expected, const char *found)
|
|
11
|
+
{
|
|
12
|
+
if (strcmp(expected, found) != 0) {
|
|
13
|
+
fprintf(stderr, "Found: [%s]\n", found);
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
return 1;
|
|
17
|
+
}
|
|
18
|
+
#define assert_streq(EXPECTED, FOUND) assert(streq((EXPECTED), (FOUND)))
|
|
19
|
+
|
|
20
|
+
static void
|
|
21
|
+
test_randombytes(void)
|
|
22
|
+
{
|
|
23
|
+
uint8_t dk[hydro_random_SEEDBYTES];
|
|
24
|
+
uint8_t tmp[10000];
|
|
25
|
+
unsigned long b = 0U;
|
|
26
|
+
unsigned long bp;
|
|
27
|
+
uint32_t x;
|
|
28
|
+
size_t i, j;
|
|
29
|
+
|
|
30
|
+
for (i = 0; i < 10000; i++) {
|
|
31
|
+
x = hydro_random_u32();
|
|
32
|
+
for (j = 0; j < sizeof x; j++) {
|
|
33
|
+
b += (x >> j) & 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
assert(b > 18000 && b < 22000);
|
|
37
|
+
|
|
38
|
+
b = 0;
|
|
39
|
+
hydro_random_buf(tmp, sizeof tmp);
|
|
40
|
+
for (i = 0; i < 10000; i++) {
|
|
41
|
+
for (j = 0; j < sizeof tmp[0]; j++) {
|
|
42
|
+
b += (tmp[i] >> j) & 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
assert(b > 4500 && b < 5500);
|
|
46
|
+
|
|
47
|
+
memcpy(dk, tmp, sizeof dk);
|
|
48
|
+
b = 0;
|
|
49
|
+
hydro_random_buf_deterministic(tmp, 10000, dk);
|
|
50
|
+
for (i = 0; i < 10000; i++) {
|
|
51
|
+
for (j = 0; j < sizeof tmp[0]; j++) {
|
|
52
|
+
b += (tmp[i] >> j) & 1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
assert(b > 4500 && b < 5500);
|
|
56
|
+
bp = b;
|
|
57
|
+
b = 0;
|
|
58
|
+
hydro_random_buf_deterministic(tmp, 10000, dk);
|
|
59
|
+
for (i = 0; i < 10000; i++) {
|
|
60
|
+
for (j = 0; j < sizeof tmp[0]; j++) {
|
|
61
|
+
b += (tmp[i] >> j) & 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
assert(b == bp);
|
|
65
|
+
|
|
66
|
+
for (i = 0; i < 1000; i++) {
|
|
67
|
+
for (j = 1; j < 100; j++) {
|
|
68
|
+
x = hydro_random_uniform((uint32_t) j);
|
|
69
|
+
assert(x < j);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static void
|
|
75
|
+
test_hash(void)
|
|
76
|
+
{
|
|
77
|
+
hydro_hash_state st;
|
|
78
|
+
uint8_t dk[hydro_random_SEEDBYTES];
|
|
79
|
+
uint8_t h[100];
|
|
80
|
+
uint8_t key[hydro_hash_KEYBYTES];
|
|
81
|
+
uint8_t msg[1000];
|
|
82
|
+
char hex[100 * 2 + 1];
|
|
83
|
+
size_t i;
|
|
84
|
+
|
|
85
|
+
memset(dk, 0, sizeof dk);
|
|
86
|
+
hydro_random_buf_deterministic(key, sizeof key, dk);
|
|
87
|
+
hydro_increment(dk, sizeof dk);
|
|
88
|
+
hydro_hash_init(&st, ctx, key);
|
|
89
|
+
for (i = 0; i <= sizeof msg; i++) {
|
|
90
|
+
hydro_random_buf_deterministic(msg, i, dk);
|
|
91
|
+
hydro_increment(dk, sizeof dk);
|
|
92
|
+
hydro_hash_update(&st, msg, i);
|
|
93
|
+
}
|
|
94
|
+
hydro_hash_final(&st, h, sizeof h);
|
|
95
|
+
hydro_bin2hex(hex, sizeof hex, h, sizeof h);
|
|
96
|
+
assert_streq(
|
|
97
|
+
"e5d2beb77a039965850ee76327e06b2fa6cb5121db8038b11bce4641a9c4bd843658104bdf07342570bb5fd1d7"
|
|
98
|
+
"2c0d31a8981b47c718fddaffbd4171605c873cbaf921bb57988dd814f3a3fbef9799ff7c762705c4bf37ab2981"
|
|
99
|
+
"5981bf0d8833d60afe14",
|
|
100
|
+
hex);
|
|
101
|
+
hydro_hash_hash(h, sizeof h, msg, sizeof msg, ctx, key);
|
|
102
|
+
hydro_bin2hex(hex, sizeof hex, h, sizeof h);
|
|
103
|
+
assert_streq(
|
|
104
|
+
"724bd8883df73320ffd70923cb997f9a99bc670c4d78887be4975add0099fbf489b266a85d1f56743062d60a05"
|
|
105
|
+
"590cbce47e45108367879bf4641cbaefe584e8618cbeb8c230ae956da22c7c5c4f11a8804ca576ec20fa5da239"
|
|
106
|
+
"dde3d03a6018383c21f5",
|
|
107
|
+
hex);
|
|
108
|
+
hydro_hash_hash(h, hydro_hash_BYTES, msg, sizeof msg, ctx, key);
|
|
109
|
+
hydro_bin2hex(hex, sizeof hex, h, hydro_hash_BYTES);
|
|
110
|
+
assert_streq("7dfa45ce18210e2422fd658bf7beccb6e534e44f99ae359f4af3ba41af8ca463", hex);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static void
|
|
114
|
+
test_core(void)
|
|
115
|
+
{
|
|
116
|
+
uint8_t x[100];
|
|
117
|
+
uint8_t y[100];
|
|
118
|
+
uint8_t a[5] = { 1, 2, 3, 4, 5 };
|
|
119
|
+
uint8_t b[5] = { 1, 2, 3, 4, 5 };
|
|
120
|
+
char hex[201];
|
|
121
|
+
const char *hexf;
|
|
122
|
+
|
|
123
|
+
memset(x, 0xd0, sizeof x);
|
|
124
|
+
hydro_memzero(x, sizeof x);
|
|
125
|
+
assert(x[0] == 0);
|
|
126
|
+
assert(x[sizeof x - 1] == 0);
|
|
127
|
+
hydro_increment(x, sizeof x);
|
|
128
|
+
assert(x[0] == 1);
|
|
129
|
+
assert(x[sizeof x - 1] == 0);
|
|
130
|
+
x[0] = 0xff;
|
|
131
|
+
hydro_increment(x, sizeof x);
|
|
132
|
+
assert(x[0] == 0);
|
|
133
|
+
assert(x[1] == 1);
|
|
134
|
+
assert(x[sizeof x - 1] == 0);
|
|
135
|
+
assert(hydro_equal(a, b, sizeof a));
|
|
136
|
+
assert(!hydro_equal(a, a, sizeof a));
|
|
137
|
+
assert(hydro_compare(a, b, sizeof a) == 0);
|
|
138
|
+
assert(hydro_compare(a, a, sizeof a) == 0);
|
|
139
|
+
a[0]++;
|
|
140
|
+
assert(hydro_compare(a, b, sizeof a) == 1);
|
|
141
|
+
assert(hydro_compare(b, a, sizeof a) == -1);
|
|
142
|
+
hydro_random_buf(x, sizeof x);
|
|
143
|
+
assert(hydro_bin2hex(hex, sizeof hex, x, sizeof x) != NULL);
|
|
144
|
+
assert(hydro_hex2bin(y, 1, hex, sizeof hex, NULL, NULL) == -1);
|
|
145
|
+
assert(hydro_hex2bin(y, sizeof y, hex, sizeof hex, NULL, NULL) == -1);
|
|
146
|
+
assert(hydro_hex2bin(y, sizeof y, hex, sizeof hex - 1, NULL, NULL) == sizeof x);
|
|
147
|
+
assert(hydro_equal(x, y, sizeof x));
|
|
148
|
+
assert(hydro_hex2bin(x, sizeof x, "452a", 4, NULL, NULL) == 2);
|
|
149
|
+
assert(hydro_hex2bin(y, sizeof y, "#452a#", 6, "#", NULL) == 2);
|
|
150
|
+
assert(hydro_equal(x, y, sizeof x));
|
|
151
|
+
memcpy(hex, "#452a", sizeof "#452a");
|
|
152
|
+
assert(hydro_hex2bin(x, sizeof x, hex, 0, NULL, &hexf) == 0);
|
|
153
|
+
assert(hexf == hex);
|
|
154
|
+
assert(hydro_hex2bin(x, sizeof x, hex, sizeof "#452a", NULL, &hexf) == 0);
|
|
155
|
+
assert(hexf == hex);
|
|
156
|
+
assert(hydro_hex2bin(x, sizeof x, hex, sizeof "#452a", "#", &hexf) == 2);
|
|
157
|
+
assert(hexf == hex + 6);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static void
|
|
161
|
+
test_secretbox(void)
|
|
162
|
+
{
|
|
163
|
+
uint8_t key[hydro_secretbox_KEYBYTES];
|
|
164
|
+
uint8_t m[25];
|
|
165
|
+
uint8_t m2[25];
|
|
166
|
+
uint8_t c[hydro_secretbox_HEADERBYTES + 25];
|
|
167
|
+
uint8_t dk[hydro_random_SEEDBYTES];
|
|
168
|
+
uint8_t probe[hydro_secretbox_PROBEBYTES];
|
|
169
|
+
|
|
170
|
+
memset(dk, 0, sizeof dk);
|
|
171
|
+
hydro_random_buf_deterministic(m, sizeof m, dk);
|
|
172
|
+
hydro_increment(dk, sizeof dk);
|
|
173
|
+
hydro_random_buf_deterministic(key, sizeof key, dk);
|
|
174
|
+
hydro_increment(dk, sizeof dk);
|
|
175
|
+
hydro_secretbox_encrypt(c, m, sizeof m, 0, ctx, key);
|
|
176
|
+
assert(hydro_secretbox_decrypt(m2, c, sizeof c, 0, ctx, key) == 0);
|
|
177
|
+
assert(hydro_equal(m, m2, sizeof m));
|
|
178
|
+
|
|
179
|
+
hydro_secretbox_probe_create(probe, c, sizeof c, ctx, key);
|
|
180
|
+
assert(hydro_secretbox_probe_verify(probe, c, sizeof c, ctx, key) == 0);
|
|
181
|
+
probe[0]++;
|
|
182
|
+
assert(hydro_secretbox_probe_verify(probe, c, sizeof c, ctx, key) == -1);
|
|
183
|
+
probe[0]--;
|
|
184
|
+
key[0]++;
|
|
185
|
+
assert(hydro_secretbox_probe_verify(probe, c, sizeof c, ctx, key) == -1);
|
|
186
|
+
key[0]--;
|
|
187
|
+
|
|
188
|
+
assert(hydro_secretbox_decrypt(m2, c, 0, 0, ctx, key) == -1);
|
|
189
|
+
assert(hydro_secretbox_decrypt(m2, c, 1, 0, ctx, key) == -1);
|
|
190
|
+
assert(hydro_secretbox_decrypt(m2, c, hydro_secretbox_HEADERBYTES, 0, ctx, key) == -1);
|
|
191
|
+
assert(hydro_secretbox_decrypt(m2, c, sizeof c, 1, ctx, key) == -1);
|
|
192
|
+
assert(!hydro_equal(m, m2, sizeof m));
|
|
193
|
+
key[0]++;
|
|
194
|
+
assert(hydro_secretbox_decrypt(m2, c, sizeof c, 0, ctx, key) == -1);
|
|
195
|
+
key[0]--;
|
|
196
|
+
c[hydro_random_uniform(sizeof c)]++;
|
|
197
|
+
assert(hydro_secretbox_decrypt(m2, c, sizeof c, 0, ctx, key) == -1);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static void
|
|
201
|
+
test_kdf(void)
|
|
202
|
+
{
|
|
203
|
+
uint8_t key[hydro_kdf_KEYBYTES];
|
|
204
|
+
uint8_t dk[hydro_random_SEEDBYTES];
|
|
205
|
+
uint8_t subkey1[16];
|
|
206
|
+
uint8_t subkey2[16];
|
|
207
|
+
uint8_t subkey3[32];
|
|
208
|
+
uint8_t subkey4[50];
|
|
209
|
+
char subkey1_hex[16 * 2 + 1];
|
|
210
|
+
char subkey2_hex[16 * 2 + 1];
|
|
211
|
+
char subkey3_hex[32 * 2 + 1];
|
|
212
|
+
char subkey4_hex[50 * 2 + 1];
|
|
213
|
+
|
|
214
|
+
memset(dk, 0, sizeof dk);
|
|
215
|
+
hydro_random_buf_deterministic(key, sizeof key, dk);
|
|
216
|
+
hydro_kdf_derive_from_key(subkey1, sizeof subkey1, 1, ctx, key);
|
|
217
|
+
hydro_kdf_derive_from_key(subkey2, sizeof subkey2, 2, ctx, key);
|
|
218
|
+
hydro_kdf_derive_from_key(subkey3, sizeof subkey3, 0, ctx, key);
|
|
219
|
+
hydro_kdf_derive_from_key(subkey4, sizeof subkey4, 0, ctx, key);
|
|
220
|
+
hydro_bin2hex(subkey1_hex, sizeof subkey1_hex, subkey1, sizeof subkey1);
|
|
221
|
+
hydro_bin2hex(subkey2_hex, sizeof subkey2_hex, subkey2, sizeof subkey2);
|
|
222
|
+
hydro_bin2hex(subkey3_hex, sizeof subkey3_hex, subkey3, sizeof subkey3);
|
|
223
|
+
hydro_bin2hex(subkey4_hex, sizeof subkey4_hex, subkey4, sizeof subkey4);
|
|
224
|
+
assert_streq("af8019d3516d4ba6c80a7ea5a87e4d77", subkey1_hex);
|
|
225
|
+
assert_streq("af8c4cba4e1f36c293631cc7001717dd", subkey2_hex);
|
|
226
|
+
assert_streq("ff9345489dea1e4fe59194cea8794c9b0af9380c2d18c3ab38eeef2af95c1e26", subkey3_hex);
|
|
227
|
+
assert_streq(
|
|
228
|
+
"a8dd79ca19d604d1487b82d76b8d4ad4138a29dfaeeb207b99b2e5904e7855555bb94a76070fa71871df6ed911"
|
|
229
|
+
"661d99efec",
|
|
230
|
+
subkey4_hex);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
static void
|
|
234
|
+
test_sign(void)
|
|
235
|
+
{
|
|
236
|
+
uint8_t msg[500];
|
|
237
|
+
uint8_t sig[hydro_sign_BYTES];
|
|
238
|
+
hydro_sign_state st;
|
|
239
|
+
hydro_sign_keypair kp;
|
|
240
|
+
|
|
241
|
+
hydro_random_buf(msg, sizeof msg);
|
|
242
|
+
hydro_sign_keygen(&kp);
|
|
243
|
+
hydro_sign_create(sig, msg, sizeof msg, ctx, kp.sk);
|
|
244
|
+
assert(hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == 0);
|
|
245
|
+
sig[0]++;
|
|
246
|
+
assert(hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == -1);
|
|
247
|
+
sig[0]--;
|
|
248
|
+
sig[hydro_sign_BYTES - 1]++;
|
|
249
|
+
assert(hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == -1);
|
|
250
|
+
sig[hydro_sign_BYTES - 1]--;
|
|
251
|
+
msg[0]++;
|
|
252
|
+
assert(hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == -1);
|
|
253
|
+
msg[0]++;
|
|
254
|
+
hydro_sign_create(sig, msg, sizeof msg, ctx, kp.sk);
|
|
255
|
+
|
|
256
|
+
hydro_sign_init(&st, ctx);
|
|
257
|
+
hydro_sign_update(&st, msg, (sizeof msg) / 3);
|
|
258
|
+
hydro_sign_update(&st, msg + (sizeof msg) / 3, (sizeof msg) - (sizeof msg) / 3);
|
|
259
|
+
assert(hydro_sign_final_verify(&st, sig, kp.pk) == 0);
|
|
260
|
+
|
|
261
|
+
hydro_sign_init(&st, ctx);
|
|
262
|
+
hydro_sign_update(&st, msg, (sizeof msg) / 3);
|
|
263
|
+
hydro_sign_update(&st, msg + (sizeof msg) / 3, (sizeof msg) - (sizeof msg) / 3);
|
|
264
|
+
hydro_sign_final_create(&st, sig, kp.sk);
|
|
265
|
+
|
|
266
|
+
hydro_sign_init(&st, ctx);
|
|
267
|
+
hydro_sign_update(&st, msg, (sizeof msg) / 3);
|
|
268
|
+
hydro_sign_update(&st, msg + (sizeof msg) / 3, (sizeof msg) - (sizeof msg) / 3);
|
|
269
|
+
assert(hydro_sign_final_verify(&st, sig, kp.pk) == 0);
|
|
270
|
+
|
|
271
|
+
hydro_sign_init(&st, ctx);
|
|
272
|
+
hydro_sign_update(&st, msg, (sizeof msg) / 3);
|
|
273
|
+
hydro_sign_update(&st, msg + (sizeof msg) / 3, (sizeof msg) - (sizeof msg) / 3);
|
|
274
|
+
sig[0]++;
|
|
275
|
+
assert(hydro_sign_final_verify(&st, sig, kp.pk) == -1);
|
|
276
|
+
|
|
277
|
+
hydro_sign_create(sig, msg, 0, ctx, kp.sk);
|
|
278
|
+
assert(hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == -1);
|
|
279
|
+
assert(hydro_sign_verify(sig, msg, 0, ctx, kp.pk) == 0);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
static void
|
|
283
|
+
test_kx_n(void)
|
|
284
|
+
{
|
|
285
|
+
hydro_kx_keypair server_static_kp;
|
|
286
|
+
uint8_t psk[hydro_kx_PSKBYTES];
|
|
287
|
+
uint8_t packet1[hydro_kx_N_PACKET1BYTES];
|
|
288
|
+
hydro_kx_session_keypair kp_client;
|
|
289
|
+
hydro_kx_session_keypair kp_server;
|
|
290
|
+
|
|
291
|
+
hydro_kx_keygen(&server_static_kp);
|
|
292
|
+
hydro_random_buf(psk, sizeof psk);
|
|
293
|
+
|
|
294
|
+
hydro_kx_n_1(&kp_client, packet1, psk, server_static_kp.pk);
|
|
295
|
+
hydro_kx_n_2(&kp_server, packet1, psk, &server_static_kp);
|
|
296
|
+
|
|
297
|
+
assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
|
|
298
|
+
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
static void
|
|
302
|
+
test_kx_kk(void)
|
|
303
|
+
{
|
|
304
|
+
hydro_kx_state st_client;
|
|
305
|
+
hydro_kx_keypair client_static_kp;
|
|
306
|
+
hydro_kx_keypair server_static_kp;
|
|
307
|
+
uint8_t packet1[hydro_kx_KK_PACKET1BYTES];
|
|
308
|
+
uint8_t packet2[hydro_kx_KK_PACKET2BYTES];
|
|
309
|
+
hydro_kx_session_keypair kp_client;
|
|
310
|
+
hydro_kx_session_keypair kp_server;
|
|
311
|
+
|
|
312
|
+
hydro_kx_keygen(&client_static_kp);
|
|
313
|
+
hydro_kx_keygen(&server_static_kp);
|
|
314
|
+
|
|
315
|
+
hydro_kx_kk_1(&st_client, packet1, server_static_kp.pk, &client_static_kp);
|
|
316
|
+
hydro_kx_kk_2(&kp_server, packet2, packet1, client_static_kp.pk, &server_static_kp);
|
|
317
|
+
hydro_kx_kk_3(&st_client, &kp_client, packet2, server_static_kp.pk);
|
|
318
|
+
|
|
319
|
+
assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
|
|
320
|
+
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
static void
|
|
324
|
+
test_kx_xx(void)
|
|
325
|
+
{
|
|
326
|
+
hydro_kx_state st_client;
|
|
327
|
+
hydro_kx_state st_server;
|
|
328
|
+
hydro_kx_keypair client_static_kp;
|
|
329
|
+
hydro_kx_keypair server_static_kp;
|
|
330
|
+
uint8_t psk[hydro_kx_PSKBYTES];
|
|
331
|
+
uint8_t client_peer_pk[hydro_kx_PUBLICKEYBYTES];
|
|
332
|
+
uint8_t server_peer_pk[hydro_kx_PUBLICKEYBYTES];
|
|
333
|
+
uint8_t packet1[hydro_kx_XX_PACKET1BYTES];
|
|
334
|
+
uint8_t packet2[hydro_kx_XX_PACKET2BYTES];
|
|
335
|
+
uint8_t packet3[hydro_kx_XX_PACKET3BYTES];
|
|
336
|
+
hydro_kx_session_keypair kp_client;
|
|
337
|
+
hydro_kx_session_keypair kp_server;
|
|
338
|
+
|
|
339
|
+
hydro_kx_keygen(&client_static_kp);
|
|
340
|
+
hydro_kx_keygen(&server_static_kp);
|
|
341
|
+
|
|
342
|
+
hydro_kx_xx_1(&st_client, packet1, NULL);
|
|
343
|
+
hydro_kx_xx_2(&st_server, packet2, packet1, NULL, &server_static_kp);
|
|
344
|
+
hydro_kx_xx_3(&st_client, &kp_client, packet3, NULL, packet2, NULL, &client_static_kp);
|
|
345
|
+
hydro_kx_xx_4(&st_server, &kp_server, NULL, packet3, NULL);
|
|
346
|
+
|
|
347
|
+
assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
|
|
348
|
+
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
|
|
349
|
+
|
|
350
|
+
hydro_random_buf(psk, sizeof psk);
|
|
351
|
+
hydro_kx_xx_1(&st_client, packet1, psk);
|
|
352
|
+
hydro_kx_xx_2(&st_server, packet2, packet1, psk, &server_static_kp);
|
|
353
|
+
hydro_kx_xx_3(&st_client, &kp_client, packet3, client_peer_pk, packet2, psk, &client_static_kp);
|
|
354
|
+
hydro_kx_xx_4(&st_server, &kp_server, server_peer_pk, packet3, psk);
|
|
355
|
+
|
|
356
|
+
assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
|
|
357
|
+
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
|
|
358
|
+
assert(hydro_equal(client_peer_pk, server_static_kp.pk, hydro_kx_PUBLICKEYBYTES));
|
|
359
|
+
assert(hydro_equal(server_peer_pk, client_static_kp.pk, hydro_kx_PUBLICKEYBYTES));
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
static void
|
|
363
|
+
test_pwhash(void)
|
|
364
|
+
{
|
|
365
|
+
uint8_t master_key[hydro_pwhash_MASTERKEYBYTES];
|
|
366
|
+
uint8_t new_master_key[hydro_pwhash_MASTERKEYBYTES];
|
|
367
|
+
uint8_t stored[hydro_pwhash_STOREDBYTES];
|
|
368
|
+
uint8_t h[64];
|
|
369
|
+
uint8_t static_key[64];
|
|
370
|
+
char h_hex[2 * 64 + 1];
|
|
371
|
+
unsigned long long ops = 1000;
|
|
372
|
+
|
|
373
|
+
memset(master_key, 'x', sizeof master_key);
|
|
374
|
+
hydro_pwhash_deterministic(h, sizeof h, "test", sizeof "test" - 1, ctx, master_key, ops, 0, 1);
|
|
375
|
+
hydro_bin2hex(h_hex, sizeof h_hex, h, sizeof h);
|
|
376
|
+
if (ops == 1000) {
|
|
377
|
+
assert_streq(
|
|
378
|
+
"2f1a804a02f25066fd0688bf8b8e03dff3a3866958a9cf5883c459e602e232d38e3e488723f0b4a2bc61d2"
|
|
379
|
+
"0cb36a04a4d2eb18be99bc61870d72d7de5d67f237",
|
|
380
|
+
h_hex);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
hydro_pwhash_keygen(master_key);
|
|
384
|
+
assert(hydro_pwhash_create(stored, "test", sizeof "test" - 1, master_key, ops, 0, 1) == 0);
|
|
385
|
+
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, master_key, ops, 0, 1) == 0);
|
|
386
|
+
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, master_key, ops * 2, 10, 10) ==
|
|
387
|
+
0);
|
|
388
|
+
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, master_key, ops / 2, 10, 10) ==
|
|
389
|
+
-1);
|
|
390
|
+
assert(hydro_pwhash_verify(stored, "Test", sizeof "Test" - 1, master_key, ops, 0, 1) == -1);
|
|
391
|
+
assert(hydro_pwhash_verify(stored, "test", sizeof "tes" - 1, master_key, ops, 0, 1) == -1);
|
|
392
|
+
|
|
393
|
+
assert(hydro_pwhash_derive_static_key(static_key, sizeof static_key, stored, "test",
|
|
394
|
+
sizeof "test" - 1, ctx, master_key, ops, 0, 1) == 0);
|
|
395
|
+
assert(hydro_pwhash_derive_static_key(static_key, sizeof static_key, stored, "Test",
|
|
396
|
+
sizeof "Test" - 1, ctx, master_key, ops, 0, 1) == -1);
|
|
397
|
+
|
|
398
|
+
assert(hydro_pwhash_reencrypt(stored, master_key, master_key) == 0);
|
|
399
|
+
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, master_key, ops, 0, 1) == 0);
|
|
400
|
+
hydro_pwhash_keygen(new_master_key);
|
|
401
|
+
assert(hydro_pwhash_reencrypt(stored, master_key, new_master_key) == 0);
|
|
402
|
+
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, master_key, ops, 0, 1) == -1);
|
|
403
|
+
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, new_master_key, ops, 0, 1) == 0);
|
|
404
|
+
|
|
405
|
+
assert(hydro_pwhash_upgrade(stored, new_master_key, ops * 2, 0, 1) == 0);
|
|
406
|
+
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, new_master_key, ops, 0, 1) == -1);
|
|
407
|
+
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, new_master_key, ops * 2, 0, 1) ==
|
|
408
|
+
0);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
int
|
|
412
|
+
main(void)
|
|
413
|
+
{
|
|
414
|
+
int ret;
|
|
415
|
+
|
|
416
|
+
ret = hydro_init();
|
|
417
|
+
assert(ret == 0);
|
|
418
|
+
|
|
419
|
+
test_core();
|
|
420
|
+
test_hash();
|
|
421
|
+
test_kdf();
|
|
422
|
+
test_kx_n();
|
|
423
|
+
test_kx_kk();
|
|
424
|
+
test_kx_xx();
|
|
425
|
+
test_pwhash();
|
|
426
|
+
test_randombytes();
|
|
427
|
+
test_secretbox();
|
|
428
|
+
test_sign();
|
|
429
|
+
|
|
430
|
+
return 0;
|
|
431
|
+
}
|
data/vendor/main.c
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#include <stdio.h>
|
|
2
|
+
|
|
3
|
+
#include "libhydrogen/hydrogen.c"
|
|
4
|
+
#include "stringencoders/src/modp_b64.c"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Encrypts and encodes a message using hydro_secretbox_encrypt and
|
|
8
|
+
* modp_b64_encode functions. Size of the dest parameter should be:
|
|
9
|
+
*
|
|
10
|
+
* modp_b64_encode_len(size of message + hydro_secretbox_HEADERBYTES);
|
|
11
|
+
*
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
*
|
|
15
|
+
* const char* message = "My secret message";
|
|
16
|
+
* const char* context = "examples";
|
|
17
|
+
* const uint8_t key[hydro_secretbox_KEYBYTES];
|
|
18
|
+
* hydro_secretbox_keygen(key);
|
|
19
|
+
*
|
|
20
|
+
* int max = modp_b64_encode_len(strlen(message) + hydro_secretbox_HEADERBYTES);
|
|
21
|
+
* char* dest[max];
|
|
22
|
+
* size_t size = encrypt_encode(dest, message, strlen(message), 0, context, key);
|
|
23
|
+
*
|
|
24
|
+
*
|
|
25
|
+
* @see https://github.com/jedisct1/libhydrogen/wiki/Contexts
|
|
26
|
+
* @see https://github.com/jedisct1/libhydrogen/wiki/Secret-key-encryption
|
|
27
|
+
*
|
|
28
|
+
* @param dest stores the output string
|
|
29
|
+
* @param message is the original message to encrypt and encode
|
|
30
|
+
* @param message_len is the size of the message parameter
|
|
31
|
+
* @param message_id optional message tag
|
|
32
|
+
* @param context is an 8 char string describing usage.
|
|
33
|
+
* @param key the shared, secret 32 bit key used in encryption/decryption
|
|
34
|
+
* @return size of the encoded string
|
|
35
|
+
*
|
|
36
|
+
* TODO assert context and key length
|
|
37
|
+
*/
|
|
38
|
+
size_t encrypt_encode(char* dest, const char* message, size_t message_len,
|
|
39
|
+
uint64_t message_id,
|
|
40
|
+
const char context[hydro_secretbox_CONTEXTBYTES],
|
|
41
|
+
const uint8_t key[hydro_secretbox_KEYBYTES]) {
|
|
42
|
+
int cipher_len = message_len + hydro_secretbox_HEADERBYTES;
|
|
43
|
+
uint8_t cipher[cipher_len];
|
|
44
|
+
int status = hydro_secretbox_encrypt(cipher, message, message_len, message_id,
|
|
45
|
+
context, key);
|
|
46
|
+
|
|
47
|
+
if (status != 0) {
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// TODO I'm making the assumption that a uint8_t[cipher_len] is a safe
|
|
52
|
+
// substitute for the char* as expected by modp_b64_encode. Make sure this is
|
|
53
|
+
// correct.
|
|
54
|
+
return modp_b64_encode(dest, cipher, cipher_len);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Decodes and decrypts a message using modp_b64_decode and
|
|
59
|
+
* hydro_secretbox_decrypt functions. Since the estimated decoded size is not
|
|
60
|
+
* always accurate, it is safest to allocate a little more than required and
|
|
61
|
+
* then clean up the result using the real size, which is returned by this
|
|
62
|
+
* function:
|
|
63
|
+
*
|
|
64
|
+
* int max = modp_b64_decode_len(size of message);
|
|
65
|
+
* size_t real = decode_decrypt(...);
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
*
|
|
69
|
+
* // Assuming a key and context already exist, as well as a message, which
|
|
70
|
+
* // is the encoded and encoded message.
|
|
71
|
+
* int max = modp_b64_decode_len(strlen(message));
|
|
72
|
+
* char* dest[max];
|
|
73
|
+
* size_t size = decode_decrypt(dest, message, strlen(message), 0, context, key);
|
|
74
|
+
*
|
|
75
|
+
*
|
|
76
|
+
* @param dest stores the output string
|
|
77
|
+
* @param message is the message to decode and decrypt
|
|
78
|
+
* @param message_len is the size of the message parameter
|
|
79
|
+
* @param message_id optional message tag
|
|
80
|
+
* @param context is an 8 char string describing usage.
|
|
81
|
+
* @param key the shared, secret 32 bit key used in encryption/decryption
|
|
82
|
+
* @return size of the decrypted string
|
|
83
|
+
*
|
|
84
|
+
* TODO assert context and key length
|
|
85
|
+
*/
|
|
86
|
+
size_t decode_decrypt(char* dest, const void* message, size_t message_len,
|
|
87
|
+
uint64_t message_id,
|
|
88
|
+
const char context[hydro_secretbox_CONTEXTBYTES],
|
|
89
|
+
const uint8_t key[hydro_secretbox_KEYBYTES]) {
|
|
90
|
+
int max_decoded_len = modp_b64_decode_len(message_len);
|
|
91
|
+
char* decoded[max_decoded_len];
|
|
92
|
+
int decoded_len = modp_b64_decode(decoded, message, message_len);
|
|
93
|
+
|
|
94
|
+
// TODO I'm making the assumption that a char* is a safe substitute for the
|
|
95
|
+
// uint8_t* as expected by hydro_secretbox_decrypt. Make sure this is
|
|
96
|
+
// correct.
|
|
97
|
+
int status = hydro_secretbox_decrypt(dest, decoded, decoded_len, message_id,
|
|
98
|
+
context, key);
|
|
99
|
+
|
|
100
|
+
if (status != 0) {
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return decoded_len - hydro_secretbox_HEADERBYTES;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
int main(int argc, char** argv) {
|
|
108
|
+
(void)argc;
|
|
109
|
+
(void)argv;
|
|
110
|
+
|
|
111
|
+
const char* message =
|
|
112
|
+
"The C Programming Language (sometimes termed K&R, after its authors' "
|
|
113
|
+
"initials) is a computer programming book written by Brian Kernighan and "
|
|
114
|
+
"Dennis Ritchie, the latter of whom originally designed and implemented "
|
|
115
|
+
"the language, as well as co-designed the Unix operating system with "
|
|
116
|
+
"which development of the language was closely intertwined. The book was "
|
|
117
|
+
"central to the development and popularization of the C programming "
|
|
118
|
+
"language and is still widely read and used today. Because the book was "
|
|
119
|
+
"co-authored by the original language designer, and because the first "
|
|
120
|
+
"edition of the book served for many years as the de facto standard for "
|
|
121
|
+
"the language, the book was regarded by many to be the authoritative "
|
|
122
|
+
"reference on C.";
|
|
123
|
+
|
|
124
|
+
const char* context = "examples";
|
|
125
|
+
const uint8_t key[hydro_secretbox_KEYBYTES];
|
|
126
|
+
hydro_secretbox_keygen(key);
|
|
127
|
+
|
|
128
|
+
int max_enc =
|
|
129
|
+
modp_b64_encode_len(strlen(message) + hydro_secretbox_HEADERBYTES);
|
|
130
|
+
char* encoded[max_enc];
|
|
131
|
+
int enc_size =
|
|
132
|
+
encrypt_encode(encoded, message, strlen(message), 0, context, key);
|
|
133
|
+
|
|
134
|
+
int max_size = modp_b64_decode_len(enc_size);
|
|
135
|
+
char* result[max_size];
|
|
136
|
+
int real_size = decode_decrypt(result, encoded, enc_size, 0, context, key);
|
|
137
|
+
printf("max_size = %d\n", max_size);
|
|
138
|
+
printf("size = %d\n", real_size);
|
|
139
|
+
printf("result = %s\n", result);
|
|
140
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
*.o
|
|
2
|
+
*.log
|
|
3
|
+
*.trs
|
|
4
|
+
*.lo
|
|
5
|
+
Makefile
|
|
6
|
+
Makefile.in
|
|
7
|
+
.libs
|
|
8
|
+
.deps
|
|
9
|
+
*.la
|
|
10
|
+
aclocal.m4
|
|
11
|
+
autom4te.cache/
|
|
12
|
+
compile
|
|
13
|
+
config.guess
|
|
14
|
+
config.h
|
|
15
|
+
config.h.in
|
|
16
|
+
config.status
|
|
17
|
+
config.sub
|
|
18
|
+
configure
|
|
19
|
+
depcomp
|
|
20
|
+
install-sh
|
|
21
|
+
libtool
|
|
22
|
+
ltmain.sh
|
|
23
|
+
m4/
|
|
24
|
+
missing
|
|
25
|
+
stamp-h1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
it could be you. Send pull requests!
|