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,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* \file
|
|
3
|
+
* <PRE>
|
|
4
|
+
* MODP_B36 - High performance base36 encoder/decoder
|
|
5
|
+
* https://github.com/client9/stringencoders
|
|
6
|
+
*
|
|
7
|
+
* Copyright © 2006-2016 Nick Galbreath
|
|
8
|
+
* All rights reserved.
|
|
9
|
+
*
|
|
10
|
+
* Released under MIT license. See LICENSE for details.
|
|
11
|
+
* </pre>
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/* exported public header */
|
|
15
|
+
#include "modp_b36.h"
|
|
16
|
+
#include "modp_stdint.h"
|
|
17
|
+
/* private header */
|
|
18
|
+
#include "modp_b36_data.h"
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* Might need changing depending on platform
|
|
22
|
+
* we need htonl, and ntohl
|
|
23
|
+
*/
|
|
24
|
+
#include <arpa/inet.h>
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* you can decode IN PLACE!
|
|
28
|
+
* no memory allocated
|
|
29
|
+
*/
|
|
30
|
+
size_t modp_b36_decode(char* out, const char* data, size_t len)
|
|
31
|
+
{
|
|
32
|
+
size_t i;
|
|
33
|
+
int j;
|
|
34
|
+
const size_t buckets = len / 7;
|
|
35
|
+
const uint8_t* d2 = (const uint8_t*)data;
|
|
36
|
+
if (len % 7 != 0) {
|
|
37
|
+
return (size_t)-1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
uint32_t* o2 = (uint32_t*)out;
|
|
41
|
+
for (i = 0; i < buckets; ++i) {
|
|
42
|
+
uint32_t tmp = 0;
|
|
43
|
+
for (j = 0; j < 7; ++j) {
|
|
44
|
+
uint32_t digit = gsCharToInt[(uint32_t)*d2++];
|
|
45
|
+
if (digit >= 36) {
|
|
46
|
+
return (size_t)-1;
|
|
47
|
+
}
|
|
48
|
+
tmp = tmp * 36 + digit;
|
|
49
|
+
}
|
|
50
|
+
*o2++ = htonl(tmp);
|
|
51
|
+
}
|
|
52
|
+
return 4 * buckets;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* src != out
|
|
57
|
+
*/
|
|
58
|
+
size_t modp_b36_encode(char* out, const char* src, size_t len)
|
|
59
|
+
{
|
|
60
|
+
const uint32_t* sary = (const uint32_t*)src;
|
|
61
|
+
const size_t buckets = len / 4;
|
|
62
|
+
if (len % 4 != 0) {
|
|
63
|
+
return (size_t)-1;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
size_t i;
|
|
67
|
+
for (i = 0; i < buckets; ++i) {
|
|
68
|
+
uint32_t tmp = *sary++;
|
|
69
|
+
tmp = htonl(tmp);
|
|
70
|
+
|
|
71
|
+
/* this crazy function */
|
|
72
|
+
#if 0
|
|
73
|
+
*out++ = (char)gsIntToChar[(tmp / 52200625)]; // don't need % 36 here, always < 36
|
|
74
|
+
*out++ = (char)gsIntToChar[(tmp / 614125) % 36];
|
|
75
|
+
*out++ = (char)gsIntToChar[(tmp / 7225) % 36];
|
|
76
|
+
*out++ = (char)gsIntToChar[(tmp / 36) % 36];
|
|
77
|
+
*out++ = (char)gsIntToChar[tmp % 36];
|
|
78
|
+
#else
|
|
79
|
+
/* is really this */
|
|
80
|
+
*(out + 6) = gsIntToChar[tmp % 36];
|
|
81
|
+
tmp /= 36;
|
|
82
|
+
*(out + 5) = gsIntToChar[tmp % 36];
|
|
83
|
+
tmp /= 36;
|
|
84
|
+
*(out + 4) = gsIntToChar[tmp % 36];
|
|
85
|
+
tmp /= 36;
|
|
86
|
+
*(out + 3) = gsIntToChar[tmp % 36];
|
|
87
|
+
tmp /= 36;
|
|
88
|
+
*(out + 2) = gsIntToChar[tmp % 36];
|
|
89
|
+
tmp /= 36;
|
|
90
|
+
*(out + 1) = gsIntToChar[tmp % 36];
|
|
91
|
+
tmp /= 36;
|
|
92
|
+
*out = gsIntToChar[tmp];
|
|
93
|
+
out += 7;
|
|
94
|
+
#endif
|
|
95
|
+
// NOTES
|
|
96
|
+
// Version 1 under -O3 is about 10-20 PERCENT faster than version 2
|
|
97
|
+
// BUT Version 1 is 10 TIMES SLOWER when used with -Os !!!
|
|
98
|
+
// Reason: gcc does a lot of tricks to remove the divisions
|
|
99
|
+
// op with multiplies and shift.
|
|
100
|
+
// In V1 with -O3 this works. Under -Os it reverts to very
|
|
101
|
+
// slow division.
|
|
102
|
+
// In V2 -O3 it does the same thing, but under Os, it's smart
|
|
103
|
+
// enough to know we want the quotient and remainder and only
|
|
104
|
+
// one div call per line.
|
|
105
|
+
}
|
|
106
|
+
*out = 0; // final null
|
|
107
|
+
return buckets * 7;
|
|
108
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* \file modp_b36.h
|
|
3
|
+
* \brief Base 36 encoding and decoding
|
|
4
|
+
*
|
|
5
|
+
* This provides a endian-safe base36 encode/decode operations. This
|
|
6
|
+
* means, the result will be the same on x86 or ibm/sparc chips.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* <pre>
|
|
11
|
+
* High Performance Base36 Encoder / Decoder
|
|
12
|
+
*
|
|
13
|
+
* Copyright © 2013-2016 Nick Galbreath
|
|
14
|
+
* All rights reserved.
|
|
15
|
+
*
|
|
16
|
+
* https://github.com/client9/stringencoders
|
|
17
|
+
*
|
|
18
|
+
* Released under MIT license. See LICENSE for details.
|
|
19
|
+
* </PRE>
|
|
20
|
+
*
|
|
21
|
+
* This provides a endian-safe base36 encode/decode operations. This
|
|
22
|
+
* means, the result will be the same on x86 or ibm/sparc chips.
|
|
23
|
+
*
|
|
24
|
+
* (Note: making it endian-specifc only results in a 5% savings in
|
|
25
|
+
* the decode operation, so why bother)
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
#ifndef COM_MODP_STRINGENCODERS_B36
|
|
29
|
+
#define COM_MODP_STRINGENCODERS_B36
|
|
30
|
+
#include "extern_c_begin.h"
|
|
31
|
+
#include "modp_stdint.h"
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* \brief base 36 encode
|
|
35
|
+
*
|
|
36
|
+
* \param[out] dest should have at least b36fast_encode_len memory allocated
|
|
37
|
+
* \param[in] src input string
|
|
38
|
+
* \param[in] len input string length, must be a multiple of 4
|
|
39
|
+
* \return the strlen of the destination, or -1 if error
|
|
40
|
+
*
|
|
41
|
+
*/
|
|
42
|
+
size_t modp_b36_encode(char* dest, const char* src, size_t len);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* \brief Base 36 decode
|
|
46
|
+
* \param[out] dest -- destination locations. May equal input.
|
|
47
|
+
* \param[in] src -- source b36data
|
|
48
|
+
* \param len -- length of source
|
|
49
|
+
* \return -1 on decoding error, length of output otherwise
|
|
50
|
+
* No ending null is added
|
|
51
|
+
*/
|
|
52
|
+
size_t modp_b36_decode(char* dest, const char* src, size_t len);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* \brief Returns the amount of memory to allocate for encoding the input
|
|
56
|
+
* string.
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
#define modp_b36_encode_len(A) ((A + 3) / 4 * 5 + 1)
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* \brief Return output strlen, without a NULL
|
|
63
|
+
*/
|
|
64
|
+
#define modp_b36_encode_strlen(A) ((A + 3) / 4 * 5)
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* \brief Return the amount of memory to allocate for decoding a base 36
|
|
68
|
+
* encoded string.
|
|
69
|
+
*
|
|
70
|
+
*/
|
|
71
|
+
#define modp_b36_decode_len(A) ((A + 4) / 5 * 4)
|
|
72
|
+
|
|
73
|
+
#include "extern_c_end.h"
|
|
74
|
+
|
|
75
|
+
#ifdef __cplusplus
|
|
76
|
+
#include <cstring>
|
|
77
|
+
#include <string>
|
|
78
|
+
|
|
79
|
+
namespace modp {
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
*
|
|
83
|
+
* \param[in] s the input data
|
|
84
|
+
* \param[in] len the length of input
|
|
85
|
+
* \return b36 encoded string
|
|
86
|
+
*/
|
|
87
|
+
inline std::string b36_encode(const char* s, size_t len)
|
|
88
|
+
{
|
|
89
|
+
std::string x(modp_b36_encode_len(len), '\0');
|
|
90
|
+
size_t d = modp_b36_encode(const_cast<char*>(x.data()), s, len);
|
|
91
|
+
if (d == (size_t)-1) {
|
|
92
|
+
x.clear();
|
|
93
|
+
} else {
|
|
94
|
+
x.erase(d, std::string::npos);
|
|
95
|
+
}
|
|
96
|
+
return x;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* \param[in] null-terminated c-string input
|
|
101
|
+
* \return b36 encoded string
|
|
102
|
+
*/
|
|
103
|
+
inline std::string b36_encode(const char* s)
|
|
104
|
+
{
|
|
105
|
+
return b36_encode(s, strlen(s));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* /param[in,out] s the string to encode
|
|
110
|
+
* /return a reference to the input string, empty if error
|
|
111
|
+
*/
|
|
112
|
+
inline std::string& b36_encode(std::string& s)
|
|
113
|
+
{
|
|
114
|
+
std::string x(b36_encode(s.data(), s.size()));
|
|
115
|
+
s.swap(x);
|
|
116
|
+
return s;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* \param[in] s the input string
|
|
121
|
+
* \return base36 encoded string
|
|
122
|
+
*/
|
|
123
|
+
inline std::string b36_encode(const std::string& s)
|
|
124
|
+
{
|
|
125
|
+
return b36_encode(s.data(), s.size());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Base36 decode a string.
|
|
130
|
+
* This function does not allocate memory.
|
|
131
|
+
*
|
|
132
|
+
* \param s the string to decode
|
|
133
|
+
* \return a reference to the input string. The string is empty
|
|
134
|
+
* if an error occurred.
|
|
135
|
+
*/
|
|
136
|
+
inline std::string& b36_decode(std::string& s)
|
|
137
|
+
{
|
|
138
|
+
size_t d = modp_b36_decode(const_cast<char*>(s.data()), s.data(), s.size());
|
|
139
|
+
if (d == (size_t)-1) {
|
|
140
|
+
s.clear();
|
|
141
|
+
} else {
|
|
142
|
+
s.erase(d, std::string::npos);
|
|
143
|
+
}
|
|
144
|
+
return s;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
inline std::string b36_decode(const std::string& s)
|
|
148
|
+
{
|
|
149
|
+
std::string x(s);
|
|
150
|
+
b36_decode(x);
|
|
151
|
+
return x;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
inline std::string b36_decode(const char* s, size_t len)
|
|
155
|
+
{
|
|
156
|
+
std::string x(s, len);
|
|
157
|
+
return b36_decode(x);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
inline std::string b36_decode(const char* s)
|
|
161
|
+
{
|
|
162
|
+
std::string x(s);
|
|
163
|
+
return b36_decode(x);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
} /* namespace modp */
|
|
167
|
+
|
|
168
|
+
#endif /* ifdef __cplusplus */
|
|
169
|
+
|
|
170
|
+
#endif /* ifndef MODP_B36 */
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* \file modp_b64.c
|
|
3
|
+
* <PRE>
|
|
4
|
+
* MODP_B64 - High performance base64 encoder/decoder
|
|
5
|
+
* https://github.com/client9/stringencoders
|
|
6
|
+
*
|
|
7
|
+
* Copyright © 2005-2016 Nick Galbreath
|
|
8
|
+
* All rights reserved.
|
|
9
|
+
* Released under MIT license. See LICENSE for details.
|
|
10
|
+
* </PRE>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* If you are ripping this out of the library, comment out the next
|
|
15
|
+
* line and uncomment the next lines as approrpiate
|
|
16
|
+
*/
|
|
17
|
+
// #include "config.h"
|
|
18
|
+
|
|
19
|
+
/* public header */
|
|
20
|
+
#include "modp_b64.h"
|
|
21
|
+
|
|
22
|
+
/* if on motorola, sun, ibm; uncomment this */
|
|
23
|
+
/* #define WORDS_BIGENDIAN 1 */
|
|
24
|
+
/* else for Intel, Amd; uncomment this */
|
|
25
|
+
/* #undef WORDS_BIGENDIAN */
|
|
26
|
+
|
|
27
|
+
#include "modp_b64_data.h"
|
|
28
|
+
|
|
29
|
+
#define BADCHAR 0x01FFFFFF
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* you can control if we use padding by commenting out this
|
|
33
|
+
* next line. However, I highly recommend you use padding and not
|
|
34
|
+
* using it should only be for compatibility with a 3rd party.
|
|
35
|
+
* Also, 'no padding' is not tested!
|
|
36
|
+
*/
|
|
37
|
+
#define DOPAD 1
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
* if we aren't doing padding
|
|
41
|
+
* set the pad character to NULL
|
|
42
|
+
*/
|
|
43
|
+
#ifndef DOPAD
|
|
44
|
+
#undef CHARPAD
|
|
45
|
+
#define CHARPAD '\0'
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
size_t modp_b64_encode(char* dest, const char* str, size_t len)
|
|
49
|
+
{
|
|
50
|
+
size_t i = 0;
|
|
51
|
+
const uint8_t* s = (const uint8_t*)str;
|
|
52
|
+
uint8_t* p = (uint8_t*)dest;
|
|
53
|
+
|
|
54
|
+
/* unsigned here is important! */
|
|
55
|
+
/* uint8_t is fastest on G4, amd */
|
|
56
|
+
/* uint32_t is fastest on Intel */
|
|
57
|
+
uint32_t t1, t2, t3;
|
|
58
|
+
|
|
59
|
+
if (len > 2) {
|
|
60
|
+
for (i = 0; i < len - 2; i += 3) {
|
|
61
|
+
t1 = s[i];
|
|
62
|
+
t2 = s[i + 1];
|
|
63
|
+
t3 = s[i + 2];
|
|
64
|
+
*p++ = e0[t1];
|
|
65
|
+
*p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
|
|
66
|
+
*p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)];
|
|
67
|
+
*p++ = e2[t3];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
switch (len - i) {
|
|
72
|
+
case 0:
|
|
73
|
+
break;
|
|
74
|
+
case 1:
|
|
75
|
+
t1 = s[i];
|
|
76
|
+
*p++ = e0[t1];
|
|
77
|
+
*p++ = e1[(t1 & 0x03) << 4];
|
|
78
|
+
*p++ = CHARPAD;
|
|
79
|
+
*p++ = CHARPAD;
|
|
80
|
+
break;
|
|
81
|
+
default: /* case 2 */
|
|
82
|
+
t1 = s[i];
|
|
83
|
+
t2 = s[i + 1];
|
|
84
|
+
*p++ = e0[t1];
|
|
85
|
+
*p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
|
|
86
|
+
*p++ = e2[(t2 & 0x0F) << 2];
|
|
87
|
+
*p++ = CHARPAD;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
*p = '\0';
|
|
91
|
+
return (size_t)(p - (uint8_t*)dest);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */
|
|
95
|
+
size_t modp_b64_decode(char* dest, const char* src, size_t len)
|
|
96
|
+
{
|
|
97
|
+
size_t i;
|
|
98
|
+
if (len == 0)
|
|
99
|
+
return 0;
|
|
100
|
+
|
|
101
|
+
#ifdef DOPAD
|
|
102
|
+
/* if padding is used, then the message must be at least
|
|
103
|
+
4 chars and be a multiple of 4.
|
|
104
|
+
there can be at most 2 pad chars at the end */
|
|
105
|
+
if (len < 4 || (len % 4 != 0))
|
|
106
|
+
return -1;
|
|
107
|
+
if (src[len - 1] == CHARPAD) {
|
|
108
|
+
len--;
|
|
109
|
+
if (src[len - 1] == CHARPAD) {
|
|
110
|
+
len--;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
#endif /* DOPAD */
|
|
114
|
+
|
|
115
|
+
size_t leftover = len % 4;
|
|
116
|
+
size_t chunks = (leftover == 0) ? len / 4 - 1 : len / 4;
|
|
117
|
+
|
|
118
|
+
uint8_t* p = (uint8_t*)dest;
|
|
119
|
+
uint32_t x = 0;
|
|
120
|
+
uint32_t* destInt = (uint32_t*)p;
|
|
121
|
+
uint32_t* srcInt = (uint32_t*)src;
|
|
122
|
+
uint32_t y = *srcInt++;
|
|
123
|
+
for (i = 0; i < chunks; ++i) {
|
|
124
|
+
x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff];
|
|
125
|
+
|
|
126
|
+
if (x >= BADCHAR)
|
|
127
|
+
return -1;
|
|
128
|
+
*destInt = x << 8;
|
|
129
|
+
p += 3;
|
|
130
|
+
destInt = (uint32_t*)p;
|
|
131
|
+
y = *srcInt++;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
switch (leftover) {
|
|
135
|
+
case 0:
|
|
136
|
+
x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff];
|
|
137
|
+
if (x >= BADCHAR)
|
|
138
|
+
return -1;
|
|
139
|
+
*p++ = ((uint8_t*)&x)[1];
|
|
140
|
+
*p++ = ((uint8_t*)&x)[2];
|
|
141
|
+
*p = ((uint8_t*)&x)[3];
|
|
142
|
+
return (chunks + 1) * 3;
|
|
143
|
+
#ifndef DOPAD
|
|
144
|
+
case 1: /* with padding this is an impossible case */
|
|
145
|
+
x = d3[y >> 24];
|
|
146
|
+
*p = (uint8_t)x;
|
|
147
|
+
break;
|
|
148
|
+
#endif
|
|
149
|
+
case 2:
|
|
150
|
+
x = d3[y >> 24] * 64 + d3[(y >> 16) & 0xff];
|
|
151
|
+
*p = (uint8_t)(x >> 4);
|
|
152
|
+
break;
|
|
153
|
+
default: /* case 3 */
|
|
154
|
+
x = (d3[y >> 24] * 64 + d3[(y >> 16) & 0xff]) * 64 + d3[(y >> 8) & 0xff];
|
|
155
|
+
*p++ = (uint8_t)(x >> 10);
|
|
156
|
+
*p = (uint8_t)(x >> 2);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (x >= BADCHAR)
|
|
161
|
+
return -1;
|
|
162
|
+
return 3 * chunks + (6 * leftover) / 8;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
#else /* LITTLE ENDIAN -- INTEL AND FRIENDS */
|
|
166
|
+
|
|
167
|
+
size_t modp_b64_decode(char* dest, const char* src, size_t len)
|
|
168
|
+
{
|
|
169
|
+
size_t i;
|
|
170
|
+
size_t leftover;
|
|
171
|
+
size_t chunks;
|
|
172
|
+
|
|
173
|
+
uint8_t* p;
|
|
174
|
+
uint32_t x;
|
|
175
|
+
uint32_t* destInt;
|
|
176
|
+
const uint32_t* srcInt = (const uint32_t*)src;
|
|
177
|
+
uint32_t y = *srcInt++;
|
|
178
|
+
|
|
179
|
+
if (len == 0)
|
|
180
|
+
return 0;
|
|
181
|
+
|
|
182
|
+
#ifdef DOPAD
|
|
183
|
+
/*
|
|
184
|
+
* if padding is used, then the message must be at least
|
|
185
|
+
* 4 chars and be a multiple of 4
|
|
186
|
+
*/
|
|
187
|
+
if (len < 4 || (len % 4 != 0)) {
|
|
188
|
+
return (size_t)-1; /* error */
|
|
189
|
+
}
|
|
190
|
+
/* there can be at most 2 pad chars at the end */
|
|
191
|
+
if (src[len - 1] == CHARPAD) {
|
|
192
|
+
len--;
|
|
193
|
+
if (src[len - 1] == CHARPAD) {
|
|
194
|
+
len--;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
#endif
|
|
198
|
+
|
|
199
|
+
leftover = len % 4;
|
|
200
|
+
chunks = (leftover == 0) ? len / 4 - 1 : len / 4;
|
|
201
|
+
|
|
202
|
+
p = (uint8_t*)dest;
|
|
203
|
+
x = 0;
|
|
204
|
+
destInt = (uint32_t*)p;
|
|
205
|
+
srcInt = (const uint32_t*)src;
|
|
206
|
+
y = *srcInt++;
|
|
207
|
+
for (i = 0; i < chunks; ++i) {
|
|
208
|
+
x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff];
|
|
209
|
+
|
|
210
|
+
if (x >= BADCHAR) {
|
|
211
|
+
return (size_t)-1;
|
|
212
|
+
}
|
|
213
|
+
*destInt = x;
|
|
214
|
+
p += 3;
|
|
215
|
+
destInt = (uint32_t*)p;
|
|
216
|
+
y = *srcInt++;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
switch (leftover) {
|
|
220
|
+
case 0:
|
|
221
|
+
x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff];
|
|
222
|
+
|
|
223
|
+
if (x >= BADCHAR) {
|
|
224
|
+
return (size_t)-1;
|
|
225
|
+
}
|
|
226
|
+
*p++ = ((uint8_t*)(&x))[0];
|
|
227
|
+
*p++ = ((uint8_t*)(&x))[1];
|
|
228
|
+
*p = ((uint8_t*)(&x))[2];
|
|
229
|
+
return (chunks + 1) * 3;
|
|
230
|
+
#ifndef DOPAD
|
|
231
|
+
case 1: /* with padding this is an impossible case */
|
|
232
|
+
x = d0[y & 0xff];
|
|
233
|
+
*p = *((uint8_t*)(&x)); /* i.e. first char/byte in int */
|
|
234
|
+
break;
|
|
235
|
+
#endif
|
|
236
|
+
case 2: /* case 2, 1 output byte */
|
|
237
|
+
x = d0[y & 0xff] | d1[y >> 8 & 0xff];
|
|
238
|
+
*p = *((uint8_t*)(&x)); /* i.e. first char */
|
|
239
|
+
break;
|
|
240
|
+
default: /* case 3, 2 output bytes */
|
|
241
|
+
x = d0[y & 0xff] | d1[y >> 8 & 0xff] | d2[y >> 16 & 0xff]; /* 0x3c */
|
|
242
|
+
*p++ = ((uint8_t*)(&x))[0];
|
|
243
|
+
*p = ((uint8_t*)(&x))[1];
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (x >= BADCHAR) {
|
|
248
|
+
return (size_t)-1;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return 3 * chunks + (6 * leftover) / 8;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
#endif /* if bigendian / else / endif */
|