aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/contracts')
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol23
1 files changed, 23 insertions, 0 deletions
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol
index 0a99168eb..20c9abcb8 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol
@@ -31,6 +31,7 @@ contract MixinSignatureValidator is
Caller,
Ecrecover,
EIP712,
+ Trezor,
Contract
}
@@ -107,6 +108,28 @@ contract MixinSignatureValidator is
isValid = signer == recovered;
return isValid;
+ // Signature from Trezor hardware wallet
+ // It differs from web3.eth_sign in the encoding of message length
+ // (Bitcoin varint encoding vs ascii-decimal, the later is not
+ // self-terminating which leads to ambiguities).
+ // See also:
+ // https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
+ // https://github.com/trezor/trezor-mcu/blob/master/firmware/ethereum.c#L602
+ // https://github.com/trezor/trezor-mcu/blob/master/firmware/crypto.c#L36
+ } else if (signatureType == SignatureType.Trezor) {
+ require(signature.length == 66);
+ v = uint8(signature[1]);
+ r = get32(signature, 2);
+ s = get32(signature, 34);
+ recovered = ecrecover(
+ keccak256("\x19Ethereum Signed Message:\n\x41", hash),
+ v,
+ r,
+ s
+ );
+ isValid = signer == recovered;
+ return isValid;
+
// Signature verified by signer contract
} else if (signatureType == SignatureType.Contract) {
isValid = ISigner(signer).isValidSignature(hash, signature);