b58 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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +6 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +8 -0
  8. data/Gemfile.lock +37 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +44 -0
  11. data/Rakefile +14 -0
  12. data/b58.gemspec +28 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +8 -0
  15. data/ext/b58/b58.c +126 -0
  16. data/ext/b58/b58.h +6 -0
  17. data/ext/b58/extconf.rb +14 -0
  18. data/ext/libbase58/.gitignore +25 -0
  19. data/ext/libbase58/.travis.yml +48 -0
  20. data/ext/libbase58/AUTHORS +2 -0
  21. data/ext/libbase58/COPYING +19 -0
  22. data/ext/libbase58/INSTALL +20 -0
  23. data/ext/libbase58/Makefile.am +44 -0
  24. data/ext/libbase58/README.md +66 -0
  25. data/ext/libbase58/autogen.sh +11 -0
  26. data/ext/libbase58/base58.c +205 -0
  27. data/ext/libbase58/clitool.c +130 -0
  28. data/ext/libbase58/configure.ac +49 -0
  29. data/ext/libbase58/libbase58.h +23 -0
  30. data/ext/libbase58/libbase58.pc.in +10 -0
  31. data/ext/libbase58/tests/decode-b58c-fail.sh +2 -0
  32. data/ext/libbase58/tests/decode-b58c-null.sh +3 -0
  33. data/ext/libbase58/tests/decode-b58c-toolong.sh +2 -0
  34. data/ext/libbase58/tests/decode-b58c-tooshort.sh +2 -0
  35. data/ext/libbase58/tests/decode-b58c.sh +3 -0
  36. data/ext/libbase58/tests/decode-highbit-prefix.sh +3 -0
  37. data/ext/libbase58/tests/decode-highbit.sh +3 -0
  38. data/ext/libbase58/tests/decode-small.sh +3 -0
  39. data/ext/libbase58/tests/decode-zero.sh +3 -0
  40. data/ext/libbase58/tests/decode.sh +3 -0
  41. data/ext/libbase58/tests/encode-b58c-high.sh +3 -0
  42. data/ext/libbase58/tests/encode-b58c.sh +3 -0
  43. data/ext/libbase58/tests/encode-fail.sh +3 -0
  44. data/ext/libbase58/tests/encode-neg-index.sh +4 -0
  45. data/ext/libbase58/tests/encode-small.sh +3 -0
  46. data/ext/libbase58/tests/encode.sh +3 -0
  47. data/lib/b58.rb +7 -0
  48. data/lib/b58/version.rb +3 -0
  49. metadata +93 -0
@@ -0,0 +1,25 @@
1
+ *~
2
+ *.pc
3
+ *.la
4
+ *.o
5
+ libtool
6
+ ltmain.sh
7
+ missing
8
+ install-sh
9
+ depcomp
10
+ configure
11
+ config.*
12
+ *.lo
13
+ autom4te.cache
14
+ ar-lib
15
+ test-driver
16
+ aclocal.m4
17
+ Makefile
18
+ Makefile.in
19
+ .deps
20
+ *.log
21
+ .libs
22
+ ii
23
+ *.tar*
24
+ base58
25
+ tests/*.trs
@@ -0,0 +1,48 @@
1
+ os: linux
2
+ language: c
3
+ compiler: gcc
4
+ sudo: false
5
+ matrix:
6
+ include:
7
+ - compiler: ": Complete"
8
+ env: CONFIGURE_OPTS="--enable-tool --enable-static --enable-shared" MAKE_CHECK=1
9
+ addons:
10
+ apt:
11
+ packages:
12
+ - build-essential
13
+ - libgcrypt11-dev
14
+ - compiler: ": No tool/tests"
15
+ env: CONFIGURE_OPTS="--disable-tool --enable-static --enable-shared"
16
+ addons:
17
+ apt:
18
+ packages:
19
+ - build-essential
20
+ - compiler: ": Win32 - No tool/tests"
21
+ env: CONFIGURE_OPTS="--disable-tool --host=i686-w64-mingw32 --enable-static --enable-shared"
22
+ addons:
23
+ apt:
24
+ packages:
25
+ - gcc-mingw-w64-i686
26
+ - binutils-mingw-w64-i686
27
+ - mingw-w64-i686-dev
28
+ - compiler: ": Win64 - No tool/tests"
29
+ env: CONFIGURE_OPTS="--disable-tool --host=x86_64-w64-mingw32 --enable-static --enable-shared"
30
+ addons:
31
+ apt:
32
+ packages:
33
+ - gcc-mingw-w64-x86-64
34
+ - binutils-mingw-w64-x86-64
35
+ - mingw-w64-x86-64-dev
36
+ exclude:
37
+ - compiler: gcc
38
+ install:
39
+ - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi
40
+ - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi
41
+ script:
42
+ - unset CC
43
+ - ./autogen.sh
44
+ - ./configure $CONFIGURE_OPTS || tail -n 1000 config.log
45
+ - make
46
+ - test -z "$MAKE_CHECK" || make check
47
+ - make install DESTDIR=$PWD/ii
48
+ - cd ii && find
@@ -0,0 +1,2 @@
1
+ Luke Dashjr <luke-jr+libbase58@utopios.org>
2
+ Huang Le <4tarhl@gmail.com>
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2014 Luke Dashjr
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+ Installation
2
+ --------------------
3
+ # Install libgcrypt first, e.g. via `brew install libgcrypt` on OS X or libgcrypt-dev on Linux
4
+ # Generate the final build scripts
5
+ ./autogen.sh
6
+ # Build the CLI and library
7
+ ./configure && make
8
+
9
+ Dependencies
10
+ --------------------
11
+ Many of the test scripts depend on the "xxd" tool to convert between hexadecimal and binary.
12
+ If this tool is not installed on your Operating System, you can probably get it as part of
13
+ the "vim" editor from https://www.vim.org/ or by installing the vim-share package.
14
+
15
+ Troubleshooting
16
+ --------------------
17
+ If libgcrypt isn't found after install, set AM_PATH_LIBGCRYPT env var to libgcrypt path
18
+ prior to running autogen.sh. For example, on OS X with ver 1.7.6:
19
+
20
+ export AM_PATH_LIBGCRYPT="/usr/local/Cellar/libgcrypt/1.7.6/lib"
@@ -0,0 +1,44 @@
1
+ # Copyright 2014 Luke Dashjr
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify it
4
+ # under the terms of the standard MIT license. See COPYING for more details.
5
+
6
+ lib_LTLIBRARIES = libbase58.la
7
+ libbase58_la_SOURCES = base58.c
8
+ libbase58_la_LDFLAGS = -version-info $(LIBBASE58_SO_VERSION) -no-undefined
9
+
10
+ libbase58_includedir = $(includedir)
11
+ libbase58_include_HEADERS = libbase58.h
12
+
13
+ pkgconfigdir = $(libdir)/pkgconfig
14
+ pkgconfig_DATA = libbase58.pc
15
+
16
+ dist_noinst_SCRIPTS = autogen.sh
17
+ dist_doc_DATA = AUTHORS COPYING INSTALL README.md
18
+
19
+ if USE_TOOL
20
+ bin_PROGRAMS = base58
21
+ base58_SOURCES = clitool.c
22
+ base58_CFLAGS = $(LIBGCRYPT_CFLAGS)
23
+ base58_LDADD = libbase58.la $(LIBGCRYPT_LIBS)
24
+
25
+ TESTS = \
26
+ tests/decode.sh \
27
+ tests/decode-b58c.sh \
28
+ tests/decode-b58c-fail.sh \
29
+ tests/decode-b58c-null.sh \
30
+ tests/decode-b58c-toolong.sh \
31
+ tests/decode-b58c-tooshort.sh \
32
+ tests/decode-small.sh \
33
+ tests/decode-zero.sh \
34
+ tests/encode.sh \
35
+ tests/encode-b58c.sh \
36
+ tests/encode-b58c-high.sh \
37
+ tests/encode-fail.sh \
38
+ tests/encode-neg-index.sh \
39
+ tests/encode-small.sh
40
+ SH_LOG_COMPILER = /bin/sh
41
+ AM_TESTS_ENVIRONMENT = PATH='$(abs_top_builddir)':"$$PATH"; export PATH;
42
+ TESTS_ENVIRONMENT = $(AM_TESTS_ENVIRONMENT)
43
+ endif
44
+ TEST_EXTENSIONS = .sh
@@ -0,0 +1,66 @@
1
+ Initialisation
2
+ --------------
3
+
4
+ Before you can use libbase58 for base58check, you must provide a SHA256
5
+ function. The required function signature is:
6
+
7
+ bool my_sha256(void *digest, const void *data, size_t datasz)
8
+
9
+ Simply assign your function to b58_sha256_impl:
10
+
11
+ b58_sha256_impl = my_sha256;
12
+
13
+ This is only required if base58check is used. Raw base58 does not need SHA256.
14
+
15
+
16
+ Decoding Base58
17
+ ---------------
18
+
19
+ Simply allocate a buffer to store the binary data in, and set a variable with
20
+ the buffer size, and call the b58tobin function:
21
+
22
+ bool b58tobin(void *bin, size_t *binsz, const char *b58, size_t b58sz)
23
+
24
+ The "canonical" base58 byte length will be assigned to binsz on success, which
25
+ may be larger than the actual buffer if the input has many leading zeros.
26
+ Regardless of the canonical byte length, the full binary buffer will be used.
27
+ If b58sz is zero, it will be initialised with strlen(b58); note that a true
28
+ zero-length base58 string is not supported here.
29
+
30
+
31
+ Validating Base58Check
32
+ ----------------------
33
+
34
+ After calling b58tobin, you can validate base58check data using the b58check
35
+ function:
36
+
37
+ int b58check(const void *bin, size_t binsz, const char *b58, size_t b58sz)
38
+
39
+ Call it with the same buffers used for b58tobin. If the return value is
40
+ negative, an error occurred. Otherwise, the return value is the base58check
41
+ "version" byte from the decoded data.
42
+
43
+
44
+ Encoding Base58
45
+ ---------------
46
+
47
+ Allocate a string to store the base58 content, create a size_t variable with the
48
+ size of that allocation, and call:
49
+
50
+ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
51
+
52
+ Note that you must pass a pointer to the string size variable, not the size
53
+ itself. When b58enc returns, the variable will be modified to contain the actual
54
+ number of bytes used (including the null terminator). If encoding fails for any
55
+ reason, or if the string buffer is not large enough for the result, b58enc will
56
+ return false. Otherwise, it returns true to indicate success.
57
+
58
+
59
+ Encoding Base58Check
60
+ --------------------
61
+
62
+ Targeting base58check is done similarly to raw base58 encoding, but you must
63
+ also provide a version byte:
64
+
65
+ bool b58check_enc(char *b58c, size_t *b58c_sz, uint8_t ver,
66
+ const void *data, size_t datasz)
@@ -0,0 +1,11 @@
1
+ #!/bin/sh -e
2
+ # Written by Luke Dashjr in 2012
3
+ # This program is released under the terms of the Creative Commons "CC0 1.0 Universal" license and/or copyright waiver.
4
+
5
+ if test -z "$srcdir"; then
6
+ srcdir=`dirname "$0"`
7
+ if test -z "$srcdir"; then
8
+ srcdir=.
9
+ fi
10
+ fi
11
+ autoreconf --force --install --verbose "$srcdir"
@@ -0,0 +1,205 @@
1
+ /*
2
+ * Copyright 2012-2014 Luke Dashjr
3
+ *
4
+ * This program is free software; you can redistribute it and/or modify it
5
+ * under the terms of the standard MIT license. See COPYING for more details.
6
+ */
7
+
8
+ #ifndef WIN32
9
+ #include <arpa/inet.h>
10
+ #else
11
+ #include <winsock2.h>
12
+ #endif
13
+
14
+ #include <stdbool.h>
15
+ #include <stddef.h>
16
+ #include <stdint.h>
17
+ #include <string.h>
18
+
19
+ #include "libbase58.h"
20
+
21
+ bool (*b58_sha256_impl)(void *, const void *, size_t) = NULL;
22
+
23
+ static const int8_t b58digits_map[] = {
24
+ -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
25
+ -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
26
+ -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
27
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
28
+ -1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
29
+ 22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
30
+ -1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
31
+ 47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
32
+ };
33
+
34
+ typedef uint64_t b58_maxint_t;
35
+ typedef uint32_t b58_almostmaxint_t;
36
+ #define b58_almostmaxint_bits (sizeof(b58_almostmaxint_t) * 8)
37
+ static const b58_almostmaxint_t b58_almostmaxint_mask = ((((b58_maxint_t)1) << b58_almostmaxint_bits) - 1);
38
+
39
+ bool b58tobin(void *bin, size_t *binszp, const char *b58, size_t b58sz)
40
+ {
41
+ size_t binsz = *binszp;
42
+ const unsigned char *b58u = (void*)b58;
43
+ unsigned char *binu = bin;
44
+ size_t outisz = (binsz + sizeof(b58_almostmaxint_t) - 1) / sizeof(b58_almostmaxint_t);
45
+ b58_almostmaxint_t outi[outisz];
46
+ b58_maxint_t t;
47
+ b58_almostmaxint_t c;
48
+ size_t i, j;
49
+ uint8_t bytesleft = binsz % sizeof(b58_almostmaxint_t);
50
+ b58_almostmaxint_t zeromask = bytesleft ? (b58_almostmaxint_mask << (bytesleft * 8)) : 0;
51
+ unsigned zerocount = 0;
52
+
53
+ if (!b58sz)
54
+ b58sz = strlen(b58);
55
+
56
+ for (i = 0; i < outisz; ++i) {
57
+ outi[i] = 0;
58
+ }
59
+
60
+ // Leading zeros, just count
61
+ for (i = 0; i < b58sz && b58u[i] == '1'; ++i)
62
+ ++zerocount;
63
+
64
+ for ( ; i < b58sz; ++i)
65
+ {
66
+ if (b58u[i] & 0x80)
67
+ // High-bit set on invalid digit
68
+ return false;
69
+ if (b58digits_map[b58u[i]] == -1)
70
+ // Invalid base58 digit
71
+ return false;
72
+ c = (unsigned)b58digits_map[b58u[i]];
73
+ for (j = outisz; j--; )
74
+ {
75
+ t = ((b58_maxint_t)outi[j]) * 58 + c;
76
+ c = t >> b58_almostmaxint_bits;
77
+ outi[j] = t & b58_almostmaxint_mask;
78
+ }
79
+ if (c)
80
+ // Output number too big (carry to the next int32)
81
+ return false;
82
+ if (outi[0] & zeromask)
83
+ // Output number too big (last int32 filled too far)
84
+ return false;
85
+ }
86
+
87
+ j = 0;
88
+ if (bytesleft) {
89
+ for (i = bytesleft; i > 0; --i) {
90
+ *(binu++) = (outi[0] >> (8 * (i - 1))) & 0xff;
91
+ }
92
+ ++j;
93
+ }
94
+
95
+ for (; j < outisz; ++j)
96
+ {
97
+ for (i = sizeof(*outi); i > 0; --i) {
98
+ *(binu++) = (outi[j] >> (8 * (i - 1))) & 0xff;
99
+ }
100
+ }
101
+
102
+ // Count canonical base58 byte count
103
+ binu = bin;
104
+ for (i = 0; i < binsz; ++i)
105
+ {
106
+ if (binu[i])
107
+ break;
108
+ --*binszp;
109
+ }
110
+ *binszp += zerocount;
111
+
112
+ return true;
113
+ }
114
+
115
+ static
116
+ bool my_dblsha256(void *hash, const void *data, size_t datasz)
117
+ {
118
+ uint8_t buf[0x20];
119
+ return b58_sha256_impl(buf, data, datasz) && b58_sha256_impl(hash, buf, sizeof(buf));
120
+ }
121
+
122
+ int b58check(const void *bin, size_t binsz, const char *base58str, size_t b58sz)
123
+ {
124
+ unsigned char buf[32];
125
+ const uint8_t *binc = bin;
126
+ unsigned i;
127
+ if (binsz < 4)
128
+ return -4;
129
+ if (!my_dblsha256(buf, bin, binsz - 4))
130
+ return -2;
131
+ if (memcmp(&binc[binsz - 4], buf, 4))
132
+ return -1;
133
+
134
+ // Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end)
135
+ for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i)
136
+ {} // Just finding the end of zeros, nothing to do in loop
137
+ if (binc[i] == '\0' || base58str[i] == '1')
138
+ return -3;
139
+
140
+ return binc[0];
141
+ }
142
+
143
+ static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
144
+
145
+ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
146
+ {
147
+ const uint8_t *bin = data;
148
+ int carry;
149
+ size_t i, j, high, zcount = 0;
150
+ size_t size;
151
+
152
+ while (zcount < binsz && !bin[zcount])
153
+ ++zcount;
154
+
155
+ size = (binsz - zcount) * 138 / 100 + 1;
156
+ uint8_t buf[size];
157
+ memset(buf, 0, size);
158
+
159
+ for (i = zcount, high = size - 1; i < binsz; ++i, high = j)
160
+ {
161
+ for (carry = bin[i], j = size - 1; (j > high) || carry; --j)
162
+ {
163
+ carry += 256 * buf[j];
164
+ buf[j] = carry % 58;
165
+ carry /= 58;
166
+ if (!j) {
167
+ // Otherwise j wraps to maxint which is > high
168
+ break;
169
+ }
170
+ }
171
+ }
172
+
173
+ for (j = 0; j < size && !buf[j]; ++j);
174
+
175
+ if (*b58sz <= zcount + size - j)
176
+ {
177
+ *b58sz = zcount + size - j + 1;
178
+ return false;
179
+ }
180
+
181
+ if (zcount)
182
+ memset(b58, '1', zcount);
183
+ for (i = zcount; j < size; ++i, ++j)
184
+ b58[i] = b58digits_ordered[buf[j]];
185
+ b58[i] = '\0';
186
+ *b58sz = i + 1;
187
+
188
+ return true;
189
+ }
190
+
191
+ bool b58check_enc(char *b58c, size_t *b58c_sz, uint8_t ver, const void *data, size_t datasz)
192
+ {
193
+ uint8_t buf[1 + datasz + 0x20];
194
+ uint8_t *hash = &buf[1 + datasz];
195
+
196
+ buf[0] = ver;
197
+ memcpy(&buf[1], data, datasz);
198
+ if (!my_dblsha256(hash, buf, datasz + 1))
199
+ {
200
+ *b58c_sz = 0;
201
+ return false;
202
+ }
203
+
204
+ return b58enc(b58c, b58c_sz, buf, 1 + datasz + 4);
205
+ }