Skip to content

Commit

Permalink
initial version 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
whitslack committed Oct 30, 2023
0 parents commit 72968ef
Show file tree
Hide file tree
Showing 13 changed files with 1,042 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/doxygen-gh-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: 'Deploy Doxygen docs to GitHub Pages'

on:
push:
branches:
- master

permissions:
contents: write

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3

- name: Install Doxygen
run: sudo apt-get install doxygen graphviz -y

- name: Generate documentation
run: doxygen

- name: Create .nojekyll
run: touch html/.nojekyll

- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: html
single-commit: true
35 changes: 35 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
*~
*.log
*.o
/doxygen-doc/
/base58check
/libbase58check.pc
/test

# http://www.gnu.org/software/automake

*.trs
Makefile
Makefile.in
.deps/
.dirstamp

# http://www.gnu.org/software/autoconf

/aclocal.m4
/autom4te.cache/
/build-aux/
/config.cache
/config.h
/config.h.in
/config.log
/config.status
/configure
/stamp-h1

# https://www.gnu.org/software/libtool/

*.la
*.lo
.libs/
/libtool
22 changes: 22 additions & 0 deletions Doxyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
PROJECT_NAME = $(PROJECT)
PROJECT_BRIEF = "Library for Base58Check encoding and decoding"
OUTPUT_DIRECTORY = $(DOCDIR)
OPTIMIZE_OUTPUT_FOR_C = YES
INLINE_SIMPLE_STRUCTS = YES
SHOW_INCLUDE_FILES = NO
SORT_BRIEF_DOCS = YES
WARN_NO_PARAMDOC = YES
FILE_PATTERNS = *.h \
*.dox
VERBATIM_HEADERS = NO
GENERATE_HTML = $(GENERATE_HTML)
GENERATE_HTMLHELP = $(GENERATE_HTMLHELP)
GENERATE_CHI = $(GENERATE_CHI)
GENERATE_LATEX = $(GENERATE_LATEX)
GENERATE_RTF = $(GENERATE_RTF)
GENERATE_MAN = $(GENERATE_MAN)
GENERATE_XML = $(GENERATE_XML)
MAN_LINKS = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = __attribute__(x)=
14 changes: 14 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004

Copyright (C) 2004 Sam Hocevar
22 rue de Plaisance, 75014 Paris, France
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. You just DO WHAT THE FUCK YOU WANT TO.

55 changes: 55 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
ACLOCAL_AMFLAGS = -I build-aux/m4

AM_CPPFLAGS =
if NDEBUG
AM_CPPFLAGS += -DNDEBUG
endif
COMMON_CFLAGS := -Wall -Wextra -Wcast-qual -Wconversion -Wdisabled-optimization -Wdouble-promotion -Wno-implicit-fallthrough -Wmissing-declarations -Wno-missing-field-initializers -Wpacked -Wno-parentheses -Wredundant-decls -Wno-sign-conversion $(addprefix -Wsuggest-attribute=,pure const noreturn malloc) -Wno-vla
AM_CFLAGS = $(COMMON_CFLAGS) $(addprefix -Werror=,implicit-function-declaration incompatible-pointer-types int-conversion)
AM_CXXFLAGS = $(COMMON_CFLAGS) -Wnoexcept -Wold-style-cast -Wsign-promo -Wsuggest-override -Wno-terminate -Wzero-as-null-pointer-constant

include_HEADERS = base58check.h

pkgconfig_DATA = libbase58check.pc
EXTRA_DIST = $(pkgconfig_DATA)

lib_LTLIBRARIES = libbase58check.la
libbase58check_la_SOURCES = libbase58check.c
libbase58check_la_CFLAGS = $(GMP_CFLAGS) $(OPENSSL_CFLAGS)
libbase58check_la_LIBADD = $(GMP_LIBS) $(OPENSSL_LIBS)
# How to update version-info:
# - oldprog+newlib and newprog+oldlib are both okay => +0:+1:+0
# - oldprog+newlib is okay, but newprog+oldlib won't work => +1:=0:+1
# - oldprog+newlib won't work => +1:=0:=0
libbase58check_la_LDFLAGS = -no-undefined -version-info 0:0:0

bin_PROGRAMS = base58check
base58check_SOURCES = base58check.c
base58check_LDADD = libbase58check.la

if BUILD_TESTS

check_PROGRAMS = test
test_SOURCES = test.cpp
test_CPPFLAGS = $(filter-out -DNDEBUG,$(AM_CPPFLAGS))
test_LDFLAGS = -no-install
test_LDADD = libbase58check.la

TESTS = $(check_PROGRAMS)
noinst_PROGRAMS = $(check_PROGRAMS)

else

check-local :
@! echo "You didn't enable the tests! Run './configure --enable-tests'." >&2

endif # BUILD_TESTS

@DX_RULES@
MOSTLYCLEANFILES = $(DX_CLEANFILES)

if BUILD_MANPAGES
man3_MANS = $(addprefix doxygen-doc/man/man3/,$(addsuffix .3,base58check.h \
$(shell sed -Ene 's/^((\w|\*)+\s+)+(\w+)\(.*$$/\3/p#)' $(srcdir)/base58check.h)))
$(man3_MANS) : doxygen-doc
endif
84 changes: 84 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# libbase58check
**Library for Base58Check encoding and decoding**

This simple C library has two primary functions, **`base58check_encode`** and **`base58check_decode`**. Please refer to the auto-generated [Doxygen documentation](https://whitslack.github.io/libbase58check/base58check_8h.html) for usage details.

There are also overloaded C++ convenience functions if you are writing in C++.

### Usage examples

Here's an example of generating a 256-bit private key and encoding it as Base58Check in Bitcoin's Wallet Import Format (WIF):
```cpp
#include <base58check.h>

#include <algorithm>
#include <array>
#include <iostream>
#include <random>
#include <ranges>

int main() {
// fill a 32-byte key from std::random_device
using random_t = std::random_device::result_type;
std::array<random_t, 32 / sizeof(random_t)> key;
std::random_device random;
std::ranges::generate(key, std::reference_wrapper(random));

// wrap the key between a 0x80 type byte and a 0x01 flag byte
std::array<std::byte, 34> bytes;
bytes[0] = std::byte { 0x80 };
std::ranges::copy(std::as_bytes(std::span(key)), bytes.begin() + 1);
bytes[33] = std::byte { 0x01 };

// Base58Check encode the wrapped key and print it out
std::cout << base58check::encode(bytes) << std::endl;
return 0;
}
```

And here's an example of decoding a Base58Check encoding from standard input:
```cpp
#include <base58check.h>

#include <iostream>
#include <sstream>

int main() {
// read all input from cin to EOF
std::ostringstream ss;
ss << std::cin.rdbuf();

// chop off any trailing newline character
auto str = std::move(ss).str();
if (str.ends_with('\n'))
str.pop_back();

// decode the Base58Check and output the raw bytes
auto bytes = base58check::decode(str);
std::cout.write(reinterpret_cast<const char *>(bytes.data()),
bytes.size()) << std::flush;

return 0;
}
```

### Building

1. Install the prerequisites — most/all of which you probably already have:

* [Autoconf](https://www.gnu.org/software/autoconf/)
* [Autoconf Archive](https://www.gnu.org/software/autoconf-archive/)
* [Automake](https://www.gnu.org/software/automake/)
* [GMP](https://gmplib.org/)
* [Libtool](https://www.gnu.org/software/libtool/)
* [OpenSSL](https://www.openssl.org/)
* [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/)

1. Then it's just your standard Autotools madness:

```
$ autoreconf -i
$ ./configure
$ make
$ sudo make install
```
72 changes: 72 additions & 0 deletions base58check.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#define _GNU_SOURCE

#include "base58check.h"

#include <err.h>
#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <sysexits.h>
#include <unistd.h>


static void print_usage() {
fprintf(stderr, "usage: %s [-d]\n\n"
"Reads data from stdin, encodes it in Base58Check, and writes the encoding to\n"
"stdout. Specify -d to decode instead.\n",
program_invocation_short_name);
}

int main(int argc, char *argv[]) {
static const struct option longopts[] = {
{ .name = "decode", .has_arg = no_argument, .val = 'd' },
{ .name = "help", .has_arg = no_argument, .val = 1 },
{ .name = "version", .has_arg = no_argument, .val = 2 },
{ }
};
bool decode = false;
for (int opt; (opt = getopt_long(argc, argv, "d", longopts, NULL)) >= 0;) {
switch (opt) {
case 1:
print_usage();
return EX_OK;
case 2:
printf("base58check %s\n", VERSION);
return EX_OK;
case 'd':
decode = true;
break;
default:
print_usage();
return EX_USAGE;
}
}

unsigned char in[4096];
size_t n_in = 0;

for (size_t r; n_in < sizeof in && (r = fread(in + n_in, 1, sizeof in - n_in, stdin)) > 0; n_in += r);
if (ferror(stdin) || n_in == sizeof in)
return EX_IOERR;

unsigned char *out = NULL;
size_t n_out = 0;
if (decode) {
if (n_in && in[n_in - 1] == '\n')
in[--n_in] = '\0';
if (base58check_decode(&out, &n_out, (char *) in, n_in, 0))
errx(EX_DATAERR, "input was not a valid Base58Check encoding");
}
else {
n_out = 1;
if (base58check_encode((char **) &out, &n_out, in, n_in, 0))
return EX_UNAVAILABLE;
out[n_out++] = '\n';
}

if (fwrite(out, 1, n_out, stdout) < n_out)
return EX_IOERR;

return EX_OK;
}
Loading

0 comments on commit 72968ef

Please sign in to comment.