mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-12 18:49:07 +00:00
use new base58 code for address functions, add function for obtaining wif
This commit is contained in:
parent
4b1211e0ae
commit
5e9cd15527
21
base58.c
21
base58.c
@ -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:
|
||||
|
81
ecdsa.c
81
ecdsa.c
@ -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;
|
||||
uint8_t data[21];
|
||||
data[0] = version;
|
||||
ecdsa_get_pubkeyhash(pub_key, data + 1);
|
||||
base58_encode_check(data, 21, addr);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
|
1
ecdsa.h
1
ecdsa.h
@ -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);
|
||||
|
23
tests.c
23
tests.c
@ -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…
Reference in New Issue
Block a user