Skip to content

Commit

Permalink
signer/core: add canonical TypedData hashing methods (#25283)
Browse files Browse the repository at this point in the history
  • Loading branch information
nik-suri authored Jul 22, 2022
1 parent 1764f8f commit ba3919c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
19 changes: 19 additions & 0 deletions signer/core/apitypes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,25 @@ type TypedDataDomain struct {
Salt string `json:"salt"`
}

// TypedDataAndHash is a helper function that calculates a hash for typed data conforming to EIP-712.
// This hash can then be safely used to calculate a signature.
//
// See https://eips.ethereum.org/EIPS/eip-712 for the full specification.
//
// This gives context to the signed typed data and prevents signing of transactions.
func TypedDataAndHash(typedData TypedData) ([]byte, string, error) {
domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map())
if err != nil {
return nil, "", err
}
typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message)
if err != nil {
return nil, "", err
}
rawData := fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))
return crypto.Keccak256([]byte(rawData)), rawData, nil
}

// HashStruct generates a keccak256 hash of the encoding of the provided data
func (typedData *TypedData) HashStruct(primaryType string, data TypedDataMessage) (hexutil.Bytes, error) {
encodedData, err := typedData.EncodeData(primaryType, data, 1)
Expand Down
10 changes: 2 additions & 8 deletions signer/core/signed_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,23 +233,17 @@ func (api *SignerAPI) SignTypedData(ctx context.Context, addr common.MixedcaseAd
// - the signature preimage (hash)
func (api *SignerAPI) signTypedData(ctx context.Context, addr common.MixedcaseAddress,
typedData apitypes.TypedData, validationMessages *apitypes.ValidationMessages) (hexutil.Bytes, hexutil.Bytes, error) {
domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map())
sighash, rawData, err := apitypes.TypedDataAndHash(typedData)
if err != nil {
return nil, nil, err
}
typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message)
if err != nil {
return nil, nil, err
}
rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash)))
sighash := crypto.Keccak256(rawData)
messages, err := typedData.Format()
if err != nil {
return nil, nil, err
}
req := &SignDataRequest{
ContentType: apitypes.DataTyped.Mime,
Rawdata: rawData,
Rawdata: []byte(rawData),
Messages: messages,
Hash: sighash,
Address: addr}
Expand Down

0 comments on commit ba3919c

Please sign in to comment.