commit f703579360abfa80d15e878944dd8c2c74991a2d Author: Luke Dashjr Date: Sun Aug 17 11:29:46 2014 +0000 Initial import of code from libblkmaker diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b1f046f --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +*~ +*.pc +*.la +*.o +libtool +ltmain.sh +missing +install-sh +depcomp +configure +config.* +*.lo +autom4te.cache +ar-lib +aclocal.m4 +Makefile +Makefile.in +.deps +.libs +ii +*.tar* diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..4fdf44e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,16 @@ +# Copyright 2014 Luke Dashjr +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the standard MIT license. See COPYING for more details. + +lib_LTLIBRARIES = libbase58.la +libbase58_la_SOURCES = base58.c +libbase58_la_LDFLAGS = -version-info $(LIBBASE58_SO_VERSION) -no-undefined + +libbase58_includedir = $(includedir) +libbase58_include_HEADERS = base58.h + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libbase58.pc + +dist_noinst_SCRIPTS = autogen.sh diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..0e2f2d1 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,11 @@ +#!/bin/sh -e +# Written by Luke Dashjr in 2012 +# This program is released under the terms of the Creative Commons "CC0 1.0 Universal" license and/or copyright waiver. + +if test -z "$srcdir"; then + srcdir=`dirname "$0"` + if test -z "$srcdir"; then + srcdir=. + fi +fi +autoreconf --force --install --verbose "$srcdir" diff --git a/base58.c b/base58.c new file mode 100644 index 0000000..ab26440 --- /dev/null +++ b/base58.c @@ -0,0 +1,112 @@ +/* + * Copyright 2012 Luke Dashjr + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the standard MIT license. See COPYING for more details. + */ + +#ifndef WIN32 +#include +#else +#include +#endif + +#include +#include +#include + +bool (*blkmk_sha256_impl)(void *, const void *, size_t) = NULL; + +static const int8_t b58digits[] = { + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1, + -1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1, + 22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1, + -1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46, + 47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1, +}; + +bool _blkmk_b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz) { + const unsigned char *b58u = (void*)b58; + unsigned char *binu = bin; + size_t outisz = (binsz + 3) / 4; + uint32_t outi[outisz]; + uint64_t t; + uint32_t c; + size_t i, j; + uint8_t bytesleft = binsz % 4; + uint32_t zeromask = ~((1 << ((bytesleft) * 8)) - 1); + + if (!b58sz) + b58sz = strlen(b58); + + memset(outi, 0, outisz * sizeof(*outi)); + + for (i = 0; i < b58sz; ++i) + { + if (b58u[i] & 0x80) + // High-bit set on invalid digit + return false; + if (b58digits[b58u[i]] == -1) + // Invalid base58 digit + return false; + c = b58digits[b58u[i]]; + for (j = outisz; j--; ) + { + t = ((uint64_t)outi[j]) * 58 + c; + c = (t & 0x3f00000000) >> 32; + outi[j] = t & 0xffffffff; + } + if (c) + // Output number too big (carry to the next int32) + return false; + if (outi[0] & zeromask) + // Output number too big (last int32 filled too far) + return false; + } + + j = 0; + switch (bytesleft) { + case 3: + *(binu++) = (outi[0] & 0xff0000) >> 16; + case 2: + *(binu++) = (outi[0] & 0xff00) >> 8; + case 1: + *(binu++) = (outi[0] & 0xff); + ++j; + default: + break; + } + + for (; j < outisz; ++j) + { + *((uint32_t*)binu) = htonl(outi[j]); + binu += sizeof(uint32_t); + } + return true; +} + +static +bool _blkmk_dblsha256(void *hash, const void *data, size_t datasz) { + return blkmk_sha256_impl(hash, data, datasz) && blkmk_sha256_impl(hash, hash, 32); +} + +int _blkmk_b58check(void *bin, size_t binsz, const char *base58str) { + unsigned char buf[32]; + unsigned char *binc = bin; + unsigned i; + if (!_blkmk_dblsha256(buf, bin, binsz - 4)) + return -2; + if (memcmp(&binc[binsz - 4], buf, 4)) + return -1; + + // Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end) + for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i) + {} // Just finding the end of zeros, nothing to do in loop + if (binc[i] == '\0' || base58str[i] == '1') + return -3; + + return binc[0]; +} diff --git a/base58.h b/base58.h new file mode 100644 index 0000000..7e853fe --- /dev/null +++ b/base58.h @@ -0,0 +1,10 @@ +#ifndef LIBBASE58_H +#define LIBBASE58_H + +#include +#include + +extern bool _blkmk_b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz); +extern int _blkmk_b58check(void *bin, size_t binsz, const char *b58); + +#endif diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..248d2e4 --- /dev/null +++ b/configure.ac @@ -0,0 +1,28 @@ +dnl * Copyright 2012-2014 Luke Dashjr +dnl * +dnl * This program is free software; you can redistribute it and/or modify it +dnl * under the terms of the standard MIT license. See COPYING for more details. + +AC_INIT( + [libbase58], + [0.1], + [luke_libbase58@dashjr.org], + [libbase58]) +AC_PREREQ([2.59]) +AM_INIT_AUTOMAKE([1.12 -Wall dist-xz foreign]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AC_PROG_CC_C99 +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +LT_INIT([]) + +# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html +AC_SUBST([LIBBASE58_SO_VERSION], [0:0:0]) + +AC_CONFIG_FILES([Makefile + libbase58.pc:libbase58.pc.in +]) + +AC_CHECK_LIB([ws2_32], [strchr]) + +AC_OUTPUT diff --git a/libbase58.pc.in b/libbase58.pc.in new file mode 100644 index 0000000..0dd00b2 --- /dev/null +++ b/libbase58.pc.in @@ -0,0 +1,9 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: @PACKAGE_NAME@ +Description: Library for Bitcoin's base58 encoding. +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lbase58