[Pettycoin-dev] [raw_decode_base_n PATCH 2/3] Add function raw_decode_base_n
Nelson Castillo
nelsoneci at gmail.com
Thu Aug 14 20:28:50 EST 2014
Generalize raw_decode_base58 and make raw_decode_base58 depend on
raw_decode_base_n.
This will make it decoding from other bases easier in the future.
Signed-off-by: Nelson Castillo <nelsoneci at gmail.com>
---
base58.c | 43 ++++++++++++++++++++++++++++++++++---------
base58.h | 1 +
test/run-01-base58.c | 10 +++++-----
3 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/base58.c b/base58.c
index bdf5ea2..cd3f960 100644
--- a/base58.c
+++ b/base58.c
@@ -12,16 +12,17 @@
#include <openssl/sha.h>
#include <string.h>
-static const char enc[] =
+static const char enc_16[] = "0123456789abcdef";
+static const char enc_58[] =
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
-static char encode_char(unsigned long val)
+static char encode_char(unsigned long val, const char *enc)
{
assert(val < strlen(enc));
return enc[val];
}
-static int decode_char(char c)
+static int decode_char(char c, const char *enc)
{
const char *pos = strchr(enc, c);
if (!pos)
@@ -58,7 +59,7 @@ static char *encode_base58(char *buf, size_t buflen,
p = NULL;
goto out;
}
- *p = encode_char(rem);
+ *p = encode_char(rem, enc_58);
}
/* Now, this is really weird. We pad with zeroes, but not at
@@ -69,7 +70,7 @@ static char *encode_base58(char *buf, size_t buflen,
p = NULL;
goto out;
}
- *p = encode_char(0);
+ *p = encode_char(0, enc_58);
data_len--;
data++;
}
@@ -80,19 +81,35 @@ out:
}
/*
- * Decode a base58-encoded string into a byte sequence.
+ * Decode a base_n-encoded string into a byte sequence.
*/
-bool raw_decode_base58(BIGNUM *bn, const char *src, size_t len)
+bool raw_decode_base_n(BIGNUM *bn, const char *src, size_t len, int base)
{
+ const char *enc;
+
BN_zero(bn);
+ assert(base == 16 || base == 58);
+ switch (base) {
+ case 16:
+ enc = enc_16;
+ break;
+ case 58:
+ enc = enc_58;
+ break;
+ }
+
while (len) {
- int val = decode_char(*src);
+ char current = *src;
+
+ if (base == 16)
+ current = tolower(current); /* TODO: Not in ccan. */
+ int val = decode_char(current, enc);
if (val < 0) {
BN_free(bn);
return false;
}
- BN_mul_word(bn, 58);
+ BN_mul_word(bn, base);
BN_add_word(bn, val);
src++;
len--;
@@ -101,6 +118,14 @@ bool raw_decode_base58(BIGNUM *bn, const char *src, size_t len)
return true;
}
+/*
+ * Decode a base58-encoded string into a byte sequence.
+ */
+bool raw_decode_base58(BIGNUM *bn, const char *src, size_t len)
+{
+ return raw_decode_base_n(bn, src, len, 58);
+}
+
void base58_get_checksum(u8 csum[4], const u8 buf[], size_t buflen)
{
SHA256_CTX sha256;
diff --git a/base58.h b/base58.h
index bcaa211..d324049 100644
--- a/base58.h
+++ b/base58.h
@@ -42,6 +42,7 @@ char *key_to_base58(const tal_t *ctx, bool test_net, EC_KEY *key,
EC_KEY *key_from_base58(const char *base58, size_t base58_len,
bool *test_net, struct protocol_pubkey *key);
+bool raw_decode_base_n(BIGNUM *bn, const char *src, size_t len, int base);
bool raw_decode_base58(BIGNUM *bn, const char *src, size_t len);
void base58_get_checksum(u8 csum[4], const u8 buf[], size_t buflen);
diff --git a/test/run-01-base58.c b/test/run-01-base58.c
index 1fbc7bf..f0a4e79 100644
--- a/test/run-01-base58.c
+++ b/test/run-01-base58.c
@@ -18,7 +18,7 @@ int main(void)
assert(tal_parent(p) == ctx);
assert(p[0] == 'P');
assert(strlen(p) < BASE58_ADDR_MAX_LEN);
- assert(strspn(p, enc) == strlen(p));
+ assert(strspn(p, enc_58) == strlen(p));
memset(&addr2, 0, sizeof(addr2));
assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p)));
assert(test_net == false);
@@ -29,7 +29,7 @@ int main(void)
assert(tal_parent(p) == ctx);
assert(p[0] == 'q');
assert(strlen(p) < BASE58_ADDR_MAX_LEN);
- assert(strspn(p, enc) == strlen(p));
+ assert(strspn(p, enc_58) == strlen(p));
memset(&addr2, 0, sizeof(addr2));
assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p)));
assert(test_net == true);
@@ -40,7 +40,7 @@ int main(void)
assert(tal_parent(p) == ctx);
assert(strstarts(p, "P-1"));
assert(strlen(p) < BASE58_ADDR_MAX_LEN + 2);
- assert(strspn(p+2, enc) == strlen(p+2));
+ assert(strspn(p+2, enc_58) == strlen(p+2));
memset(&addr2, 0, sizeof(addr2));
assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p)));
assert(test_net == false);
@@ -51,7 +51,7 @@ int main(void)
assert(tal_parent(p) == ctx);
assert(strstarts(p, "P-m") || strstarts(p, "P-n"));
assert(strlen(p) < BASE58_ADDR_MAX_LEN + 2);
- assert(strspn(p+2, enc) == strlen(p+2));
+ assert(strspn(p+2, enc_58) == strlen(p+2));
memset(&addr2, 0, sizeof(addr2));
assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p)));
assert(test_net == true);
@@ -75,7 +75,7 @@ int main(void)
/* Now, turn it into pettcoin-style key. */
p = key_to_base58(ctx, true, key, false);
- assert(strspn(p, enc) == strlen(p));
+ assert(strspn(p, enc_58) == strlen(p));
/* Convert back, check it is OK. */
EC_KEY_free(key);
More information about the Pettycoin-dev
mailing list