1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 22:38:08 +00:00

Implement RSKIP-60 checksum address encoding

This commit is contained in:
Ilan 2018-06-19 14:52:39 -03:00 committed by Pavol Rusnak
parent f586155d80
commit 4153e662b6
3 changed files with 60 additions and 4 deletions

View File

@ -22,6 +22,9 @@
*/ */
#include "address.h" #include "address.h"
#include <stdio.h>
#include <string.h>
#include "bignum.h"
size_t address_prefix_bytes_len(uint32_t address_type) size_t address_prefix_bytes_len(uint32_t address_type)
{ {
@ -56,7 +59,7 @@ bool address_check_prefix(const uint8_t *addr, uint32_t address_type)
#if USE_ETHEREUM #if USE_ETHEREUM
#include "sha3.h" #include "sha3.h"
void ethereum_address_checksum(const uint8_t *addr, char *address) void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60, uint8_t chain_id)
{ {
const char *hex = "0123456789abcdef"; const char *hex = "0123456789abcdef";
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
@ -64,8 +67,19 @@ void ethereum_address_checksum(const uint8_t *addr, char *address)
address[i * 2 + 1] = hex[addr[i] & 0xF]; address[i * 2 + 1] = hex[addr[i] & 0xF];
} }
address[40] = 0; address[40] = 0;
SHA3_CTX ctx;
uint8_t hash[32]; uint8_t hash[32];
keccak_256((const uint8_t *)address, 40, hash); keccak_256_Init(&ctx);
if(rskip60)
{
char prefix[16];
int prefix_size = bn_format_uint64(chain_id, NULL, "0x", 0, 0, false, prefix, sizeof(prefix));
keccak_Update(&ctx, (const uint8_t *)prefix, prefix_size);
}
keccak_Update(&ctx, (const uint8_t *)address, 40);
keccak_Final(&ctx, hash);
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
if (hash[i] & 0x80 && address[i * 2 ] >= 'a' && address[i * 2 ] <= 'f') { if (hash[i] & 0x80 && address[i * 2 ] >= 'a' && address[i * 2 ] <= 'f') {
address[i * 2] -= 0x20; address[i * 2] -= 0x20;

View File

@ -33,7 +33,7 @@ size_t address_prefix_bytes_len(uint32_t address_type);
void address_write_prefix_bytes(uint32_t address_type, uint8_t *out); void address_write_prefix_bytes(uint32_t address_type, uint8_t *out);
bool address_check_prefix(const uint8_t *addr, uint32_t address_type); bool address_check_prefix(const uint8_t *addr, uint32_t address_type);
#if USE_ETHEREUM #if USE_ETHEREUM
void ethereum_address_checksum(const uint8_t *addr, char *address); void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60, uint8_t chain_id);
#endif #endif
#endif #endif

View File

@ -3802,7 +3802,45 @@ START_TEST(test_ethereum_address)
const char **vec = vectors; const char **vec = vectors;
while (*vec) { while (*vec) {
memcpy(addr, fromhex(*vec), 20); memcpy(addr, fromhex(*vec), 20);
ethereum_address_checksum(addr, address); ethereum_address_checksum(addr, address, false, 1);
ck_assert_str_eq(address, *vec);
vec++;
}
}
END_TEST
// test vectors from https://github.com/rsksmart/RSKIPs/blob/master/IPs/RSKIP60.md
START_TEST(test_rsk_address)
{
uint8_t addr[20];
char address[41];
static const char *rskip60_chain30[] = {
"5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD",
"Fb6916095cA1Df60bb79ce92cE3EA74c37c5d359",
"DBF03B407c01E7CD3cBea99509D93F8Dddc8C6FB",
"D1220A0Cf47c7B9BE7a2e6ba89F429762E7B9adB",
0
};
const char **vec = rskip60_chain30;
while (*vec) {
memcpy(addr, fromhex(*vec), 20);
ethereum_address_checksum(addr, address, true, 30);
ck_assert_str_eq(address, *vec);
vec++;
}
static const char *rskip60_chain31[] = {
"5aAeb6053F3e94c9b9A09F33669435E7EF1BEaEd",
"Fb6916095CA1dF60bb79CE92ce3Ea74C37c5D359",
"dbF03B407C01E7cd3cbEa99509D93f8dDDc8C6fB",
"d1220a0CF47c7B9Be7A2E6Ba89f429762E7b9adB",
0
};
vec = rskip60_chain31;
while (*vec) {
memcpy(addr, fromhex(*vec), 20);
ethereum_address_checksum(addr, address, true, 31);
ck_assert_str_eq(address, *vec); ck_assert_str_eq(address, *vec);
vec++; vec++;
} }
@ -4744,6 +4782,10 @@ Suite *test_suite(void)
tcase_add_test(tc, test_ethereum_address); tcase_add_test(tc, test_ethereum_address);
suite_add_tcase(s, tc); suite_add_tcase(s, tc);
tc = tcase_create("rsk_address");
tcase_add_test(tc, test_rsk_address);
suite_add_tcase(s, tc);
tc = tcase_create("wif"); tc = tcase_create("wif");
tcase_add_test(tc, test_wif); tcase_add_test(tc, test_wif);
suite_add_tcase(s, tc); suite_add_tcase(s, tc);