mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 14:28:07 +00:00
Implement RSKIP-60 checksum address encoding
This commit is contained in:
parent
f586155d80
commit
4153e662b6
18
address.c
18
address.c
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user