use new base58 code for address functions, add function for obtaining wif

pull/25/head
Pavol Rusnak 10 years ago
parent 4b1211e0ae
commit 5e9cd15527

@ -32,8 +32,8 @@ int base58_encode_check(const uint8_t *data, int len, char *str)
case 78: // xpub/xprv 78
outlen = 111;
break;
case 34: // WIF privkey 1+32
outlen = 51;
case 34: // WIF privkey 1+32+1
outlen = 52;
break;
case 21: // address 1+20
outlen = 34;
@ -57,9 +57,20 @@ int base58_encode_check(const uint8_t *data, int len, char *str)
mydata[i] = rem * 4 + (tmp / 58);
rem = tmp % 58;
}
str[outlen - 1 - j] = code[rem];
str[j] = code[rem];
}
// remove duplicite 1s at the end
while (outlen > 1 && str[outlen - 1] == code[0] && str[outlen - 2] == code[0]) {
outlen--;
}
str[outlen] = 0;
char s;
// reverse string
for (i = 0; i < outlen / 2; i++) {
s = str[i];
str[i] = str[outlen - 1 - i];
str[outlen - 1 - i] = s;
}
return outlen;
}
@ -83,8 +94,8 @@ int base58_decode_check(const char *str, uint8_t *data)
case 111: // xpub/xprv
outlen = 78;
break;
case 51: // WIF privkey
outlen = 34;
case 52: // WIF privkey
outlen = 35;
break;
case 27: // address
case 28:

@ -31,6 +31,7 @@
#include "ripemd160.h"
#include "hmac.h"
#include "ecdsa.h"
#include "base58.h"
// cp2 = cp1 + cp2
void point_add(const curve_point *cp1, curve_point *cp2)
@ -347,79 +348,25 @@ void ecdsa_get_pubkeyhash(const uint8_t *pub_key, uint8_t *pubkeyhash)
void ecdsa_get_address(const uint8_t *pub_key, uint8_t version, char *addr)
{
const char code[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
char *p = addr, s;
uint8_t a[32], b[21];
uint32_t r;
bignum256 c;
int i, l;
b[0] = version;
ecdsa_get_pubkeyhash(pub_key, b + 1);
sha256_Raw(b, 21, a);
sha256_Raw(a, 32, a);
memcpy(a + 28, a, 4); // checksum
memset(a, 0, 7); // zeroes
memcpy(a + 7, b, 21); // version || ripemd160(sha256(pubkey))
bn_read_be(a, &c);
while (!bn_is_zero(&c)) {
bn_divmod58(&c, &r);
*p = code[r];
p++;
}
i = 7;
while (a[i] == 0) {
*p = code[0];
p++; i++;
}
*p = 0;
l = strlen(addr);
uint8_t data[21];
data[0] = version;
ecdsa_get_pubkeyhash(pub_key, data + 1);
base58_encode_check(data, 21, addr);
}
for (i = 0; i < l / 2; i++) {
s = addr[i];
addr[i] = addr[l - 1 - i];
addr[l - 1 - i] = s;
}
void ecdsa_get_wif(const uint8_t *priv_key, uint8_t version, char *wif)
{
uint8_t data[34];
data[0] = version;
memcpy(data + 1, priv_key, 32);
data[33 ] = 0x01;
base58_encode_check(data, 34, wif);
}
int ecdsa_address_decode(const char *addr, uint8_t *out)
{
if (!addr) return 0;
const char code[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
bignum256 num;
uint8_t buf[32], check[32];
bn_zero(&num);
uint32_t k;
size_t 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);
// compute address hash
sha256_Raw(buf + 7, 21, check);
sha256_Raw(check, 32, check);
// check if valid
if (memcmp(buf + 7 + 21, check, 4) != 0) {
return 0;
}
memcpy(out, buf + 7, 21);
return 1;
return base58_decode_check(addr, out) == 21;
}
void uncompress_coords(uint8_t odd, const bignum256 *x, bignum256 *y)

@ -45,6 +45,7 @@ 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_pubkeyhash(const uint8_t *pub_key, uint8_t *pubkeyhash);
void ecdsa_get_address(const uint8_t *pub_key, uint8_t version, char *addr);
void ecdsa_get_wif(const uint8_t *priv_key, uint8_t version, char *wif);
int ecdsa_address_decode(const char *addr, uint8_t *out);
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);

@ -728,6 +728,25 @@ START_TEST(test_address)
}
END_TEST
START_TEST(test_wif)
{
uint8_t priv_key[32];
char wif[53];
memcpy(priv_key, fromhex("1111111111111111111111111111111111111111111111111111111111111111"), 32);
ecdsa_get_wif(priv_key, 0x80, wif); ck_assert_str_eq(wif, "KwntMbt59tTsj8xqpqYqRRWufyjGunvhSyeMo3NTYpFYzZbXJ5Hp");
ecdsa_get_wif(priv_key, 0xEF, wif); ck_assert_str_eq(wif, "cN9spWsvaxA8taS7DFMxnk1yJD2gaF2PX1npuTpy3vuZFJdwavaw");
memcpy(priv_key, fromhex("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"), 32);
ecdsa_get_wif(priv_key, 0x80, wif); ck_assert_str_eq(wif, "L4ezQvyC6QoBhxB4GVs9fAPhUKtbaXYUn8YTqoeXwbevQq4U92vN");
ecdsa_get_wif(priv_key, 0xEF, wif); ck_assert_str_eq(wif, "cV1ysqy3XUVSsPeKeugH2Utm6ZC1EyeArAgvxE73SiJvfa6AJng7");
memcpy(priv_key, fromhex("47f7616ea6f9b923076625b4488115de1ef1187f760e65f89eb6f4f7ff04b012"), 32);
ecdsa_get_wif(priv_key, 0x80, wif); ck_assert_str_eq(wif, "KydbzBtk6uc7M6dXwEgTEH2sphZxSPbmDSz6kUUHi4eUpSQuhEbq");
ecdsa_get_wif(priv_key, 0xEF, wif); ck_assert_str_eq(wif, "cPzbT6tbXyJNWY6oKeVabbXwSvsN6qhTHV8ZrtvoDBJV5BRY1G5Q");
}
END_TEST
START_TEST(test_address_decode)
{
int res;
@ -867,6 +886,10 @@ Suite *test_suite(void)
tcase_add_test(tc, test_address_decode);
suite_add_tcase(s, tc);
tc = tcase_create("wif");
tcase_add_test(tc, test_wif);
suite_add_tcase(s, tc);
tc = tcase_create("ecdsa_der");
tcase_add_test(tc, test_ecdsa_der);
suite_add_tcase(s, tc);

Loading…
Cancel
Save