diff options
Diffstat (limited to 'packages/contracts')
-rw-r--r-- | packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol | 23 |
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); |