Chapter 26
Espresso TEE Verifier

Warning: 

this component has no documented requirements. A new requirements page should be created and linked to this component.


Contents



26.1 Overview
26.1.1 Verify
26.1.2 Signature V Overview
26.1.3 RegisterSigner
26.1.4 RegisteredSigners
26.1.5 RegisteredEnclaveHashes



26.1 # Overview

Espresso TEE Verifier contract is the high level contract that underneath calls the specific TEE implementation contracts. Like Espresso SGX TEE verifier

26.1.1 # Verify

Verify function is used by the SequencerInbox contract to verify the signature from a registered signer, a signer is considered registered if the signer address was generated inside one of the registered enclaves. This function recovers the address from the signature and calls all TEE verifier contracts to check whether the address is a registered signer in either one.

26.1.2 # Signature V Overview

Ethereum signatures include a recovery identifier v, originally set to 27 or 28 by adding 27 to the ECDSA value (0 or 1). OpenZeppelin’s ECDSA.recover expects v to be 27 or 28, reflecting this legacy standard. However, modern Go libraries (e.g., go-ethereum) return v as 0 or 1, requiring adjustment (e.g., adding 27) to ensure compatibility with the contract.

1    function verify(signature, userDataHash, TeeType)  { 
2        address signer = ECDSA.recover(userDataHash, signature); 
3 
4        if (teeType == TeeType.SGX) { 
5            if (!espressoSGXTEEVerifier.registeredSigners(signer)) { 
6                return false; 
7            } 
8            return true; 
9        } 
10 
11        if (teeType == TeeType.NITRO) { 
12            if (!espressoNitroTEEVerifier.registeredSigners(signer)) { 
13                return false; 
14            } 
15            return true; 
16        } 
17 
18        revert UnsupportedTeeType(); 
19    }

26.1.3 # RegisterSigner

Forwards the register signer call to the TEE verifier contracts based on the TEE type.

1    function registerSigner(attestation, data, TeeType) 
2        external 
3    { 
4        if (teeType == TeeType.SGX) { 
5            espressoSGXTEEVerifier.registerSigner(attestation, data); 
6            return; 
7        } 
8 
9        if (teeType == TeeType.NITRO) { 
10            espressoNitroTEEVerifier.registerSigner(attestation, data); 
11            return; 
12        } 
13 
14        revert UnsupportedTeeType(); 
15    }

26.1.4 # RegisteredSigners

Returns true if the signer is registered in even one of the TEE verifier contracts.

1    function registeredSigners(signer, TeeType) { 
2        if (teeType == TeeType.SGX) { 
3            return espressoSGXTEEVerifier.registeredSigners(signer); 
4        } 
5 
6        if (teeType == TeeType.NITRO) { 
7            return espressoNitroTEEVerifier.registeredSigners(signer); 
8        } 
9 
10        revert UnsupportedTeeType(); 
11    }

26.1.5 # RegisteredEnclaveHashes

Returns true if the enclave hash is registered in even one of the TEE verifier contracts.

1    function registeredEnclaveHashes(enclaveHash, TeeType) { 
2        if (teeType == TeeType.SGX) { 
3            return espressoSGXTEEVerifier.registeredEnclaveHash(enclaveHash); 
4        } 
5 
6        if (teeType == TeeType.NITRO) { 
7            return espressoNitroTEEVerifier.registeredEnclaveHash(enclaveHash); 
8        } 
9 
10        revert UnsupportedTeeType(); 
11    }