Ethereum EIP712 Signature 2021 (2024)

Suite Definition

The Ethereum EIP 712 signature suite 2021 MUST be used in conjunction with the signing and verification algorithms in the Data Integrity [[DATA-INTEGRITY]] specification. The suite consists of the following algorithms:

Parameter Value Specification
canonicalization algorithm
(if automatically-generated `types` object is present)
JCS [[JCS]]
message digest algorithm EIP712 uses Keccak-256 [[EIP712]]
signature algorithm EIP712 uses ECDSA K-256 [[EIP712]]

To generate the EIP712 signature, EIP712 requires TypedData which is a JSON object containing type information, domain separator parameters and the message object.

TypedData MUST be a JSON object according to the EIP712 specification and contains properties types, domain, primaryType and message. The types property of TypedData can be generated by the types generation algorithm if not provided as input. Note: in the case of this generation, elements will be normalized according to [JCS].

  • types MUST be a JSON array with at least two entries. The first entry refers to the EIP712Domain property that contains the JSON schema according to the EIP712 specification. Remaining entries MUST be the JSON schemas of the message to be signed in the EIP712 format. types MUST contain a property proof of type Proof which contains the JSON schema for all properties of the final data integrity proof proof property that need to be signed.
  • message MUST be the unsigned data document that contains the message to be signed. The message MUST contain a proof property with values set to the values of the properties in the resulting data-cite="DATA-INTEGRITY#dfn-signed-data-document">signed data document's proof property that are expected to be signed.
  • domain MUST have the value as defined in EIP712. If domain is not provided, a default object is applied with the only property being name with value EthereumEip712Signature2021
  • primaryType MUST have the value as defined in EIP712. primaryType represents the top-level type of the object in the EIP712 message but does not have to correspond to any of the types in the message.

Types Generation

If TypedData's types object is not provided to the signature suite, the suite MUST generate the JSON object by inferring types from the input document, and optionally a provided `primaryType`.

In case of ambiguous types, the algorithm SHOULD defer to using the most liberal option. For example, a number should be inferred as the uint256 type even if that specific number can fit in a uint8 type.

The types generation algorithm is defined as follows:

  1. Creates a mapping output from string to TypedDataField[] types, where TypedDataField is an object consisting of two string properties - name and type
  2. Creates an empty array types of TypedDataField to collect all the fields
  3. Canonicalizes the input document using the canonicalization algorithm
  4. If `primaryType` is not provided, set `primaryType = "Document"` else use the provided value.
  5. For each property in the canonicalized input document, iterated in lexicographic order of property name according to RFC 8785 Section 3.2.3, the algorithm checks the type of the value specific to the implementation language.
  6. If the type of the value is a primitive boolean, number or string, push an object to types with the name set to the property name of the input document, and type set to the corresponding EIP712 primitive type
    1. boolean - maps to bool
    2. number - maps to uint256
    3. string - maps to string
  7. If the type of the value is an array, ensure each element of the array has the same primitive type. Push an object to types with the name set to the property name of the input document and type set to the corresponding EIP712 array type
    1. boolean[] - maps to bool[]
    2. number[] - maps to uint256[]
    3. string[] - maps to string[]

    WARNING: The current algorithm definition does not support auto generating types for arrays of structs. We need to work on that.

  8. If the type of the value is an object, call the function recursively on the inner object, and set the return value equal to _recursiveOutput.
    1. Set _recursiveTypes = _recursiveOutput[primaryType]
    2. Push an object to types with the name set to the property name of the input document and type set to the CapitalCased property name - propertyType
    3. Set output[propertyType] = _recursiveTypes
    4. Loop over _recursiveOutput, and if any keys other than primaryType are present, add them directly to output. If any such key already has an entry in output, raise an error.
  9. Finally, set output[primaryType] to the types array that was generated. Return output
The following is an example of the autogenerated schema. Given the following input document and no `primaryType`:
 { "@context": ["https://schema.org", "https://w3id.org/security/v2"], "@type": "Person", "name": { "first": "Jane", "last": "Doe" }, "otherData": { "jobTitle": "Professor", "school": "University of ExampleLand" }, "telephone": "(425) 123-4567", "email": "[email protected]" } 
It will generate the following schema:
 { "Document": [ { "name": "@context", type: "string[]" }, { "name": "@type", type: "string" }, { "name": "email", type: "string" }, { "name": "name", type: "Name" }, { "name": "otherData", type: "OtherData" }, { "name": "telephone", type: "string" } ], "Name": [ { "name": "first", type: "string" }, { "name": "last", type: "string" } ], "OtherData": [ { "name": "jobTitle", type: "string" }, { "name": "school", type: "string" } ] } 

Verification Method

The cryptographic material used to verify a data integrity proof is called the verification method.

This signature suite does not define a new verification method type. The following verification method types can be used with Ethereum EIP712 Signature 2021:

Proof Representation

The cryptographic material used to represent a data integrity proof is called the proof type.

This specification relies on the output of the EIP712 signature function.

Ethereum EIP712 Signature 2021

The verificationMethod property of the proof SHOULD be a URI. Dereferencing the verificationMethod SHOULD result in an object of type EcdsaSecp256k1VerificationKey2019, EcdsaSecp256k1RecoveryMethod2020, or JsonWebKey2020. If the dereferenced verification method object is of type JsonWebKey2020, it MUST contain a property publicKeyJwk, containing a secp256k1 public key represented as a JSON Web Key (JWK) according to RFC 8812 Section 3.1.

The type property of the proof MUST be EthereumEip712Signature2021.

The created property of the proof MUST be an [ISO_8601] formated date string.

The proofPurpose property of the proof MUST be a string, and SHOULD match the verification relationship expressed by the verification method controller.

The proofValue property of the proof MUST be the hex encoded output of the EIP712 signature function according [EIP712].

The eip712 property MUST contain meta-information about the signature generation process that can be used when the signature is verified. It MUST contain the following properties:

  • types MUST be a URI that results in an object that contains the JSON schema that describes the message to be signed according to EIP712, or an object that contains the JSON schema itself.
  • domain MUST be the domain property of the EIP712 TypedData object.
  • primaryType MUST be the primaryType property of the EIP712 TypedData object.

The canonicalizationHash property of the proof, if present, MUST contain a value computed from the input document and proof as specified in Linked Data Canonicalization Hash.

The following is a non-normative example of an EthereumEip712Signature2021 proof:

 { "proof": { "type": "EthereumEip712Signature2021", "created": "2019-12-11T03:50:55Z", "proofPurpose": "assertionMethod", "proofValue": "0xc565d38982e1a5004efb5ee390fba0a08bb5e72b3f3e91094c66bc395c324f785425d58d5c1a601372d9c16164e380c63e89f1e0ea95fdefdf7b2854c4f938e81b", "verificationMethod": "did:example:aaaabbbb#issuerKey-1", "eip712": { "types": "https://example.com/schemas/v1", "primaryType": "VerifiableCredential" } } } 

JSON-LD Context

The @context property of a JSON-LD document using this signature suite SHOULD include the following URI string: https://w3id.org/security/suites/eip712sig-2021/v1.

To ensure the integrity of a JSON-LD document's RDF data model, use the proof canonicalizationHash property described in .

Linked Data Canonicalization Hash

IRI
https://w3id.org/security/suites/eip712sig-2021#canonicalizationHash
Status
unstable
Domain
sec:Signature
Range
xsd:string

Linked data proof suites conventionally create a proof verification hash for signing and verifying the document and proof as JSON-LD/RDF, using JSON-LD context expansion, RDF Deserialization, and [[RDF-DATASET-CANONICALIZATION]]. This signature suite instead signs a structured TypedData object derived from the JSON-LD document, without JSON-LD or RDF processing. For use cases where JSON-LD and RDF processing is needed, this document specifies an optional property of a EthereumEip712Signature2021 proof, canonicalizationHash, for a verification hash computed with JSON-LD/RDF processing and URDNA2015. Signing over this property and verifying it during proof verification secures the RDF data model of the signed document. Construction of the canonicalizationHash value is defined in .

The input document provided to MUST be the document as it would be returned after proof creation (with the eip712 proof property) except without the proofValue proof property.

When preparing the TypedData structure for signing or verification, the canonicalizationHash value MUST be included in the message's proof object.

Note that although the proof object in the input document provided to includes the eip712 property, the proof object in the message in the TypedData structure does not include the eip712 property. That is because the properties of the eip712 object are instead included in non-message parts of the TypedData structure; but for the purpose of linked data integrity, it is desired to include the eip712 properties as they would be in the returned document. After signing, proof properties eip712, proofValue and canonicalizationHash are inserted into the proof object before returning the document.

Linked Data Canonicalization Hash Algorithm

Given an input unsigned data document document which includes a proof property with object value proof, the value for canonicalizationHash is computed as follows:

  1. Convert document from JSON-LD to an RDF dataset, dataset, according to JSON-LD 1.1 Processing Algorithms and API § 8.1 Deserialize JSON-LD to RDF Algorithm.
  2. Canonicalize dataset according to [[RDF-DATASET-CANONICALIZATION]].
  3. Serialize dataset in N-Quads format as nquads.
  4. Sort the lines of nquads lexicographically (comparing each N-Quad line as a UTF-8 byte string, sorting in ascending order).
  5. Compute the SHA-256 digest of nquads (including the trailing newline) as digest (encoded as a lowercase hexadecimal value).
  6. Return digest.

Test Vectors

The following test vectors are provided to assist implementers. Some of the given test vectors specify inputOptions which are options to be passed when creating a proof. These can include options specifying the domain, types, primaryType, verificationMethod, date, embedAsURI, and embed.

The following is an example Ethereum-compatible hexadecimal private key, and corresponding did:pkh verificationMethod that can be used to assist with test vectors:

 { "privateKey": "0x149195a4059ac8cafe2d56fc612f613b6b18b9265a73143c9f6d7cfbbed76b7e", "verificationMethod": "did:pkh:eip155:1:0xAED7EA8035eEc47E657B34eF5D020c7005487443#blockchainAccountId" } 

The following are some example input documents that will be provided to the Ethereum EIP712 Signature Suite, to generate various type of output proofs:

 { "testBasicDocument": { "@context": ["https://schema.org", "https://w3id.org/security/v2"], "@type": "Person", "firstName": "Jane", "lastName": "Does", "jobTitle": "Professor", "telephone": "(425) 123-4567", "email": "[email protected]" }, "testNestedDocument": { "@context": ["https://schema.org", "https://w3id.org/security/v2"], "@type": "Person", "data": { "name": { "firstName": "John", "lastName": "Doe" }, "job": { "jobTitle": "Professor", "employer": "University of Waterloo" } }, "telephone": "(425) 123-4567" } } 

Basic Document - Types Generation - No Embedding

This test vector has not yet been verified by more than one independent implementation.

With the following inputOptions provided to the signature suite along with the testBasicDocument input document:

 { "date": "2021-08-30T13:28:02Z", "verificationMethod": "did:pkh:eip155:1:0xAED7EA8035eEc47E657B34eF5D020c7005487443#blockchainAccountId", "domain": { "name": "Test" } } 

The following is the resulting proof object:

 { "created": "2021-08-30T13:28:02Z", "proofPurpose": "assertionMethod", "proofValue": "0xbbdf2914c7572185bbc263e066dfb43f3136e4441fddb3fe3ea4541bbf7fd1f00d8e5af3ce4fbb1f2ebd5256f39b22cef7f285189df2976ea0c385c77f0a42791b", "type": "EthereumEip712Signature2021", "verificationMethod": "did:pkh:eip155:1:0xAED7EA8035eEc47E657B34eF5D020c7005487443#blockchainAccountId", } 

Nested Document - TypedData Provided - Embedded EIP712 Properties

With the following inputOptions provided to the signature suite along with the testNestedDocument input document:

 { "verificationMethod": "did:pkh:eip155:1:0xAED7EA8035eEc47E657B34eF5D020c7005487443#blockchainAccountId", "types": { "Data": [ { "name": "job", "type": "Job" }, { "name": "name", "type": "Name" } ], "Document": [ { "name": "@context", "type": "string[]" }, { "name": "@type", "type": "string" }, { "name": "data", "type": "Data" }, { "name": "telephone", "type": "string" }, { "name": "proof", "type": "Proof" } ], "Job": [ { "name": "employer", "type": "string" }, { "name": "jobTitle", "type": "string" } ], "Proof": [ { "name": "created", "type": "string" }, { "name": "proofPurpose", "type": "string" }, { "name": "type", "type": "string" }, { "name": "verificationMethod", "type": "string" } ], "Name": [ { "name": "firstName", "type": "string" }, { "name": "lastName", "type": "string" } ] }, "domain": { "name": "Test" }, "date": "2021-08-30T13:28:02Z", "embed": true } 

The following is the resulting proof object:

 { "created": "2021-08-30T13:28:02Z", "eip712": { "domain": { "name": "Test", }, "primaryType": "Document", "types": { "Data": [ { "name": "job", "type": "Job", }, { "name": "name", "type": "Name", }, ], "Document": [ { "name": "@context", "type": "string[]", }, { "name": "@type", "type": "string", }, { "name": "data", "type": "Data", }, { "name": "telephone", "type": "string", }, { "name": "proof", "type": "Proof", }, ], "Job": [ { "name": "employer", "type": "string", }, { "name": "jobTitle", "type": "string", }, ], "Name": [ { "name": "firstName", "type": "string", }, { "name": "lastName", "type": "string", }, ], "Proof": [ { "name": "created", "type": "string", }, { "name": "proofPurpose", "type": "string", }, { "name": "type", "type": "string", }, { "name": "verificationMethod", "type": "string", }, ], }, }, "proofPurpose": "assertionMethod", "proofValue": "0xcf5844be1f1a5c1a083565d492ab4bee93bd0e24a4573bd8ff47331ad225b9d11c4831aade8d071f4abb8c9e266aaaf30612c582c2bc8f082b8788448895fa4a1b", "type": "EthereumEip712Signature2021", "verificationMethod": "did:pkh:eip155:1:0xAED7EA8035eEc47E657B34eF5D020c7005487443#blockchainAccountId", } 

Nested Document - Types Generation - TypedData Schema as URI

With the following inputOptions provided to the signature suite along with the testNestedDocument input document:

 { "embedAsURI": true, "date": "2021-08-30T13:28:02Z", "verificationMethod": "did:pkh:eip155:1:0xAED7EA8035eEc47E657B34eF5D020c7005487443#blockchainAccountId", "domain": { "name": "Test" } } 

The following is the resulting proof object:

 { "created": "2021-08-30T13:28:02Z", "proofPurpose": "assertionMethod", "type": "EthereumEip712Signature2021", "verificationMethod": "did:pkh:eip155:1:0xAED7EA8035eEc47E657B34eF5D020c7005487443#blockchainAccountId", "proofValue": "0x8327ad5e4b2426eac7626400c75f000c3e04caf2a863b888988e4e85533880183d4b9cc6870183e55dabfa96b9486624f45ef849bb146257d123f297a2dbf3a11c", "eip712": { "domain": { "name": "Test" }, "types": "https://example.org/types.json", "primaryType": "Document" } } 

Dereferencing the types URI should result in the following object:

 { "Data": [ { "name": "job", "type": "Job" }, { "name": "name", "type": "Name" } ], "Job": [ { "name": "employer", "type": "string" }, { "name": "jobTitle", "type": "string" } ], "Name": [ { "name": "firstName", "type": "string" }, { "name": "lastName", "type": "string" } ], "Document": [ { "name": "@context", "type": "string[]" }, { "name": "@type", "type": "string" }, { "name": "data", "type": "Data" }, { "name": "proof", "type": "Proof" }, { "name": "telephone", "type": "string" } ], "Proof": [ { "name": "created", "type": "string" }, { "name": "proofPurpose", "type": "string" }, { "name": "type", "type": "string" }, { "name": "verificationMethod", "type": "string" } ] } 

The example URI provided above is not a real URI that would dereference, but outlines the expected behaviour.

Nested Document - Types Generation - Types Embedded

With the following inputOptions provided to the signature suite along with the testNestedDocument input document:

 { "date": "2021-08-30T13:28:02Z", "verificationMethod": "did:pkh:eip155:1:0xAED7EA8035eEc47E657B34eF5D020c7005487443#blockchainAccountId", "domain": { "name": "Test" }, "embed": true } 

The following is the resulting proof object:

 { "created": "2021-08-30T13:28:02Z", "eip712": { "domain": { "name": "EthereumEip712Signature2021", }, "primaryType": "Document", "types": { "Data": [ { "name": "job", "type": "Job", }, { "name": "name", "type": "Name", }, ], "Document": [ { "name": "@context", "type": "string[]", }, { "name": "@type", "type": "string", }, { "name": "data", "type": "Data", }, { "name": "proof", "type": "Proof", }, { "name": "telephone", "type": "string", }, ], "Job": [ { "name": "employer", "type": "string", }, { "name": "jobTitle", "type": "string", }, ], "Name": [ { "name": "firstName", "type": "string", }, { "name": "lastName", "type": "string", }, ], "Proof": [ { "name": "created", "type": "string", }, { "name": "proofPurpose", "type": "string", }, { "name": "type", "type": "string", }, { "name": "verificationMethod", "type": "string", }, ], }, }, "proofPurpose": "assertionMethod", "proofValue": "0x7d57ace2be9cc3944aac023f66130935e489bbb1c9b469a4a5b4f16e5c298b57291bc80d52c6f873b11f4bf45c97c6e2506419af7506eaac5374e9ed381fcc5b1b", "type": "EthereumEip712Signature2021", "verificationMethod": "did:pkh:eip155:1:0xAED7EA8035eEc47E657B34eF5D020c7005487443#blockchainAccountId", } 

A conforming document is any concrete expression of the data model that complies with the normative statements in this specification. Specifically, all relevant normative statements in Sections and of this document MUST be enforced.

A conforming processor is any algorithm realized as software and/or hardware that generates or consumes a conforming document. Conforming processors MUST produce errors when non-conforming documents are consumed.

This document also contains examples that contain JSON and JSON-LD content. Some of these examples contain characters that are invalid JSON, such as inline comments (//) and the use of ellipsis (...) to denote information that adds little value to the example. Implementers are cautioned to remove this content if they desire to use the information as valid JSON or JSON-LD.

Security Considerations

The following section describes security considerations that developers implementing this specification should be aware of in order to create secure software.

This specification relies on JCS, which is used to generate the `types` object deterministically if not provided. please review [[JCS]] for details.

This specification relies on EIP712, please review [[EIP712]].

TODO: We need to add a complete list of security considerations, e.g., what happens if EIP712 JSON schema does not match the message to be signed.

Signing over JSON-LD expanded terms is optional.

Linked data signatures suites typically use JSON-LD to RDF Deserialization, RDF Dataset Canonicalization and serialization as N-Quads, as part of constructing the data to sign. This signature suite differs by instead signing based on the JSON document structure more directly, without conversion to RDF. This is supposed to enable a more human-readable signing input. However, it means that information from the JSON-LD context is not included in the signing input that otherwise would be. If the referenced JSON-LD context files are changed, changing the definition of some terms, it is possible that the proof signature may remain valid but the underlying JSON-LD/RDF data could be different.

In some cases, this could create security issues if unmitigated, because the semantic disambiguation information is not included in the signing method's integrity guarantees. One common method for additionally securing those linked data documents is to add an additional, but optional, "semantic integrity" hash to the proof object before URDNA canonicalization. This digest then acts as a kind of checksum that the verifier can use to check the integrity of the expanded context. The algorithms for generating this digest (and implicitly, the algorithm for how to verify it) can be found in the Linked Data Proof specification.

To prevent this kind of issue, this specification defines a mechanism for including a cryptographic digest of the RDF data in the proof property, which is included in the signing input: (canonicalizationHash proof property). While it is not expected that EIP-712 signers will be able to natively understand this canonicalization hash, signers and verifiers of this proof suite using JSON-LD processing can use it to ensure the integrity of the signed data document as a linked data document. When using this signature suite with JSON-LD documents, SHOULD be used.

Ethereum EIP712 Signature 2021 (2024)
Top Articles
How Drone Technologies Enhance Event Security in 2024?
Common cyber security measures | nibusinessinfo.co.uk
English Bulldog Puppies For Sale Under 1000 In Florida
Katie Pavlich Bikini Photos
Gamevault Agent
Pieology Nutrition Calculator Mobile
Hocus Pocus Showtimes Near Harkins Theatres Yuma Palms 14
Hendersonville (Tennessee) – Travel guide at Wikivoyage
Compare the Samsung Galaxy S24 - 256GB - Cobalt Violet vs Apple iPhone 16 Pro - 128GB - Desert Titanium | AT&T
Vardis Olive Garden (Georgioupolis, Kreta) ✈️ inkl. Flug buchen
Craigslist Dog Kennels For Sale
Things To Do In Atlanta Tomorrow Night
Non Sequitur
Crossword Nexus Solver
How To Cut Eelgrass Grounded
Pac Man Deviantart
Alexander Funeral Home Gallatin Obituaries
Energy Healing Conference Utah
Geometry Review Quiz 5 Answer Key
Hobby Stores Near Me Now
Icivics The Electoral Process Answer Key
Allybearloves
Bible Gateway passage: Revelation 3 - New Living Translation
Yisd Home Access Center
Pearson Correlation Coefficient
Home
Shadbase Get Out Of Jail
Gina Wilson Angle Addition Postulate
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Walmart Pharmacy Near Me Open
Marquette Gas Prices
A Christmas Horse - Alison Senxation
Ou Football Brainiacs
Access a Shared Resource | Computing for Arts + Sciences
Vera Bradley Factory Outlet Sunbury Products
Pixel Combat Unblocked
Movies - EPIC Theatres
Cvs Sport Physicals
Mercedes W204 Belt Diagram
Mia Malkova Bio, Net Worth, Age & More - Magzica
'Conan Exiles' 3.0 Guide: How To Unlock Spells And Sorcery
Teenbeautyfitness
Where Can I Cash A Huntington National Bank Check
Topos De Bolos Engraçados
Sand Castle Parents Guide
Gregory (Five Nights at Freddy's)
Grand Valley State University Library Hours
Hello – Cornerstone Chapel
Stoughton Commuter Rail Schedule
Nfsd Web Portal
Selly Medaline
Latest Posts
Article information

Author: Maia Crooks Jr

Last Updated:

Views: 6264

Rating: 4.2 / 5 (63 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Maia Crooks Jr

Birthday: 1997-09-21

Address: 93119 Joseph Street, Peggyfurt, NC 11582

Phone: +2983088926881

Job: Principal Design Liaison

Hobby: Web surfing, Skiing, role-playing games, Sketching, Polo, Sewing, Genealogy

Introduction: My name is Maia Crooks Jr, I am a homely, joyous, shiny, successful, hilarious, thoughtful, joyous person who loves writing and wants to share my knowledge and understanding with you.