ffi-hydrogen 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +30 -0
  5. data/.travis.yml +10 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +72 -0
  9. data/Rakefile +46 -0
  10. data/bench/both.rb +86 -0
  11. data/bench/encode.rb +57 -0
  12. data/bench/encrypt.rb +80 -0
  13. data/bench/init.rb +5 -0
  14. data/bin/console +14 -0
  15. data/bin/setup +8 -0
  16. data/ffi-hydrogen.gemspec +31 -0
  17. data/lib/ffi/hydrogen.rb +216 -0
  18. data/vendor/.clang-format +2 -0
  19. data/vendor/.gitignore +3 -0
  20. data/vendor/README.md +2 -0
  21. data/vendor/libhydrogen/.clang-format +95 -0
  22. data/vendor/libhydrogen/.gitignore +32 -0
  23. data/vendor/libhydrogen/.travis.yml +22 -0
  24. data/vendor/libhydrogen/LICENSE +18 -0
  25. data/vendor/libhydrogen/Makefile +61 -0
  26. data/vendor/libhydrogen/Makefile.arduino +51 -0
  27. data/vendor/libhydrogen/README.md +29 -0
  28. data/vendor/libhydrogen/hydrogen.c +18 -0
  29. data/vendor/libhydrogen/hydrogen.h +317 -0
  30. data/vendor/libhydrogen/impl/common.h +316 -0
  31. data/vendor/libhydrogen/impl/core.h +220 -0
  32. data/vendor/libhydrogen/impl/gimli-core/portable.h +39 -0
  33. data/vendor/libhydrogen/impl/gimli-core/sse2.h +97 -0
  34. data/vendor/libhydrogen/impl/gimli-core.h +25 -0
  35. data/vendor/libhydrogen/impl/hash.h +138 -0
  36. data/vendor/libhydrogen/impl/hydrogen_p.h +83 -0
  37. data/vendor/libhydrogen/impl/kdf.h +20 -0
  38. data/vendor/libhydrogen/impl/kx.h +441 -0
  39. data/vendor/libhydrogen/impl/pwhash.h +281 -0
  40. data/vendor/libhydrogen/impl/random.h +376 -0
  41. data/vendor/libhydrogen/impl/secretbox.h +236 -0
  42. data/vendor/libhydrogen/impl/sign.h +207 -0
  43. data/vendor/libhydrogen/impl/x25519.h +383 -0
  44. data/vendor/libhydrogen/library.properties +10 -0
  45. data/vendor/libhydrogen/logo.png +0 -0
  46. data/vendor/libhydrogen/tests/tests.c +431 -0
  47. data/vendor/main.c +140 -0
  48. data/vendor/stringencoders/.gitignore +25 -0
  49. data/vendor/stringencoders/.travis.yml +13 -0
  50. data/vendor/stringencoders/AUTHORS +1 -0
  51. data/vendor/stringencoders/COPYING +2 -0
  52. data/vendor/stringencoders/ChangeLog +170 -0
  53. data/vendor/stringencoders/Doxyfile +276 -0
  54. data/vendor/stringencoders/INSTALL +119 -0
  55. data/vendor/stringencoders/LICENSE +22 -0
  56. data/vendor/stringencoders/Makefile.am +3 -0
  57. data/vendor/stringencoders/NEWS +3 -0
  58. data/vendor/stringencoders/README +2 -0
  59. data/vendor/stringencoders/README.md +32 -0
  60. data/vendor/stringencoders/bootstrap.sh +3 -0
  61. data/vendor/stringencoders/configure-gcc-hardened.sh +16 -0
  62. data/vendor/stringencoders/configure.ac +44 -0
  63. data/vendor/stringencoders/doxy/footer.html +34 -0
  64. data/vendor/stringencoders/doxy/header.html +85 -0
  65. data/vendor/stringencoders/indent.sh +9 -0
  66. data/vendor/stringencoders/javascript/base64-speed.html +43 -0
  67. data/vendor/stringencoders/javascript/base64-test.html +209 -0
  68. data/vendor/stringencoders/javascript/base64.html +18 -0
  69. data/vendor/stringencoders/javascript/base64.js +176 -0
  70. data/vendor/stringencoders/javascript/qunit.css +119 -0
  71. data/vendor/stringencoders/javascript/qunit.js +1062 -0
  72. data/vendor/stringencoders/javascript/urlparse-test.html +367 -0
  73. data/vendor/stringencoders/javascript/urlparse.js +328 -0
  74. data/vendor/stringencoders/make-ci.sh +13 -0
  75. data/vendor/stringencoders/makerelease.sh +16 -0
  76. data/vendor/stringencoders/python/b85.py +176 -0
  77. data/vendor/stringencoders/src/Makefile.am +134 -0
  78. data/vendor/stringencoders/src/arraytoc.c +85 -0
  79. data/vendor/stringencoders/src/arraytoc.h +43 -0
  80. data/vendor/stringencoders/src/extern_c_begin.h +3 -0
  81. data/vendor/stringencoders/src/extern_c_end.h +3 -0
  82. data/vendor/stringencoders/src/html_named_entities_generator.py +203 -0
  83. data/vendor/stringencoders/src/modp_ascii.c +159 -0
  84. data/vendor/stringencoders/src/modp_ascii.h +162 -0
  85. data/vendor/stringencoders/src/modp_ascii_data.h +84 -0
  86. data/vendor/stringencoders/src/modp_ascii_gen.c +55 -0
  87. data/vendor/stringencoders/src/modp_b16.c +125 -0
  88. data/vendor/stringencoders/src/modp_b16.h +148 -0
  89. data/vendor/stringencoders/src/modp_b16_data.h +104 -0
  90. data/vendor/stringencoders/src/modp_b16_gen.c +65 -0
  91. data/vendor/stringencoders/src/modp_b2.c +69 -0
  92. data/vendor/stringencoders/src/modp_b2.h +130 -0
  93. data/vendor/stringencoders/src/modp_b2_data.h +44 -0
  94. data/vendor/stringencoders/src/modp_b2_gen.c +36 -0
  95. data/vendor/stringencoders/src/modp_b36.c +108 -0
  96. data/vendor/stringencoders/src/modp_b36.h +170 -0
  97. data/vendor/stringencoders/src/modp_b64.c +254 -0
  98. data/vendor/stringencoders/src/modp_b64.h +236 -0
  99. data/vendor/stringencoders/src/modp_b64_data.h +477 -0
  100. data/vendor/stringencoders/src/modp_b64_gen.c +168 -0
  101. data/vendor/stringencoders/src/modp_b64r.c +254 -0
  102. data/vendor/stringencoders/src/modp_b64r.h +242 -0
  103. data/vendor/stringencoders/src/modp_b64r_data.h +477 -0
  104. data/vendor/stringencoders/src/modp_b64w.c +254 -0
  105. data/vendor/stringencoders/src/modp_b64w.h +231 -0
  106. data/vendor/stringencoders/src/modp_b64w_data.h +477 -0
  107. data/vendor/stringencoders/src/modp_b85.c +109 -0
  108. data/vendor/stringencoders/src/modp_b85.h +171 -0
  109. data/vendor/stringencoders/src/modp_b85_data.h +36 -0
  110. data/vendor/stringencoders/src/modp_b85_gen.c +65 -0
  111. data/vendor/stringencoders/src/modp_bjavascript.c +65 -0
  112. data/vendor/stringencoders/src/modp_bjavascript.h +105 -0
  113. data/vendor/stringencoders/src/modp_bjavascript_data.h +84 -0
  114. data/vendor/stringencoders/src/modp_bjavascript_gen.c +58 -0
  115. data/vendor/stringencoders/src/modp_burl.c +228 -0
  116. data/vendor/stringencoders/src/modp_burl.h +259 -0
  117. data/vendor/stringencoders/src/modp_burl_data.h +136 -0
  118. data/vendor/stringencoders/src/modp_burl_gen.c +121 -0
  119. data/vendor/stringencoders/src/modp_html.c +128 -0
  120. data/vendor/stringencoders/src/modp_html.h +53 -0
  121. data/vendor/stringencoders/src/modp_html_named_entities.h +9910 -0
  122. data/vendor/stringencoders/src/modp_json.c +315 -0
  123. data/vendor/stringencoders/src/modp_json.h +103 -0
  124. data/vendor/stringencoders/src/modp_json_data.h +57 -0
  125. data/vendor/stringencoders/src/modp_json_gen.py +60 -0
  126. data/vendor/stringencoders/src/modp_mainpage.h +120 -0
  127. data/vendor/stringencoders/src/modp_numtoa.c +350 -0
  128. data/vendor/stringencoders/src/modp_numtoa.h +100 -0
  129. data/vendor/stringencoders/src/modp_qsiter.c +76 -0
  130. data/vendor/stringencoders/src/modp_qsiter.h +71 -0
  131. data/vendor/stringencoders/src/modp_stdint.h +43 -0
  132. data/vendor/stringencoders/src/modp_utf8.c +88 -0
  133. data/vendor/stringencoders/src/modp_utf8.h +38 -0
  134. data/vendor/stringencoders/src/modp_xml.c +311 -0
  135. data/vendor/stringencoders/src/modp_xml.h +166 -0
  136. data/vendor/stringencoders/src/stringencoders.pc +10 -0
  137. data/vendor/stringencoders/src/stringencoders.pc.in +10 -0
  138. data/vendor/stringencoders/test/Makefile.am +113 -0
  139. data/vendor/stringencoders/test/apr_base64.c +262 -0
  140. data/vendor/stringencoders/test/apr_base64.h +120 -0
  141. data/vendor/stringencoders/test/cxx_test.cc +482 -0
  142. data/vendor/stringencoders/test/minunit.h +82 -0
  143. data/vendor/stringencoders/test/modp_ascii_test.c +281 -0
  144. data/vendor/stringencoders/test/modp_b16_test.c +288 -0
  145. data/vendor/stringencoders/test/modp_b2_test.c +250 -0
  146. data/vendor/stringencoders/test/modp_b64_test.c +266 -0
  147. data/vendor/stringencoders/test/modp_b85_test.c +130 -0
  148. data/vendor/stringencoders/test/modp_bjavascript_test.c +137 -0
  149. data/vendor/stringencoders/test/modp_burl_test.c +423 -0
  150. data/vendor/stringencoders/test/modp_html_test.c +296 -0
  151. data/vendor/stringencoders/test/modp_json_test.c +336 -0
  152. data/vendor/stringencoders/test/modp_numtoa_test.c +545 -0
  153. data/vendor/stringencoders/test/modp_qsiter_test.c +280 -0
  154. data/vendor/stringencoders/test/modp_utf8_test.c +188 -0
  155. data/vendor/stringencoders/test/modp_xml_test.c +339 -0
  156. data/vendor/stringencoders/test/speedtest.c +241 -0
  157. data/vendor/stringencoders/test/speedtest_ascii.c +345 -0
  158. data/vendor/stringencoders/test/speedtest_msg.c +78 -0
  159. data/vendor/stringencoders/test/speedtest_numtoa.c +276 -0
  160. metadata +314 -0
@@ -0,0 +1,254 @@
1
+ /**
2
+ * \file modp_b64r.c
3
+ * <PRE>
4
+ * MODP_B64 - High performance base64 encoder/decoder
5
+ * https://github.com/client9/stringencoders
6
+ *
7
+ * Copyright &copy; 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_b64r.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_b64r_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_b64r_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_b64r_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_b64r_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 */
@@ -0,0 +1,242 @@
1
+ /**
2
+ * \file
3
+ * <PRE>
4
+ * High performance WEB-SAFE base64 encoder / decoder
5
+ *
6
+ * Copyright &copy; 2005-2016 Nick Galbreath -- nickg [at] client9 [dot] com
7
+ * All rights reserved.
8
+ *
9
+ * https://github.com/client9/stringencoders/
10
+ *
11
+ * Released under MIT license. See LICENSE for details.
12
+ * </pre>
13
+ *
14
+ * This uses a "URL-safe" or "WEB-safe" encoding. THe standard
15
+ * base 64 encoding uses the characters '+', '/' and '=' have special
16
+ * restrictions when used inside a URL.
17
+ *
18
+ * This uses "+" to "-", "/" to "_", and "=" to "." as the replacement
19
+ * alphabet.
20
+ *
21
+ * It's easy to change this to use "URL safe" characters and to remove
22
+ * padding. See the modp_b64.c source code for details.
23
+ *
24
+ */
25
+
26
+ #ifndef COM_MODP_STRINGENCODERS_B64R
27
+ #define COM_MODP_STRINGENCODERS_B64R
28
+
29
+ #ifdef __cplusplus
30
+ #define BEGIN_C extern "C" {
31
+ #define END_C }
32
+ #else
33
+ #define BEGIN_C
34
+ #define END_C
35
+ #endif
36
+
37
+ BEGIN_C
38
+ #include "modp_stdint.h"
39
+
40
+ /**
41
+ * Encode a raw binary string into web-safe base 64.
42
+ * \param[out] dest should be allocated by the caller to contain
43
+ * at least modp_b64w_encode_len(len) bytes (see below)
44
+ * This will contain the null-terminated b64w encoded result
45
+ * \param[in] src contains the bytes
46
+ * \param[in] len contains the number of bytes in the src
47
+ * \return length of the destination string plus the ending null byte
48
+ * i.e. the result will be equal to strlen(dest) + 1
49
+ *
50
+ * Example
51
+ *
52
+ * \code
53
+ * char* src = ...;
54
+ * int srclen = ...; //the length of number of bytes in src
55
+ * char* dest = (char*) malloc(modp_b64w_encode_len);
56
+ * int len = modp_b64w_encode(dest, src, sourcelen);
57
+ * if (len == -1) {
58
+ * printf("Error\n");
59
+ * } else {
60
+ * printf("b64w = %s\n", dest);
61
+ * }
62
+ * \endcode
63
+ *
64
+ */
65
+ size_t modp_b64r_encode(char* dest, const char* src, size_t len);
66
+
67
+ /**
68
+ * Decode a web-safe base64 encoded string
69
+ *
70
+ * \param[out] dest should be allocated by the caller to contain at least
71
+ * len * 3 / 4 bytes.
72
+ * \param[in] src should contain exactly len bytes of b64r characters.
73
+ * if src contains -any- non-base characters (such as white
74
+ * space, -1 is returned.
75
+ * \param[in] len is the length of src
76
+ *
77
+ * \return the length (strlen) of the output, or -1 if unable to
78
+ * decode
79
+ *
80
+ * \code
81
+ * char* src = ...;
82
+ * int srclen = ...; // or if you don't know use strlen(src)
83
+ * char* dest = (char*) malloc(modp_b64r_decode_len(srclen));
84
+ * int len = modp_b64r_decode(dest, src, sourcelen);
85
+ * if (len == -1) { error }
86
+ * \endcode
87
+ */
88
+ size_t modp_b64r_decode(char* dest, const char* src, size_t len);
89
+
90
+ /**
91
+ * Given a source string of length len, this returns the amount of
92
+ * memory the destination string should have.
93
+ *
94
+ * remember, this is integer math
95
+ * 3 bytes turn into 4 chars
96
+ * ceiling[len / 3] * 4 + 1
97
+ *
98
+ * +1 is for any extra null.
99
+ */
100
+ #define modp_b64r_encode_len(A) ((A + 2) / 3 * 4 + 1)
101
+
102
+ /**
103
+ * Given a base64 string of length len,
104
+ * this returns the amount of memory required for output string
105
+ * It maybe be more than the actual number of bytes written.
106
+ * NOTE: remember this is integer math
107
+ * this allocates a bit more memory than traditional versions of b64r
108
+ * decode 4 chars turn into 3 bytes
109
+ * floor[len * 3/4] + 2
110
+ */
111
+ #define modp_b64r_decode_len(A) (A / 4 * 3 + 2)
112
+
113
+ /**
114
+ * Will return the strlen of the output from encoding.
115
+ * This may be less than the required number of bytes allocated.
116
+ *
117
+ * This allows you to 'deserialized' a struct
118
+ * \code
119
+ * char* b64rencoded = "...";
120
+ * int len = strlen(b64rencoded);
121
+ *
122
+ * struct datastuff foo;
123
+ * if (modp_b64r_encode_strlen(sizeof(struct datastuff)) != len) {
124
+ * // wrong size
125
+ * return false;
126
+ * } else {
127
+ * // safe to do;
128
+ * if (modp_b64r_decode((char*) &foo, b64rencoded, len) == -1) {
129
+ * // bad characters
130
+ * return false;
131
+ * }
132
+ * }
133
+ * // foo is filled out now
134
+ * \endcode
135
+ */
136
+ #define modp_b64r_encode_strlen(A) ((A + 2) / 3 * 4)
137
+
138
+ END_C
139
+
140
+ #ifdef __cplusplus
141
+ #include <cstring>
142
+ #include <string>
143
+
144
+ namespace modp {
145
+
146
+ /** \brief b64r encode a cstr with len
147
+ *
148
+ * \param[in] s the input string to encode
149
+ * \param[in] len the length of the input string
150
+ * \return a newly allocated b64r string. Empty if failed.
151
+ */
152
+ inline std::string b64r_encode(const char* s, size_t len)
153
+ {
154
+ std::string x(modp_b64r_encode_len(len), '\0');
155
+ size_t d = modp_b64r_encode(const_cast<char*>(x.data()), s,
156
+ static_cast<int>(len));
157
+ if (d == (size_t)-1) {
158
+ x.clear();
159
+ } else {
160
+ x.erase(d, std::string::npos);
161
+ }
162
+ return x;
163
+ }
164
+
165
+ /** \brief b64r encode a cstr
166
+ *
167
+ * \param[in] s the input string to encode
168
+ * \return a newly allocated b64r string. Empty if failed.
169
+ */
170
+ inline std::string b64r_encode(const char* s)
171
+ {
172
+ return b64r_encode(s, static_cast<int>(strlen(s)));
173
+ }
174
+
175
+ /** \brief b64r encode a const std::string
176
+ *
177
+ * \param[in] s the input string to encode
178
+ * \return a newly allocated b64r string. Empty if failed.
179
+ */
180
+ inline std::string b64r_encode(const std::string& s)
181
+ {
182
+ return b64r_encode(s.data(), s.size());
183
+ }
184
+
185
+ /** \brief self-modifing b64r encode
186
+ *
187
+ * web-safe base 64 decode a string (self-modifing)
188
+ * On failure, the string is empty.
189
+ *
190
+ * \param[in,out] s the string to be decoded
191
+ * \return a reference to the input string
192
+ */
193
+ inline std::string& b64r_encode(std::string& s)
194
+ {
195
+ std::string x(b64r_encode(s.data(), s.size()));
196
+ s.swap(x);
197
+ return s;
198
+ }
199
+
200
+ inline std::string b64r_decode(const char* src, size_t len)
201
+ {
202
+ std::string x(modp_b64r_decode_len(len) + 1, '\0');
203
+ size_t d = modp_b64r_decode(const_cast<char*>(x.data()), src,
204
+ static_cast<int>(len));
205
+ if (d == (size_t)-1) {
206
+ x.clear();
207
+ } else {
208
+ x.erase(d, std::string::npos);
209
+ }
210
+ return x;
211
+ }
212
+
213
+ inline std::string b64r_decode(const char* src)
214
+ {
215
+ return b64r_decode(src, strlen(src));
216
+ }
217
+
218
+ /**
219
+ * base 64 decode a string (self-modifing)
220
+ * On failure, the string is empty.
221
+ *
222
+ * This function is for C++ only (duh)
223
+ *
224
+ * \param[in,out] s the string to be decoded
225
+ * \return a reference to the input string
226
+ */
227
+ inline std::string& b64r_decode(std::string& s)
228
+ {
229
+ std::string x(b64r_decode(s.data(), s.size()));
230
+ s.swap(x);
231
+ return s;
232
+ }
233
+
234
+ inline std::string b64r_decode(const std::string& s)
235
+ {
236
+ return b64r_decode(s.data(), s.size());
237
+ }
238
+ }
239
+
240
+ #endif /* __cplusplus */
241
+
242
+ #endif /* MODP_B64R */