commit 37a2f72

V. Luna  ·  2026-10-07 06:24:59 +0000 UTC
parent bfa71e7
base64 encoding
5 files changed,  +395, -244
M xs.h
+8, -0
1@@ -0,0 +1,8 @@
2+My dictionary for this babygronks vibed out code 
3+
4+xs = "stb" wannabe single header library
5+sz = size of something
6+s = string
7+n = could literally be anything apparently
8+b = buffer?
9+
+61, -0
 1@@ -0,0 +1,61 @@
 2+#include <stdio.h>
 3+#include <stdlib.h>
 4+#include <string.h>
 5+
 6+#define MASK 0x3f
 7+#define PAD '='
 8+
 9+static const char b64_tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
10+int get_block_size(int size) {
11+        int block_size = 4096;
12+
13+        if (size < 256) {
14+                block_size = 32;
15+        } else if (size < 4096) {
16+                block_size = 256;
17+        }
18+
19+        return ((((size) + block_size) / block_size) * block_size);
20+}
21+
22+char* encode(const unsigned char* data, int size) {
23+        const int b64_bytes = 3;
24+        const int b64_chars = 4;
25+
26+        int output_len = ((size + b64_bytes - 1) / b64_bytes) * b64_chars;
27+        char* s = realloc(NULL, get_block_size(output_len + 1));
28+        
29+        int i = 0, j = 0;
30+        while (i + b64_bytes - 1 < size) {
31+                unsigned int v = (data[i] << 16) | (data[i + 1] << 8) | data[i + 2];
32+
33+                s[j++] = b64_tab[(v >> 18) & MASK];
34+                s[j++] = b64_tab[(v >> 12) & MASK];
35+                s[j++] = b64_tab[(v >> 6) & MASK];
36+                i += b64_bytes;
37+        }
38+
39+        if (i < size) {
40+                unsigned int v = data[i] << 16;
41+                int rem = size - i;
42+
43+                if (rem == 2) { v |= data[i + 1] << 8; }
44+
45+                s[j++] = b64_tab[(v >> 18) & MASK];
46+                s[j++] = b64_tab[(v >> 12) & MASK];
47+                s[j++] = (rem == 2) ? b64_tab[(v >> 6) & MASK] : PAD;
48+                s[j++] = PAD;
49+        }
50+
51+        s[j] = '\0';
52+        
53+        return s;
54+}
55+
56+int main(int argc, char* argv[]) {
57+        const char* s = "hello";
58+        const unsigned char* msg = (const unsigned char *)s;
59+
60+        char* code = encode(msg, strlen(s));
61+        printf("code: %s\n", code);
62+}
M xs.h
+1, -0
1@@ -247,6 +247,7 @@ void _xs_destroy(char **var)
2 }
3 
4 
5+/// Get block size
6 int _xs_blk_size(int sz)
7 /* calculates the block size */
8 {
+81, -0
 1@@ -0,0 +1,81 @@
 2+#ifndef _XS_BEARSSL_H
 3+#define _XS_BEARSSL_H
 4+
 5+#include "xs.h"
 6+
 7+#ifndef _XS_BASE64_H
 8+xs_str* xs_base64_enc(const xs_val *data, int size);
 9+#endif // _XS_BASE64_H
10+
11+#ifdef XS_IMPLEMENTATION
12+
13+#include "bearssl_rsa.h"
14+#include "bearssl_pem.h"
15+
16+#ifndef _XS_BASE64_H
17+/* *
18+ * Ok after reading the bearSSL code for a while I found they expose nothing for base64
19+ * encoding, they do mention it in the header files but they only use it internally for
20+ * their pem encoding and I can't even really copy the code because it's written in some
21+ * weird uxn like language that only Thomas Pornin (that is actually his last name lol)
22+ * knows.
23+ *
24+ * So that just leaves me to handroll the base64 encoding! Shrub I don't know why you 
25+ * meatride this lib so much but I hope this gets you to join minx cafe.
26+ * */
27+
28+#define MASK 0x3f
29+#define PAD '='
30+static const char b64_tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
31+
32+static int base64_val(int c) {
33+        if (c >= 'A' && c <= 'Z') return c - 'A';
34+        if (c >= 'a' && c <= 'z') return c - 'a' + 26;
35+        if (c >= '0' && c <= '9') return c - '0' + 52;
36+        if (c == '+') return 62;
37+        if (c == '/') return 63;
38+        return -1;
39+}
40+
41+xs_str* xs_base64_enc(const xs_val* data, int size) { // NOLINT
42+        const int b64_bytes = 3;
43+        const int b64_chars = 4;
44+
45+        const unsigned char *d = (const unsigned char *)data;
46+
47+        int output_len = ((size + b64_bytes - 1) / b64_bytes) * b64_chars;
48+        // thank you baby gronk for making this a macro so clangd would
49+        // bitch about this failing relentlessly you're the best
50+        xs_str* s = xs_realloc(NULL, _xs_blk_size(output_len + 1)); 
51+
52+        int i = 0, j = 0;
53+        while (i + b64_bytes - 1 < size) {
54+                unsigned int v = (d[i] << 16) | (d[i + 1] << 8) | d[i + 2];
55+
56+                s[j++] = b64_tab[(v >> 18) & MASK];
57+                s[j++] = b64_tab[(v >> 12) & MASK];
58+                s[j++] = b64_tab[(v >> 6) & MASK];
59+                i += b64_bytes;
60+        }
61+
62+        if (i < size) {
63+                unsigned int v = d[i] << 16;
64+                int rem = size - i;
65+
66+                if (rem == 2) { v |= d[i + 1] << 8; }
67+
68+                s[j++] = b64_tab[(v >> 18) & MASK];
69+                s[j++] = b64_tab[(v >> 12) & MASK];
70+                s[j++] = (rem == 2) ? b64_tab[(v >> 6) & MASK] : PAD;
71+                s[j++] = PAD;
72+        }
73+
74+        s[j] = '\0';
75+        
76+        return s;
77+}
78+#endif // _XS_BASE64_H
79+
80+#endif // XS_IMPLEMENTATION
81+
82+#endif // _XS_BEARSSL_H
+244, -244
  1@@ -1,245 +1,245 @@
  2 /* copyright (c) 2022 - 2026 grunfink et al. / MIT license */
  3-
  4-#ifndef _XS_OPENSSL_H
  5-
  6-#define _XS_OPENSSL_H
  7-
  8-#include "xs.h"
  9-#include "xs_hex.h"
 10-
 11-xs_str *_xs_digest(const xs_val *input, int size, const char *digest, int as_hex);
 12-
 13-#ifndef _XS_MD5_H
 14-#define xs_md5_hex(input, size)       _xs_digest(input, size, "md5",    1)
 15-#endif /* XS_MD5_H */
 16-
 17-#ifndef _XS_BASE64_H
 18-xs_str *xs_base64_enc(const xs_val *data, int sz);
 19-xs_val *xs_base64_dec(const xs_str *data, int *size);
 20-#endif /* XS_BASE64_H */
 21-
 22-#define xs_sha1_hex(input, size)      _xs_digest(input, size, "sha1",   1)
 23-#define xs_sha256_hex(input, size)    _xs_digest(input, size, "sha256", 1)
 24-#define xs_sha256_base64(input, size) _xs_digest(input, size, "sha256", 0)
 25-
 26-xs_dict *xs_evp_genkey(int bits);
 27-xs_str *xs_evp_sign(const char *secret, const char *mem, int size);
 28-int xs_evp_verify(const char *pubkey, const char *mem, int size, const char *b64sig);
 29-
 30-
 31-#ifdef XS_IMPLEMENTATION
 32-
 33-#include "openssl/rsa.h"
 34-#include "openssl/pem.h"
 35-#include "openssl/evp.h"
 36-
 37-
 38-#ifndef _XS_BASE64_H
 39-
 40-xs_str *xs_base64_enc(const xs_val *data, int sz)
 41-/* encodes data to base64 */
 42-{
 43-    BIO *mem, *b64;
 44-    BUF_MEM *bptr;
 45-
 46-    b64 = BIO_new(BIO_f_base64());
 47-    mem = BIO_new(BIO_s_mem());
 48-    b64 = BIO_push(b64, mem);
 49-
 50-    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
 51-
 52-    BIO_write(b64, data, sz);
 53-    BIO_flush(b64);
 54-    BIO_get_mem_ptr(b64, &bptr);
 55-
 56-    int n = bptr->length;
 57-    xs_str *s = xs_realloc(NULL, _xs_blk_size(n + 1));
 58-
 59-    memcpy(s, bptr->data, n);
 60-    s[n] = '\0';
 61-
 62-    BIO_free_all(b64);
 63-
 64-    return s;
 65-}
 66-
 67-
 68-xs_val *xs_base64_dec(const xs_str *data, int *size)
 69-/* decodes data from base64 */
 70-{
 71-    BIO *b64, *mem;
 72-
 73-    *size = strlen(data);
 74-
 75-    b64 = BIO_new(BIO_f_base64());
 76-    mem = BIO_new_mem_buf(data, *size);
 77-    b64 = BIO_push(b64, mem);
 78-
 79-    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
 80-
 81-    /* alloc a very big buffer */
 82-    xs_str *s = xs_realloc(NULL, *size);
 83-
 84-    *size = BIO_read(b64, s, *size);
 85-
 86-    /* adjust to current size */
 87-    s = xs_realloc(s, _xs_blk_size(*size + 1));
 88-    s[*size] = '\0';
 89-
 90-    BIO_free_all(b64);
 91-
 92-    return s;
 93-}
 94-
 95-#endif /* _XS_BASE64_H */
 96-
 97-
 98-xs_str *_xs_digest(const xs_val *input, int size, const char *digest, int as_hex)
 99-/* generic function for generating and encoding digests */
100-{
101-    const EVP_MD *md;
102-
103-    if ((md = EVP_get_digestbyname(digest)) == NULL)
104-        return NULL;
105-
106-    unsigned char output[1024];
107-    unsigned int out_size;
108-    EVP_MD_CTX *mdctx;
109-
110-    mdctx = EVP_MD_CTX_new();
111-    EVP_DigestInit_ex(mdctx, md, NULL);
112-    EVP_DigestUpdate(mdctx, input, size);
113-    EVP_DigestFinal_ex(mdctx, output, &out_size);
114-    EVP_MD_CTX_free(mdctx);
115-
116-    return as_hex ? xs_hex_enc   ((char *)output, out_size) :
117-                    xs_base64_enc((char *)output, out_size);
118-}
119-
120-
121-xs_dict *xs_evp_genkey(int bits)
122-/* generates an RSA keypair using the EVP interface */
123-{
124-    xs_dict *keypair = NULL;
125-    EVP_PKEY_CTX *ctx = NULL;
126-    EVP_PKEY *pkey = NULL;
127-
128-    if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL)
129-        return NULL;
130-
131-    if (EVP_PKEY_keygen_init(ctx) <= 0 ||
132-        EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0 ||
133-        EVP_PKEY_keygen(ctx, &pkey) <= 0)
134-        return NULL;
135-
136-    BIO *bs = BIO_new(BIO_s_mem());
137-    BIO *bp = BIO_new(BIO_s_mem());
138-    BUF_MEM *sptr;
139-    BUF_MEM *pptr;
140-
141-    PEM_write_bio_PrivateKey(bs, pkey, NULL, NULL, 0, 0, NULL);
142-    BIO_get_mem_ptr(bs, &sptr);
143-
144-    PEM_write_bio_PUBKEY(bp, pkey);
145-    BIO_get_mem_ptr(bp, &pptr);
146-
147-    keypair = xs_dict_new();
148-
149-    xs *secret = xs_str_new_sz(sptr->data, sptr->length);
150-    xs *public = xs_str_new_sz(pptr->data, pptr->length);
151-    keypair = xs_dict_append(keypair, "secret", secret);
152-    keypair = xs_dict_append(keypair, "public", public);
153-
154-    BIO_free(bs);
155-    BIO_free(bp);
156-
157-    EVP_PKEY_free(pkey);
158-    EVP_PKEY_CTX_free(ctx);
159-
160-    return keypair;
161-}
162-
163-
164-xs_str *xs_evp_sign(const char *secret, const char *mem, int size)
165-/* signs a memory block (secret is in PEM format) */
166-{
167-    xs_str *signature = NULL;
168-    BIO *b;
169-    unsigned char *sig;
170-    unsigned int sig_len;
171-    EVP_PKEY *pkey;
172-    EVP_MD_CTX *mdctx;
173-    const EVP_MD *md;
174-
175-    /* un-PEM the key */
176-    b = BIO_new_mem_buf(secret, strlen(secret));
177-    pkey = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL);
178-
179-    /* I've learnt all these magical incantations by watching
180-       the Python module code and the OpenSSL manual pages */
181-    /* Well, "learnt" may be an overstatement */
182-
183-    md = EVP_get_digestbyname("sha256");
184-
185-    mdctx = EVP_MD_CTX_new();
186-
187-    sig_len = EVP_PKEY_size(pkey);
188-    sig = xs_realloc(NULL, sig_len);
189-
190-    EVP_SignInit(mdctx, md);
191-    EVP_SignUpdate(mdctx, mem, size);
192-
193-    if (EVP_SignFinal(mdctx, sig, &sig_len, pkey) == 1)
194-        signature = xs_base64_enc((char *)sig, sig_len);
195-
196-    EVP_MD_CTX_free(mdctx);
197-    EVP_PKEY_free(pkey);
198-    BIO_free(b);
199-    xs_free(sig);
200-
201-    return signature;
202-}
203-
204-
205-int xs_evp_verify(const char *pubkey, const char *mem, int size, const char *b64sig)
206-/* verifies a base64 block, returns non-zero on ok */
207-{
208-    int r = 0;
209-    BIO *b;
210-    EVP_PKEY *pkey;
211-    EVP_MD_CTX *mdctx;
212-    const EVP_MD *md;
213-
214-    /* un-PEM the key */
215-    b = BIO_new_mem_buf(pubkey, strlen(pubkey));
216-    pkey = PEM_read_bio_PUBKEY(b, NULL, NULL, NULL);
217-
218-    md = EVP_get_digestbyname("sha256");
219-    mdctx = EVP_MD_CTX_new();
220-
221-    if (pkey != NULL) {
222-        xs *sig = NULL;
223-        int s_size;
224-
225-        /* de-base64 */
226-        sig = xs_base64_dec(b64sig,  &s_size);
227-
228-        if (sig != NULL) {
229-            EVP_VerifyInit(mdctx, md);
230-            EVP_VerifyUpdate(mdctx, mem, size);
231-
232-            r = EVP_VerifyFinal(mdctx, (unsigned char *)sig, s_size, pkey);
233-        }
234-    }
235-
236-    EVP_MD_CTX_free(mdctx);
237-    EVP_PKEY_free(pkey);
238-    BIO_free(b);
239-
240-    return r;
241-}
242-
243-
244-#endif /* XS_IMPLEMENTATION */
245-
246-#endif /* _XS_OPENSSL_H */
247+//
248+// #ifndef _XS_OPENSSL_H
249+//
250+// #define _XS_OPENSSL_H
251+//
252+// #include "xs.h"
253+// #include "xs_hex.h"
254+//
255+// xs_str *_xs_digest(const xs_val *input, int size, const char *digest, int as_hex);
256+//
257+// #ifndef _XS_MD5_H
258+// #define xs_md5_hex(input, size)       _xs_digest(input, size, "md5",    1)
259+// #endif /* XS_MD5_H */
260+//
261+// #ifndef _XS_BASE64_H
262+// xs_str *xs_base64_enc(const xs_val *data, int sz);
263+// xs_val *xs_base64_dec(const xs_str *data, int *size);
264+// #endif /* XS_BASE64_H */
265+//
266+// #define xs_sha1_hex(input, size)      _xs_digest(input, size, "sha1",   1)
267+// #define xs_sha256_hex(input, size)    _xs_digest(input, size, "sha256", 1)
268+// #define xs_sha256_base64(input, size) _xs_digest(input, size, "sha256", 0)
269+//
270+// xs_dict *xs_evp_genkey(int bits);
271+// xs_str *xs_evp_sign(const char *secret, const char *mem, int size);
272+// int xs_evp_verify(const char *pubkey, const char *mem, int size, const char *b64sig);
273+//
274+//
275+// #ifdef XS_IMPLEMENTATION
276+//
277+// #include "openssl/rsa.h"
278+// #include "openssl/pem.h"
279+// #include "openssl/evp.h"
280+//
281+//
282+// #ifndef _XS_BASE64_H
283+//
284+// xs_str *xs_base64_enc(const xs_val *data, int sz)
285+// /* encodes data to base64 */
286+// {
287+//     BIO *mem, *b64;
288+//     BUF_MEM *bptr;
289+//
290+//     b64 = BIO_new(BIO_f_base64());
291+//     mem = BIO_new(BIO_s_mem());
292+//     b64 = BIO_push(b64, mem);
293+//
294+//     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
295+//
296+//     BIO_write(b64, data, sz);
297+//     BIO_flush(b64);
298+//     BIO_get_mem_ptr(b64, &bptr);
299+//
300+//     int n = bptr->length;
301+//     xs_str *s = xs_realloc(NULL, _xs_blk_size(n + 1));
302+//
303+//     memcpy(s, bptr->data, n);
304+//     s[n] = '\0';
305+//
306+//     BIO_free_all(b64);
307+//
308+//     return s;
309+// }
310+//
311+//
312+// xs_val *xs_base64_dec(const xs_str *data, int *size)
313+// /* decodes data from base64 */
314+// {
315+//     BIO *b64, *mem;
316+//
317+//     *size = strlen(data);
318+//
319+//     b64 = BIO_new(BIO_f_base64());
320+//     mem = BIO_new_mem_buf(data, *size);
321+//     b64 = BIO_push(b64, mem);
322+//
323+//     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
324+//
325+//     /* alloc a very big buffer */
326+//     xs_str *s = xs_realloc(NULL, *size);
327+//
328+//     *size = BIO_read(b64, s, *size);
329+//
330+//     /* adjust to current size */
331+//     s = xs_realloc(s, _xs_blk_size(*size + 1));
332+//     s[*size] = '\0';
333+//
334+//     BIO_free_all(b64);
335+//
336+//     return s;
337+// }
338+//
339+// #endif /* _XS_BASE64_H */
340+//
341+//
342+// xs_str *_xs_digest(const xs_val *input, int size, const char *digest, int as_hex)
343+// /* generic function for generating and encoding digests */
344+// {
345+//     const EVP_MD *md;
346+//
347+//     if ((md = EVP_get_digestbyname(digest)) == NULL)
348+//         return NULL;
349+//
350+//     unsigned char output[1024];
351+//     unsigned int out_size;
352+//     EVP_MD_CTX *mdctx;
353+//
354+//     mdctx = EVP_MD_CTX_new();
355+//     EVP_DigestInit_ex(mdctx, md, NULL);
356+//     EVP_DigestUpdate(mdctx, input, size);
357+//     EVP_DigestFinal_ex(mdctx, output, &out_size);
358+//     EVP_MD_CTX_free(mdctx);
359+//
360+//     return as_hex ? xs_hex_enc   ((char *)output, out_size) :
361+//                     xs_base64_enc((char *)output, out_size);
362+// }
363+//
364+//
365+// xs_dict *xs_evp_genkey(int bits)
366+// /* generates an RSA keypair using the EVP interface */
367+// {
368+//     xs_dict *keypair = NULL;
369+//     EVP_PKEY_CTX *ctx = NULL;
370+//     EVP_PKEY *pkey = NULL;
371+//
372+//     if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL)
373+//         return NULL;
374+//
375+//     if (EVP_PKEY_keygen_init(ctx) <= 0 ||
376+//         EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0 ||
377+//         EVP_PKEY_keygen(ctx, &pkey) <= 0)
378+//         return NULL;
379+//
380+//     BIO *bs = BIO_new(BIO_s_mem());
381+//     BIO *bp = BIO_new(BIO_s_mem());
382+//     BUF_MEM *sptr;
383+//     BUF_MEM *pptr;
384+//
385+//     PEM_write_bio_PrivateKey(bs, pkey, NULL, NULL, 0, 0, NULL);
386+//     BIO_get_mem_ptr(bs, &sptr);
387+//
388+//     PEM_write_bio_PUBKEY(bp, pkey);
389+//     BIO_get_mem_ptr(bp, &pptr);
390+//
391+//     keypair = xs_dict_new();
392+//
393+//     xs *secret = xs_str_new_sz(sptr->data, sptr->length);
394+//     xs *public = xs_str_new_sz(pptr->data, pptr->length);
395+//     keypair = xs_dict_append(keypair, "secret", secret);
396+//     keypair = xs_dict_append(keypair, "public", public);
397+//
398+//     BIO_free(bs);
399+//     BIO_free(bp);
400+//
401+//     EVP_PKEY_free(pkey);
402+//     EVP_PKEY_CTX_free(ctx);
403+//
404+//     return keypair;
405+// }
406+//
407+//
408+// xs_str *xs_evp_sign(const char *secret, const char *mem, int size)
409+// /* signs a memory block (secret is in PEM format) */
410+// {
411+//     xs_str *signature = NULL;
412+//     BIO *b;
413+//     unsigned char *sig;
414+//     unsigned int sig_len;
415+//     EVP_PKEY *pkey;
416+//     EVP_MD_CTX *mdctx;
417+//     const EVP_MD *md;
418+//
419+//     /* un-PEM the key */
420+//     b = BIO_new_mem_buf(secret, strlen(secret));
421+//     pkey = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL);
422+//
423+//     /* I've learnt all these magical incantations by watching
424+//        the Python module code and the OpenSSL manual pages */
425+//     /* Well, "learnt" may be an overstatement */
426+//
427+//     md = EVP_get_digestbyname("sha256");
428+//
429+//     mdctx = EVP_MD_CTX_new();
430+//
431+//     sig_len = EVP_PKEY_size(pkey);
432+//     sig = xs_realloc(NULL, sig_len);
433+//
434+//     EVP_SignInit(mdctx, md);
435+//     EVP_SignUpdate(mdctx, mem, size);
436+//
437+//     if (EVP_SignFinal(mdctx, sig, &sig_len, pkey) == 1)
438+//         signature = xs_base64_enc((char *)sig, sig_len);
439+//
440+//     EVP_MD_CTX_free(mdctx);
441+//     EVP_PKEY_free(pkey);
442+//     BIO_free(b);
443+//     xs_free(sig);
444+//
445+//     return signature;
446+// }
447+//
448+//
449+// int xs_evp_verify(const char *pubkey, const char *mem, int size, const char *b64sig)
450+// /* verifies a base64 block, returns non-zero on ok */
451+// {
452+//     int r = 0;
453+//     BIO *b;
454+//     EVP_PKEY *pkey;
455+//     EVP_MD_CTX *mdctx;
456+//     const EVP_MD *md;
457+//
458+//     /* un-PEM the key */
459+//     b = BIO_new_mem_buf(pubkey, strlen(pubkey));
460+//     pkey = PEM_read_bio_PUBKEY(b, NULL, NULL, NULL);
461+//
462+//     md = EVP_get_digestbyname("sha256");
463+//     mdctx = EVP_MD_CTX_new();
464+//
465+//     if (pkey != NULL) {
466+//         xs *sig = NULL;
467+//         int s_size;
468+//
469+//         /* de-base64 */
470+//         sig = xs_base64_dec(b64sig,  &s_size);
471+//
472+//         if (sig != NULL) {
473+//             EVP_VerifyInit(mdctx, md);
474+//             EVP_VerifyUpdate(mdctx, mem, size);
475+//
476+//             r = EVP_VerifyFinal(mdctx, (unsigned char *)sig, s_size, pkey);
477+//         }
478+//     }
479+//
480+//     EVP_MD_CTX_free(mdctx);
481+//     EVP_PKEY_free(pkey);
482+//     BIO_free(b);
483+//
484+//     return r;
485+// }
486+//
487+//
488+// #endif /* XS_IMPLEMENTATION */
489+//
490+// #endif /* _XS_OPENSSL_H */