-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(cardano): Message signing #88
base: master
Are you sure you want to change the base?
Conversation
a0427cb
to
fc9f2b3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ChunkIterator
is an improvement I think 👍
Apart from the comments, there are some formatting errors reported by make pystyle_check
.
core/src/apps/cardano/layout.py
Outdated
displayed_bytes = first_chunk[:MAX_DISPLAYED_SIZE] | ||
bytes_optional_plural = "byte" if data_size == 1 else "bytes" | ||
props: list[tuple[str, bytes | None]] = [ | ||
props: list[PropertyType] = [ | ||
( | ||
f"{title} ({data_size} {bytes_optional_plural}):", | ||
displayed_bytes, | ||
) | ||
] | ||
if data_size > MAX_DISPLAYED_SIZE: | ||
props.append(("...", None)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that we allow signing up to 1024 bytes without hashing, but we only display the first 56 bytes anyway. Is that the inteded behavior, or should we limit the maximum unhashed message length more (e.g. only the 160 bytes mentioned in the doc) but display all bytes?
cc @janmazak
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I think it would be best if we showed the whole ASCII message even if it is long.
For bytes in hex, showing the whole of the message does not really add security for most users --- they are likely to just be annoyed and skip it quickly. And the more paranoid users can avoid the feature (and ask us to show everything --- I doubt there will be demand for that, but we will see) or only use it when long messages are hashed.
218b6a0
to
9d44b58
Compare
common/protob/messages-cardano.proto
Outdated
* @next CardanoMessageItemAck | ||
*/ | ||
message CardanoSignMessageInit { | ||
required uint32 protocol_magic = 1; // network's protocol magic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of this? I don't think we are doing anything with Byron addresses for message signing. And isn't network id part of CardanoAddressParametersType
? (If not, why is it required while the address is optional?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@janmazak Network id isn't part of CardanoAddressParametersType, but you are right in that protocol magic and network id should be as optional as address parameters.
As for byron address, our discussion about them in slack hasn't reached a conclusion yet, please chime in
props = _get_data_chunk_props( | ||
"Empty message", payload_first_chunk, payload_size | ||
) | ||
elif not prefer_hex_display and is_unambiguous_ascii(payload_first_chunk): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wary of doing any guesswork here. Why don't we let the client choose the "display mode" (ascii/hex) explicitly and just validate it's OK?
core/src/apps/cardano/layout.py
Outdated
displayed_bytes = first_chunk[:MAX_DISPLAYED_SIZE] | ||
bytes_optional_plural = "byte" if data_size == 1 else "bytes" | ||
props: list[tuple[str, bytes | None]] = [ | ||
props: list[PropertyType] = [ | ||
( | ||
f"{title} ({data_size} {bytes_optional_plural}):", | ||
displayed_bytes, | ||
) | ||
] | ||
if data_size > MAX_DISPLAYED_SIZE: | ||
props.append(("...", None)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I think it would be best if we showed the whole ASCII message even if it is long.
For bytes in hex, showing the whole of the message does not really add security for most users --- they are likely to just be annoyed and skip it quickly. And the more paranoid users can avoid the feature (and ask us to show everything --- I doubt there will be demand for that, but we will see) or only use it when long messages are hashed.
common/protob/messages-cardano.proto
Outdated
repeated uint32 signing_path = 3; // BIP-32-style path to derive the signing key from master node | ||
required uint32 payload_size = 4; // size of the payload to be signed | ||
required bool hash_payload = 5; // whether to hash the payload before signing | ||
repeated uint32 key_path = 6; // mutually exclusive with address_parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This field seems not really useful --- if we use key hash for the address field, it will be the key used to sign the msg, so it seems we can just use signing_path
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assumed it was implied by this part of the doc that we want to separate the two paths.
Since the address field might be unrelated to the key used for signing and it seems impossible to completely determine what the existing applications use, we don’t want to impose restrictions on the derivation paths used.
Did I understand it wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sentence you quote is somewhat ambiguous. What I meant was that in general according to CIP-8 it might be unrelated and some historical use could be there in case of address. The usage of just key hash in the address field is new (AFAIK --- discussed with Ryan, gitmatchtl etc.), so we do not need to support arbitrary keys different from signing keys there. I'd be OK if you kept it implemented like this (if it works now). What makes sense to me is not to display the key path twice if it is the same --- i.e. if there is just a key hash in the address field and the key is used for signing, only show that once (I'm not sure at which place, because I don't know how people use the arbitrary msg signing feature, but I'd perhaps put more emphasis on the key that is being used to sign and always explicitly say what that key path is, and hide info about the address field from the user if it does not say anything new.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I won't add "arbitrary key in addr field (different from signing key)" to Ledger because it would cut into APDU space. I'll see today/tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we always show the message hash? (Even for ascii messages that are signed raw, not as hash.) We were told that the hash is typically displayed by dapp/sw wallet, so it's useful to the users to compute and show it.
Yes |
0865cb3
to
3a13795
Compare
|
|
d14b219
to
17be8c3
Compare
core/src/apps/cardano/layout.py
Outdated
if not is_unambiguous_ascii(payload_first_chunk): | ||
raise ProcessError( | ||
"Payload cannot be decoded as ASCII or its decoding leads to a visually ambiguous string" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to do this validation in sign_message.py
(and then just assert it here) - currently, there is no validation performed as late as when displaying something by the UI code.
} | ||
} | ||
] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also add a long ascii message (so that we have a UI test for that).
) | ||
|
||
return CardanoSignMessageFinished( | ||
signature=signature, address=address, pub_key=node.public_key() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙏
signature=signature, address=address, pub_key=node.public_key() | |
signature=signature, address=address, pub_key=remove_ed25519_prefix(node.public_key()) |
e3c4907
to
8381708
Compare
8381708
to
8ceefbf
Compare
8ceefbf
to
b3b317a
Compare
Show signing path, validate with keychain, show address parameters and increase max displayed bytes of first payload chunk unless signing hash. Also add issue number to changelog.
This makes the behavior more consistent with Ethereum message signing.
This ends up being useful for software wallets.
b3b317a
to
4bb7871
Compare
No description provided.