Skip to content

Commit

Permalink
support Blech32/Blech32m
Browse files Browse the repository at this point in the history
Note: The `--bech32m` option in the command-line utility is renamed to
`--modified`, but the old spelling, although now undocumented, is
retained for backward compatibility. Specifying both `-m`/`--modified`
and `-l`/`--blech` is allowed, but the historical `--bech32m` may not be
combined with `-l`/`--blech`.
  • Loading branch information
whitslack committed Mar 19, 2024
1 parent 9db7c45 commit 3bb870b
Show file tree
Hide file tree
Showing 11 changed files with 497 additions and 74 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*.o
/doxygen-doc/
/bech32
/bech32.1
/libbech32.pc
/test

Expand Down
2 changes: 1 addition & 1 deletion Doxyfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PROJECT_NAME = libbech32
PROJECT_BRIEF = "Library for Bech32/Bech32m encoding and decoding"
PROJECT_BRIEF = "Library for Bech32/Bech32m/Blech32/Blech32m encoding/decoding"
OUTPUT_DIRECTORY = $(DOCDIR)
OPTIMIZE_OUTPUT_FOR_C = YES
INLINE_SIMPLE_STRUCTS = YES
Expand Down
29 changes: 27 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ AM_CPPFLAGS =
if NDEBUG
AM_CPPFLAGS += -DNDEBUG
endif
if DISABLE_BLECH32
AM_CPPFLAGS += -DDISABLE_BLECH32
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
Expand All @@ -13,7 +16,15 @@ include_HEADERS = bech32.h
pkgconfig_DATA = libbech32.pc
EXTRA_DIST = $(pkgconfig_DATA)

dist_man_MANS = bech32.1
man_MANS = bech32.1
MOSTLYCLEANFILES = $(man_MANS)

bech32.1 : bech32.1.in
if DISABLE_BLECH32
sed -Ee '/^@@IF_BLECH32@@$$/,/^@@(ELSE|ENDIF)_BLECH32@@$$/d' -e '/^@@ENDIF_BLECH32@@$$/d' $< >$@
else
sed -Ee '/^@@ELSE_BLECH32@@$$/,/^@@ENDIF_BLECH32@@$$/d' -e '/^@@(END)?IF_BLECH32@@$$/d' $< >$@
endif

lib_LTLIBRARIES = libbech32.la
libbech32_la_SOURCES = libbech32.c
Expand Down Expand Up @@ -52,7 +63,7 @@ check-local:
endif # BUILD_TESTS

@DX_RULES@
MOSTLYCLEANFILES = $(DX_CLEANFILES)
MOSTLYCLEANFILES += $(DX_CLEANFILES)

if BUILD_MANPAGES
man3_MANS = $(addprefix doxygen-doc/man/man3/,$(addsuffix .3,bech32.h \
Expand All @@ -64,7 +75,21 @@ endif
install-exec-hook:
cd $(DESTDIR)$(bindir) && { test -e bech32m$(EXEEXT) || $(LN_S) -n bech32$(EXEEXT) bech32m$(EXEEXT) ; }
cd $(DESTDIR)$(man1dir) && { test -e bech32m.1 || $(LN_S) -n bech32.1 bech32m.1 ; }
if !DISABLE_BLECH32
cd $(DESTDIR)$(bindir) && { \
test -e blech32$(EXEEXT) || $(LN_S) -n bech32$(EXEEXT) blech32$(EXEEXT) ; \
test -e blech32m$(EXEEXT) || $(LN_S) -n bech32$(EXEEXT) blech32m$(EXEEXT) ; \
}
cd $(DESTDIR)$(man1dir) && { \
test -e blech32.1 || $(LN_S) -n bech32.1 blech32.1 ; \
test -e blech32m.1 || $(LN_S) -n bech32.1 blech32m.1 ; \
}
endif

uninstall-hook:
rm -f $(DESTDIR)$(bindir)/bech32m$(EXEEXT)
rm -f $(DESTDIR)$(man1dir)/bech32m.1
if !DISABLE_BLECH32
rm -f $(addprefix $(DESTDIR)$(bindir)/,$(addsuffix $(EXEEXT),blech32 blech32m))
rm -f $(addprefix $(DESTDIR)$(man1dir)/,$(addsuffix .1,blech32 blech32m))
endif
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# libbech32
**Library for Bech32/Bech32m encoding and decoding**
**Library for Bech32/Bech32m/Blech32/Blech32m encoding/decoding**

Libbech32 is a C library for encoding and decoding SegWit addresses and arbitrary bit strings in Bech32/Bech32m format. It offers three interfaces: a **low-level API** for working with arbitrary bit strings, a **high-level API** for working with SegWit Bitcoin addresses specifically, and a **command-line utility** for Bech32/Bech32m encoding/decoding from `stdin` to `stdout`. C++ wrappers are optionally provided for both APIs.
Libbech32 is a C library for encoding and decoding SegWit addresses and arbitrary bit strings in Bech32/Bech32m/Blech32/Blech32m format. It offers three interfaces: a **low-level API** for working with arbitrary bit strings, a **high-level API** for working with SegWit Bitcoin addresses specifically, and a **command-line utility** for Bech32/Bech32m/Blech32/Blech32m encoding/decoding from `stdin` to `stdout`. C++ wrappers are optionally provided for both APIs.

This document gives a general overview. Please refer to the auto-generated [Doxygen documentation](https://whitslack.github.io/libbech32/bech32_8h.html) for specific details.

## Low-level API

The low-level API allows encoding/decoding arbitrary bit strings to/from Bech32/Bech32m format. Bits are supplied to the encoder, or extracted from the decoder, through function calls that pass a buffer and a bit length. In the case that the bit length is not evenly divisible by 8, the bits of the last byte in the buffer are aligned to the least significant bit. Successive calls pack/unpack bit strings in the encoding without introducing any padding between segments.
The low-level API allows encoding/decoding arbitrary bit strings to/from Bech32/Bech32m/Blech32/Blech32m format. Bits are supplied to the encoder, or extracted from the decoder, through function calls that pass a buffer and a bit length. In the case that the bit length is not evenly divisible by 8, the bits of the last byte in the buffer are aligned to the least significant bit. Successive calls pack/unpack bit strings in the encoding without introducing any padding between segments.

### Encoding

Expand Down Expand Up @@ -136,6 +136,10 @@ int main() {
}
```

### Blech32/Blech32m

Unless configured with `--disable-blech32`, the low-level API supports Blech32/Blech32m encoding/decoding via structures and functions whose names are prefixed by `blech32_` instead of `bech32_`. Aside from the names, the API is the same. Likewise, the C++ wrappers are in the `blech32` namespace instead of `bech32`.

## High-level API

The high-level API allows encoding/decoding a SegWit address with a single function call.
Expand Down Expand Up @@ -230,11 +234,19 @@ int main() {
}
```

### Blech32/Blech32m

Unless configured with `--disable-blech32`, the high-level API supports encoding/decoding of blinding SegWit addresses via functions whose names are prefixed by `blech32_` instead of `segwit_`. Aside from the names, the API is the same. Likewise, the C++ wrappers are in the `blech32` namespace instead of `bech32`.

## Command-line utility

The library comes with a command-line utility for encoding/decoding Bech32/Bech32m. It supports only data payloads a whole number of bytes in size, optionally prefixed by a 5-bit version field such as in SegWit addresses.

**Usage:** `bech32` \[`-h`] \[`-m`] *hrp* { \[*version*] | `-d` \[`-v`|*version*] }
**Usage:**
`bech32` \[`-h`] \[`-l`] \[`-m`] *hrp* { \[*version*] | `-d` \[`-v`|*version*] }
`bech32m` \[`-h`] *hrp* { \[*version*] | `-d` \[`-v`|*version*] }
`blech32` \[`-h`] *hrp* { \[*version*] | `-d` \[`-v`|*version*] }
`blech32m` \[`-h`] *hrp* { \[*version*] | `-d` \[`-v`|*version*] }

Reads data from `stdin` and writes its Bech32 encoding to `stdout`.
If *version* is given, its least significant 5 bits are encoded as a SegWit version field.
Expand All @@ -248,9 +260,13 @@ If <em>version</em> is given, assert that it matches the version field in the da
<dd>Use hexadecimal for data input/output.
If this option is not specified, the data are read/written in raw binary.</dd>

<dt><code>-m</code>,<code>--bech32m</code></dt>
<dd>Use Bech32m instead of Bech32.
Implied if the command is invoked as <code>bech32m</code>.</dd>
<dt><code>-l</code>,<code>--blech</code></dt>
<dd>Use Blech32/Blech32m instead of Bech32/Bech32m.
Implied if the command is invoked as <code>blech32</code> or <code>blech32m</code>.</dd>

<dt><code>-m</code>,<code>--modified</code></dt>
<dd>Use Bech32m/Blech32m instead of Bech32/Blech32.
Implied if the command is invoked as <code>bech32m</code> or <code>blech32m</code>.</dd>

<dt><code>-v</code>,<code>--exit-version</code></dt>
<dd>Extract a 5-bit SegWit version field and return it as the exit status.</dd>
Expand Down
45 changes: 43 additions & 2 deletions bech32.1 → bech32.1.in
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
.TH BECH32 1 2024-03-08 libbech32
.
.SH NAME
bech32 \- encode/decode data in Bech32/Bech32m format
bech32 \- encode/decode data in
@@IF_BLECH32@@
Bech32/Bech32m/Blech32/Blech32m
@@ELSE_BLECH32@@
Bech32/Bech32m
@@ENDIF_BLECH32@@
format
.
.SH SYNOPSIS
.SY bech32
.OP \-h
@@IF_BLECH32@@
.OP \-l
@@ENDIF_BLECH32@@
.OP \-m
.I hrp
{
Expand All @@ -23,6 +32,26 @@ bech32 \- encode/decode data in Bech32/Bech32m format
.B \-d
[\fB\-v\fR|\fIversion\fR]
}
@@IF_BLECH32@@
.SY blech32
.OP \-h
.I hrp
{
[\fIversion\fR]
|
.B \-d
[\fB\-v\fR|\fIversion\fR]
}
.SY blech32m
.OP \-h
.I hrp
{
[\fIversion\fR]
|
.B \-d
[\fB\-v\fR|\fIversion\fR]
}
@@ENDIF_BLECH32@@
.YS
.
.SH DESCRIPTION
Expand All @@ -40,10 +69,22 @@ If \fIversion\fR is given, assert that it matches the version field in the data.
Use hexadecimal for data input/output.
If this option is not specified, the data are read/written in raw binary.
.TP
.BR \-m ", " \-\-bech32m
@@IF_BLECH32@@
.BR \-l ", " \-\-blech
Use Blech32/Blech32m instead of Bech32/Bech32m.
Implied if the command is invoked as
.BR blech32 " or " blech32m .
.TP
.BR \-m ", " \-\-modified
Use Bech32m/Blech32m instead of Bech32/Blech32.
Implied if the command is invoked as
.BR bech32m " or " blech32m .
@@ELSE_BLECH32@@
.BR \-m ", " \-\-modified
Use Bech32m instead of Bech32.
Implied if the command is invoked as
.BR bech32m .
@@ENDIF_BLECH32@@
.TP
.BR \-v ", " \-\-exit\-version
Extract a 5-bit SegWit version field and return it as the exit status.
Expand Down
Loading

0 comments on commit 3bb870b

Please sign in to comment.