|
|
#include "../../unity/unity.h" |
|
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
|
#include <stdint.h> |
|
|
#include <stdbool.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void setUp(void) { |
|
|
|
|
|
base_length = base58_length; |
|
|
} |
|
|
|
|
|
void tearDown(void) { |
|
|
|
|
|
} |
|
|
|
|
|
static void check_encode(const unsigned char *data, size_t data_len, |
|
|
const char *expected) |
|
|
{ |
|
|
idx_t cap = base58_length((idx_t)data_len); |
|
|
char *out = (char *)malloc((size_t)cap); |
|
|
TEST_ASSERT_NOT_NULL(out); |
|
|
memset(out, 0xAA, (size_t)cap); |
|
|
|
|
|
idx_t outlen = cap; |
|
|
base58_encode((const char *)data, data_len, out, &outlen); |
|
|
|
|
|
size_t exp_len = strlen(expected); |
|
|
TEST_ASSERT_EQUAL_UINT64(exp_len, (uint64_t)outlen); |
|
|
if (exp_len > 0) |
|
|
TEST_ASSERT_EQUAL_INT(0, memcmp(out, expected, exp_len)); |
|
|
|
|
|
for (idx_t i = outlen; i < cap; i++) |
|
|
TEST_ASSERT_EQUAL_HEX8(0xAA, (unsigned char)out[i]); |
|
|
|
|
|
free(out); |
|
|
} |
|
|
|
|
|
static size_t count_leading_zero_bytes(const unsigned char *p, size_t n) |
|
|
{ |
|
|
size_t i = 0; |
|
|
while (i < n && p[i] == 0x00) i++; |
|
|
return i; |
|
|
} |
|
|
|
|
|
static void test_base58_encode_empty(void) |
|
|
{ |
|
|
check_encode(NULL, 0, ""); |
|
|
} |
|
|
|
|
|
static void test_base58_encode_only_zeros(void) |
|
|
{ |
|
|
|
|
|
unsigned char z1[] = {0x00}; |
|
|
unsigned char z2[] = {0x00, 0x00}; |
|
|
unsigned char z3[] = {0x00, 0x00, 0x00}; |
|
|
unsigned char z4[] = {0x00, 0x00, 0x00, 0x00}; |
|
|
|
|
|
check_encode(z1, sizeof z1, "1"); |
|
|
check_encode(z2, sizeof z2, "11"); |
|
|
check_encode(z3, sizeof z3, "111"); |
|
|
check_encode(z4, sizeof z4, "1111"); |
|
|
} |
|
|
|
|
|
static void test_base58_encode_single_bytes(void) |
|
|
{ |
|
|
unsigned char v1[] = {0x01}; |
|
|
unsigned char vff[] = {0xFF}; |
|
|
|
|
|
check_encode(v1, sizeof v1, "2"); |
|
|
check_encode(vff, sizeof vff, "5Q"); |
|
|
} |
|
|
|
|
|
static void test_base58_encode_prefix_zeros_then_value(void) |
|
|
{ |
|
|
unsigned char a[] = {0x00, 0x01}; |
|
|
unsigned char b[] = {0x00, 0x00, 0xFF}; |
|
|
|
|
|
check_encode(a, sizeof a, "12"); |
|
|
check_encode(b, sizeof b, "115Q"); |
|
|
} |
|
|
|
|
|
static void test_base58_encode_small_multibyte_examples(void) |
|
|
{ |
|
|
|
|
|
unsigned char v256[] = {0x01, 0x00}; |
|
|
check_encode(v256, sizeof v256, "5R"); |
|
|
|
|
|
|
|
|
unsigned char v123[] = {0x01, 0x02, 0x03}; |
|
|
check_encode(v123, sizeof v123, "Ldp"); |
|
|
} |
|
|
|
|
|
static bool is_forbidden_base58_char(char c) |
|
|
{ |
|
|
|
|
|
return (c == '0' || c == 'O' || c == 'I' || c == 'l'); |
|
|
} |
|
|
|
|
|
static void test_base58_encode_long_input_properties(void) |
|
|
{ |
|
|
|
|
|
size_t n = 300; |
|
|
unsigned char *buf = (unsigned char *)malloc(n); |
|
|
TEST_ASSERT_NOT_NULL(buf); |
|
|
for (size_t i = 0; i < n; i++) |
|
|
buf[i] = (unsigned char)((i + 1) & 0xFF); |
|
|
buf[0] = 0x01; |
|
|
|
|
|
idx_t cap = base58_length((idx_t)n); |
|
|
char *out = (char *)malloc((size_t)cap); |
|
|
TEST_ASSERT_NOT_NULL(out); |
|
|
memset(out, 0xAA, (size_t)cap); |
|
|
|
|
|
idx_t outlen = cap; |
|
|
base58_encode((const char *)buf, n, out, &outlen); |
|
|
|
|
|
TEST_ASSERT_TRUE(outlen > 0); |
|
|
|
|
|
TEST_ASSERT_NOT_EQUAL('1', out[0]); |
|
|
|
|
|
|
|
|
for (idx_t i = 0; i < outlen; i++) |
|
|
TEST_ASSERT_FALSE(is_forbidden_base58_char(out[i])); |
|
|
|
|
|
|
|
|
for (idx_t i = outlen; i < cap; i++) |
|
|
TEST_ASSERT_EQUAL_HEX8(0xAA, (unsigned char)out[i]); |
|
|
|
|
|
free(out); |
|
|
free(buf); |
|
|
} |
|
|
|
|
|
int main(void) |
|
|
{ |
|
|
UNITY_BEGIN(); |
|
|
RUN_TEST(test_base58_encode_empty); |
|
|
RUN_TEST(test_base58_encode_only_zeros); |
|
|
RUN_TEST(test_base58_encode_single_bytes); |
|
|
RUN_TEST(test_base58_encode_prefix_zeros_then_value); |
|
|
RUN_TEST(test_base58_encode_small_multibyte_examples); |
|
|
RUN_TEST(test_base58_encode_long_input_properties); |
|
|
return UNITY_END(); |
|
|
} |