From 2e4ec7fe0a4b71bff34fa12b47bb0751fc6e995a Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Thu, 30 Jan 2014 20:34:05 +0100 Subject: [PATCH] introduce ecdsa_address_to_hash160 --- bignum.c | 23 +++++++++++++++++++++++ bignum.h | 4 ++++ ecdsa.c | 26 ++++++++++++++++++++++++++ ecdsa.h | 1 + tests.c | 23 ++++++++++++++++++++++- 5 files changed, 76 insertions(+), 1 deletion(-) diff --git a/bignum.c b/bignum.c index 5ad5d89f3..5117d0bed 100644 --- a/bignum.c +++ b/bignum.c @@ -154,6 +154,29 @@ void bn_mod(bignum256 *x, const bignum256 *prime) } } +// a = a + b +void bn_addi(bignum256 *a, uint32_t b) +{ + uint64_t t = a->val[0]; + t += b; + a->val[0] = t & 0x3FFFFFFFu; + t >>= 30; + a->val[1] += t; +} + +// a = a * b +void bn_muli(bignum256 *a, uint32_t b) +{ + uint64_t t = 0; + int i; + for (i = 0; i < 8; i++) { + t = (uint64_t)(a->val[i]) * b + t; + a->val[i] = t & 0x3FFFFFFFu; + t >>= 30; + } + a->val[8] += t; +} + // x = k * x // both inputs and result may be bigger than prime but not bigger than 2 * prime void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime) diff --git a/bignum.h b/bignum.h index 928f56fc6..293d8120f 100644 --- a/bignum.h +++ b/bignum.h @@ -73,6 +73,10 @@ void bn_rshift(bignum256 *a); void bn_mod(bignum256 *x, const bignum256 *prime); +void bn_addi(bignum256 *a, uint32_t b); + +void bn_muli(bignum256 *a, uint32_t b); + void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime); void bn_fast_mod(bignum256 *x, const bignum256 *prime); diff --git a/ecdsa.c b/ecdsa.c index ff9d534b4..ae93334be 100644 --- a/ecdsa.c +++ b/ecdsa.c @@ -342,6 +342,32 @@ void ecdsa_get_address(const uint8_t *pub_key, uint8_t version, char *addr) } } +int ecdsa_address_to_hash160(const char *addr, uint8_t *hash) +{ + if (!addr) return 0; + const char code[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + bignum256 num; + uint8_t buf[32]; + bn_zero(&num); + uint32_t k; + int i; + for (i = 0; i < strlen(addr); i++) { + bn_muli(&num, 58); + for (k = 0; k <= strlen(code); k++) { + if (code[k] == 0) { // char not found -> invalid address + return 0; + } + if (addr[i] == code[k]) { + bn_addi(&num, k); + break; + } + } + } + bn_write_be(&num, buf); + memcpy(hash, buf + 8, 20); + return 1; +} + int ecdsa_read_pubkey(const uint8_t *pub_key, curve_point *pub) { if (pub_key[0] == 0x04) { diff --git a/ecdsa.h b/ecdsa.h index 62b34cb43..1b504ee9f 100644 --- a/ecdsa.h +++ b/ecdsa.h @@ -40,6 +40,7 @@ int ecdsa_sign(const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, ui void ecdsa_get_public_key33(const uint8_t *priv_key, uint8_t *pub_key); void ecdsa_get_public_key65(const uint8_t *priv_key, uint8_t *pub_key); void ecdsa_get_address(const uint8_t *pub_key, uint8_t version, char *addr); +int ecdsa_address_to_hash160(const char *addr, uint8_t *hash); int ecdsa_read_pubkey(const uint8_t *pub_key, curve_point *pub); int ecdsa_verify(const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len); diff --git a/tests.c b/tests.c index d89929370..58e6103c4 100644 --- a/tests.c +++ b/tests.c @@ -491,6 +491,23 @@ START_TEST(test_address) } END_TEST +START_TEST(test_address_to_hash) +{ + uint8_t hash[20]; + + ecdsa_address_to_hash160("1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T", hash); ck_assert_mem_eq(hash, fromhex("c4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 20); + ecdsa_address_to_hash160("myTPjxggahXyAzuMcYp5JTkbybANyLsYBW", hash); ck_assert_mem_eq(hash, fromhex("c4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 20); + ecdsa_address_to_hash160("NEWoeZ6gh4CGvRgFAoAGh4hBqpxizGT6gZ", hash); ck_assert_mem_eq(hash, fromhex("c4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 20); + ecdsa_address_to_hash160("LdAPi7uXrLLmeh7u57pzkZc3KovxEDYRJq", hash); ck_assert_mem_eq(hash, fromhex("c4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 20); + + ecdsa_address_to_hash160("1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8", hash); ck_assert_mem_eq(hash, fromhex("79fbfc3f34e7745860d76137da68f362380c606c"), 20); + ecdsa_address_to_hash160("mrdwvWkma2D6n9mGsbtkazedQQuoksnqJV", hash); ck_assert_mem_eq(hash, fromhex("79fbfc3f34e7745860d76137da68f362380c606c"), 20); + ecdsa_address_to_hash160("N7hMq7AmgNsQXaYARrEwybbDGei9mcPNqr", hash); ck_assert_mem_eq(hash, fromhex("79fbfc3f34e7745860d76137da68f362380c606c"), 20); + ecdsa_address_to_hash160("LWLwtfycqf1uFqypLAug36W4kdgNwrZdNs", hash); ck_assert_mem_eq(hash, fromhex("79fbfc3f34e7745860d76137da68f362380c606c"), 20); +} +END_TEST + + // define test suite and cases Suite *test_suite(void) { @@ -511,10 +528,14 @@ Suite *test_suite(void) tcase_add_test(tc, test_verify_speed); suite_add_tcase(s, tc); - tc = tcase_create("addresses"); + tc = tcase_create("address"); tcase_add_test(tc, test_address); suite_add_tcase(s, tc); + tc = tcase_create("address_to_hash"); + tcase_add_test(tc, test_address_to_hash); + suite_add_tcase(s, tc); + tc = tcase_create("rijndael"); tcase_add_test(tc, test_rijndael); suite_add_tcase(s, tc);