b58 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }