Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding: bech32 accepts checksum argument for bech32m #1

Merged
merged 2 commits into from Oct 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 10 additions & 6 deletions include/torsion/encoding.h
Expand Up @@ -254,16 +254,18 @@ TORSION_EXTERN int
bech32_serialize(char *str,
const char *hrp,
const uint8_t *data,
size_t data_len);
size_t data_len,
uint32_t checksum);

TORSION_EXTERN int
bech32_deserialize(char *hrp,
uint8_t *data,
size_t *data_len,
const char *str);
const char *str,
uint32_t checksum);

TORSION_EXTERN int
bech32_is(const char *str);
bech32_is(const char *str, uint32_t checksum);

TORSION_EXTERN int
bech32_convert_bits(uint8_t *dst,
Expand All @@ -279,17 +281,19 @@ bech32_encode(char *addr,
const char *hrp,
unsigned int version,
const uint8_t *hash,
size_t hash_len);
size_t hash_len,
uint32_t checksum);

TORSION_EXTERN int
bech32_decode(char *hrp,
unsigned int *version,
uint8_t *hash,
size_t *hash_len,
const char *addr);
const char *addr,
uint32_t checksum);

TORSION_EXTERN int
bech32_test(const char *addr);
bech32_test(const char *addr, uint32_t checksum);

/*
* Cash32
Expand Down
28 changes: 16 additions & 12 deletions src/encoding.c
Expand Up @@ -1243,7 +1243,8 @@ int
bech32_serialize(char *str,
const char *hrp,
const uint8_t *data,
size_t data_len) {
size_t data_len,
uint32_t checksum) {
uint32_t chk = 1;
size_t i, hlen;
size_t j = 0;
Expand Down Expand Up @@ -1295,7 +1296,7 @@ bech32_serialize(char *str,
for (i = 0; i < 6; i++)
chk = bech32_polymod(chk);

chk ^= 1;
chk ^= checksum;

for (i = 0; i < 6; i++)
str[j++] = bech32_charset[(chk >> ((5 - i) * 5)) & 0x1f];
Expand All @@ -1309,7 +1310,8 @@ int
bech32_deserialize(char *hrp,
uint8_t *data,
size_t *data_len,
const char *str) {
const char *str,
uint32_t checksum) {
uint32_t chk = 1;
size_t hlen = 0;
size_t i, slen;
Expand Down Expand Up @@ -1376,7 +1378,7 @@ bech32_deserialize(char *hrp,
data[j++] = val;
}

if (chk != 1)
if (chk != checksum)
return 0;

*data_len = j;
Expand All @@ -1385,12 +1387,12 @@ bech32_deserialize(char *hrp,
}

int
bech32_is(const char *str) {
bech32_is(const char *str, uint32_t checksum) {
char hrp[BECH32_MAX_HRP_SIZE + 1];
uint8_t data[BECH32_MAX_DESERIALIZE_SIZE];
size_t data_len;

return bech32_deserialize(hrp, data, &data_len, str);
return bech32_deserialize(hrp, data, &data_len, str, checksum);
}

int
Expand Down Expand Up @@ -1438,7 +1440,8 @@ bech32_encode(char *addr,
const char *hrp,
unsigned int version,
const uint8_t *hash,
size_t hash_len) {
size_t hash_len,
uint32_t checksum) {
uint8_t data[BECH32_MAX_DATA_SIZE];
size_t data_len;

Expand All @@ -1459,19 +1462,20 @@ bech32_encode(char *addr,

data_len += 1;

return bech32_serialize(addr, hrp, data, data_len);
return bech32_serialize(addr, hrp, data, data_len, checksum);
}

int
bech32_decode(char *hrp,
unsigned int *version,
uint8_t *hash,
size_t *hash_len,
const char *addr) {
const char *addr,
uint32_t checksum) {
uint8_t data[BECH32_MAX_DESERIALIZE_SIZE];
size_t data_len;

if (!bech32_deserialize(hrp, data, &data_len, addr))
if (!bech32_deserialize(hrp, data, &data_len, addr, checksum))
return 0;

if (data_len == 0 || data_len > BECH32_MAX_DATA_SIZE)
Expand All @@ -1496,13 +1500,13 @@ bech32_decode(char *hrp,
}

int
bech32_test(const char *addr) {
bech32_test(const char *addr, uint32_t checksum) {
char hrp[BECH32_MAX_HRP_SIZE + 1];
unsigned int version;
uint8_t hash[BECH32_MAX_DECODE_SIZE];
size_t hash_len;

return bech32_decode(hrp, &version, hash, &hash_len, addr);
return bech32_decode(hrp, &version, hash, &hash_len, addr, checksum);
}

/*
Expand Down
21 changes: 11 additions & 10 deletions test/test.c
Expand Up @@ -3368,16 +3368,16 @@ test_encoding_bech32(drbg_t *unused) {
{
"bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6"
"qejxtdg4y5r3zarvary0c5xw7k7grplx",
"8128751e76e8199196d454941c45d1b3a323f1433b"
"5128751e76e8199196d454941c45d1b3a323f1433b"
"d6751e76e8199196d454941c45d1b3a323f1433bd6"
},
{
"BC1SW50QA3JX3S",
"9002751e"
"6002751e"
},
{
"bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
"8210751e76e8199196d454941c45d1b3a323"
"5210751e76e8199196d454941c45d1b3a323"
},
{
"tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy",
Expand Down Expand Up @@ -3409,6 +3409,7 @@ test_encoding_bech32(drbg_t *unused) {
"pgghm0aec23ttfstphjegfx08hwk5uhmusa7j28yrk8cx4qj"
};

const uint32_t checksum = 1;
char hrp[BECH32_MAX_HRP_SIZE + 1];
unsigned int version;
uint8_t script[BECH32_MAX_DECODE_SIZE + 2];
Expand All @@ -3427,16 +3428,16 @@ test_encoding_bech32(drbg_t *unused) {

ASSERT(base16_decode(script, &script_len, hex, strlen(hex)));

ASSERT(bech32_test(addr));
ASSERT(bech32_is(addr));
ASSERT(bech32_decode(hrp, &version, data, &data_len, addr));
ASSERT(bech32_test(addr, checksum));
ASSERT(bech32_is(addr, checksum));
ASSERT(bech32_decode(hrp, &version, data, &data_len, addr, checksum));
ASSERT(strlen(hrp) >= 2 && torsion_memcmp(hrp, expect[i], 2) == 0);
ASSERT(2 + data_len == script_len);
ASSERT(script[0] == (version ? version + 0x80 : 0));
ASSERT(script[0] == (version ? version + 0x50 : 0));
ASSERT(script[1] == data_len);
ASSERT(torsion_memcmp(data, script + 2, data_len) == 0);

ASSERT(bech32_encode(out, hrp, version, data, data_len));
ASSERT(bech32_encode(out, hrp, version, data, data_len, checksum));
ASSERT(strcmp(out, expect[i]) == 0);
}

Expand All @@ -3445,8 +3446,8 @@ test_encoding_bech32(drbg_t *unused) {

printf(" - Bech32 (invalid) vector #%u (%s)\n", i + 1, addr);

ASSERT(!bech32_test(addr));
ASSERT(!bech32_decode(hrp, &version, data, &data_len, addr));
ASSERT(!bech32_test(addr, checksum));
ASSERT(!bech32_decode(hrp, &version, data, &data_len, addr, checksum));
}
}

Expand Down