1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-18 05:28:40 +00:00

Segwit: Show multisig segwit address

changed layout for very large addresses.
This commit is contained in:
Jochen Hoenicke 2017-01-06 16:18:28 +01:00
parent 66ba8d09b4
commit e9eaad2fcf
No known key found for this signature in database
GPG Key ID: EB17C6B5E51193F5
3 changed files with 64 additions and 24 deletions

View File

@ -611,6 +611,9 @@ void fsm_msgGetAddress(GetAddress *msg)
if (!node) return;
hdnode_fill_public_key(node);
int is_segwit = 0;
uint8_t digest[32];
uint8_t raw[32+2+4];
size_t prelen;
if (msg->has_multisig) {
layoutProgressSwipe("Preparing", 0);
@ -619,20 +622,45 @@ void fsm_msgGetAddress(GetAddress *msg)
layoutHome();
return;
}
uint8_t buf[32];
if (compile_script_multisig_hash(&(msg->multisig), buf) == 0) {
if (compile_script_multisig_hash(&(msg->multisig), digest) == 0) {
fsm_sendFailure(FailureType_Failure_Other, "Invalid multisig script");
layoutHome();
return;
}
ripemd160(buf, 32, buf + 1);
buf[0] = coin->address_type_p2sh; // multisig cointype
base58_encode_check(buf, 21, resp->address, sizeof(resp->address));
if (msg->has_script_type
&& (msg->script_type == InputScriptType_SPENDWITNESS
|| msg->script_type == InputScriptType_SPENDP2SHWITNESS)) {
is_segwit = 1;
// segwit p2wsh: script hash is single sha256
if (msg->script_type == InputScriptType_SPENDWITNESS) {
prelen = address_prefix_bytes_len(coin->address_type_p2wsh);
address_write_prefix_bytes(coin->address_type_p2wsh, raw);
raw[prelen] = 0; // version byte
raw[prelen + 1] = 0; // always 0, see bip-142
memcpy(raw+prelen+2, digest, 32);
base58_encode_check(raw, prelen + 34, resp->address, sizeof(resp->address));
} else {
// segwit p2wsh encapsuled in p2sh address
raw[0] = 0; // push version
raw[1] = 32; // push 32 bytes
memcpy(raw+2, digest, 32); // push hash
sha256_Raw(raw, 34, digest);
prelen = address_prefix_bytes_len(coin->address_type_p2wsh);
address_write_prefix_bytes(coin->address_type_p2sh, raw);
ripemd160(digest, 32, raw + prelen);
base58_encode_check(raw, prelen + 20, resp->address, sizeof(resp->address));
}
} else {
// non-segwit p2sh multisig
prelen = address_prefix_bytes_len(coin->address_type_p2sh);
address_write_prefix_bytes(coin->address_type_p2sh, raw);
ripemd160(digest, 32, raw + prelen);
base58_encode_check(raw, prelen + 20, resp->address, sizeof(resp->address));
}
} else if (msg->has_script_type
&& msg->script_type == InputScriptType_SPENDWITNESS
&& coin->has_address_type_p2wpkh) {
uint8_t raw[22+4];
int prelen = address_prefix_bytes_len(coin->address_type_p2wpkh);
prelen = address_prefix_bytes_len(coin->address_type_p2wpkh);
address_write_prefix_bytes(coin->address_type_p2wpkh, raw);
raw[prelen] = 0; // version byte
raw[prelen + 1] = 0; // always 0, see bip-142
@ -646,16 +674,14 @@ void fsm_msgGetAddress(GetAddress *msg)
} else if (msg->has_script_type
&& msg->script_type == InputScriptType_SPENDP2SHWITNESS
&& coin->has_address_type_p2sh) {
uint8_t script[22];
uint8_t digest[32];
int prelen = address_prefix_bytes_len(coin->address_type_p2sh);
script[0] = 0; // version byte
script[1] = 20; // push 20 bytes
ecdsa_get_pubkeyhash(node->public_key, script + 2);
sha256_Raw(script, 22, digest);
ripemd160(digest, 32, digest + prelen);
address_write_prefix_bytes(coin->address_type_p2sh, digest);
if (!base58_encode_check(digest, 21, resp->address, sizeof(resp->address))) {
prelen = address_prefix_bytes_len(coin->address_type_p2sh);
raw[0] = 0; // version byte
raw[1] = 20; // push 20 bytes
ecdsa_get_pubkeyhash(node->public_key, raw + 2);
sha256_Raw(raw, 22, digest);
address_write_prefix_bytes(coin->address_type_p2sh, raw);
ripemd160(digest, 32, raw + prelen);
if (!base58_encode_check(raw, 21, resp->address, sizeof(resp->address))) {
fsm_sendFailure(FailureType_Failure_ActionCancelled, "Can't encode address");
layoutHome();
return;

View File

@ -245,6 +245,7 @@ void layoutAddress(const char *address, const char *desc)
static unsigned char bitdata[QR_MAX_BITDATA];
int a, i, j;
int side = qr_encode(QR_LEVEL_M, 0, address, 0, bitdata);
int startx;
if (side > 0 && side <= 29) {
oledInvert(0, 0, (side + 2) * 2, (side + 2) * 2);
@ -259,6 +260,20 @@ void layoutAddress(const char *address, const char *desc)
}
}
}
startx = 68;
} else if (side > 0 && side <= 60) {
oledInvert(0, 0, (side + 3), (side + 3));
for (i = 0; i < side; i++) {
for (j = 0; j< side; j++) {
a = j * side + i;
if (bitdata[a / 8] & (1 << (7 - a % 8))) {
oledClearPixel(2 + i, 2 + j);
}
}
}
startx = side + 6;
} else {
startx = 0;
}
uint32_t addrlen = strlen(address);
@ -269,12 +284,11 @@ void layoutAddress(const char *address, const char *desc)
const char **str = split_message((const uint8_t *)address, addrlen, rowlen);
if (desc) {
oledDrawString(68, 0 * 9, desc);
oledDrawString(startx, 0 * 9, desc);
}
for (i = 0; i < 4; i++) {
oledDrawString(startx, (i+1) * 9 + 4, str[i]);
}
oledDrawString(68, 1 * 9 + 4, str[0]);
oledDrawString(68, 2 * 9 + 4, str[1]);
oledDrawString(68, 3 * 9 + 4, str[2]);
oledDrawString(68, 4 * 9 + 4, str[3]);
static const char *btnYes = "Continue";
oledDrawString(OLED_WIDTH - fontCharWidth('\x06') - 1, OLED_HEIGHT - 8, "\x06");

View File

@ -130,7 +130,7 @@ typedef struct _WordRequest {
} WordRequest;
typedef struct _Address {
char address[41];
char address[60];
} Address;
typedef struct {
@ -1242,7 +1242,7 @@ extern const pb_field_t DebugLinkFlashErase_fields[2];
#define PublicKey_size (121 + HDNodeType_size)
#define GetAddress_size (81 + MultisigRedeemScriptType_size)
#define EthereumGetAddress_size 50
#define Address_size 43
#define Address_size 62
#define EthereumAddress_size 22
#define WipeDevice_size 0
#define LoadDevice_size (326 + HDNodeType_size)