1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-31 09:50:58 +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; if (!node) return;
hdnode_fill_public_key(node); hdnode_fill_public_key(node);
int is_segwit = 0; int is_segwit = 0;
uint8_t digest[32];
uint8_t raw[32+2+4];
size_t prelen;
if (msg->has_multisig) { if (msg->has_multisig) {
layoutProgressSwipe("Preparing", 0); layoutProgressSwipe("Preparing", 0);
@ -619,20 +622,45 @@ void fsm_msgGetAddress(GetAddress *msg)
layoutHome(); layoutHome();
return; return;
} }
uint8_t buf[32]; if (compile_script_multisig_hash(&(msg->multisig), digest) == 0) {
if (compile_script_multisig_hash(&(msg->multisig), buf) == 0) {
fsm_sendFailure(FailureType_Failure_Other, "Invalid multisig script"); fsm_sendFailure(FailureType_Failure_Other, "Invalid multisig script");
layoutHome(); layoutHome();
return; return;
} }
ripemd160(buf, 32, buf + 1); if (msg->has_script_type
buf[0] = coin->address_type_p2sh; // multisig cointype && (msg->script_type == InputScriptType_SPENDWITNESS
base58_encode_check(buf, 21, resp->address, sizeof(resp->address)); || 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 } else if (msg->has_script_type
&& msg->script_type == InputScriptType_SPENDWITNESS && msg->script_type == InputScriptType_SPENDWITNESS
&& coin->has_address_type_p2wpkh) { && coin->has_address_type_p2wpkh) {
uint8_t raw[22+4]; prelen = address_prefix_bytes_len(coin->address_type_p2wpkh);
int prelen = address_prefix_bytes_len(coin->address_type_p2wpkh);
address_write_prefix_bytes(coin->address_type_p2wpkh, raw); address_write_prefix_bytes(coin->address_type_p2wpkh, raw);
raw[prelen] = 0; // version byte raw[prelen] = 0; // version byte
raw[prelen + 1] = 0; // always 0, see bip-142 raw[prelen + 1] = 0; // always 0, see bip-142
@ -646,16 +674,14 @@ void fsm_msgGetAddress(GetAddress *msg)
} else if (msg->has_script_type } else if (msg->has_script_type
&& msg->script_type == InputScriptType_SPENDP2SHWITNESS && msg->script_type == InputScriptType_SPENDP2SHWITNESS
&& coin->has_address_type_p2sh) { && coin->has_address_type_p2sh) {
uint8_t script[22]; prelen = address_prefix_bytes_len(coin->address_type_p2sh);
uint8_t digest[32]; raw[0] = 0; // version byte
int prelen = address_prefix_bytes_len(coin->address_type_p2sh); raw[1] = 20; // push 20 bytes
script[0] = 0; // version byte ecdsa_get_pubkeyhash(node->public_key, raw + 2);
script[1] = 20; // push 20 bytes sha256_Raw(raw, 22, digest);
ecdsa_get_pubkeyhash(node->public_key, script + 2); address_write_prefix_bytes(coin->address_type_p2sh, raw);
sha256_Raw(script, 22, digest); ripemd160(digest, 32, raw + prelen);
ripemd160(digest, 32, digest + prelen); if (!base58_encode_check(raw, 21, resp->address, sizeof(resp->address))) {
address_write_prefix_bytes(coin->address_type_p2sh, digest);
if (!base58_encode_check(digest, 21, resp->address, sizeof(resp->address))) {
fsm_sendFailure(FailureType_Failure_ActionCancelled, "Can't encode address"); fsm_sendFailure(FailureType_Failure_ActionCancelled, "Can't encode address");
layoutHome(); layoutHome();
return; return;

View File

@ -245,6 +245,7 @@ void layoutAddress(const char *address, const char *desc)
static unsigned char bitdata[QR_MAX_BITDATA]; static unsigned char bitdata[QR_MAX_BITDATA];
int a, i, j; int a, i, j;
int side = qr_encode(QR_LEVEL_M, 0, address, 0, bitdata); int side = qr_encode(QR_LEVEL_M, 0, address, 0, bitdata);
int startx;
if (side > 0 && side <= 29) { if (side > 0 && side <= 29) {
oledInvert(0, 0, (side + 2) * 2, (side + 2) * 2); 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); 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); const char **str = split_message((const uint8_t *)address, addrlen, rowlen);
if (desc) { 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"; static const char *btnYes = "Continue";
oledDrawString(OLED_WIDTH - fontCharWidth('\x06') - 1, OLED_HEIGHT - 8, "\x06"); oledDrawString(OLED_WIDTH - fontCharWidth('\x06') - 1, OLED_HEIGHT - 8, "\x06");

View File

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