Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions interfaces/multiproof/tee/INitroEnclaveVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ struct VerifierJournal {
uint64 timestamp;
// Array of certificate hashes in the chain (root to leaf)
bytes32[] certs;
// Certificate notAfter timestamps in seconds (one per cert, matching certs[] order)
uint64[] certExpiries;
// User-defined data embedded in the attestation
bytes userData;
// Cryptographic nonce used for replay protection
Expand Down
4 changes: 3 additions & 1 deletion scripts/multiproof/DeployRiscZeroStack.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,17 @@ contract DeployRiscZeroStack is Script {
verifierId: nitroVerifierId, aggregatorId: bytes32(0), zkVerifier: risc0VerifierRouter
});

// Start with an empty trusted certs array; certs will be auto-cached on first valid proof.
// Start with empty trusted certs and expiries arrays; certs will be auto-cached on first valid proof.
bytes32[] memory trustedCerts = new bytes32[](0);
uint64[] memory trustedCertExpiries = new uint64[](0);

// Use owner as placeholder proofSubmitter; must be updated to TEEProverRegistry
// address after deployment via setProofSubmitter().
NitroEnclaveVerifier nev = new NitroEnclaveVerifier(
owner,
NITRO_MAX_TIME_DIFF,
trustedCerts,
trustedCertExpiries,
nitroRootCert,
owner,
ZkCoProcessorType.RiscZero,
Expand Down
35 changes: 33 additions & 2 deletions snapshots/abi/NitroEnclaveVerifier.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
"name": "initializeTrustedCerts",
"type": "bytes32[]"
},
{
"internalType": "uint64[]",
"name": "initializeTrustedCertExpiries",
"type": "uint64[]"
},
{
"internalType": "bytes32",
"name": "initialRootCert",
Expand Down Expand Up @@ -127,6 +132,11 @@
"name": "certs",
"type": "bytes32[]"
},
{
"internalType": "uint64[]",
"name": "certExpiries",
"type": "uint64[]"
},
{
"internalType": "bytes",
"name": "userData",
Expand Down Expand Up @@ -522,9 +532,9 @@
"name": "trustedIntermediateCerts",
"outputs": [
{
"internalType": "bool",
"internalType": "uint64",
"name": "",
"type": "bool"
"type": "uint64"
}
],
"stateMutability": "view",
Expand Down Expand Up @@ -613,6 +623,11 @@
"name": "certs",
"type": "bytes32[]"
},
{
"internalType": "uint64[]",
"name": "certExpiries",
"type": "uint64[]"
},
{
"internalType": "bytes",
"name": "userData",
Expand Down Expand Up @@ -1000,6 +1015,22 @@
"name": "CallerNotProofSubmitter",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "certsLen",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expiriesLen",
"type": "uint256"
}
],
"name": "CertExpiriesLengthMismatch",
"type": "error"
},
{
"inputs": [
{
Expand Down
6 changes: 3 additions & 3 deletions snapshots/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,11 @@
"sourceCodeHash": "0x032f11e23c188b939ba6cbdc446271b0caad2f4da00535b164a3489291162762"
},
"src/multiproof/tee/NitroEnclaveVerifier.sol:NitroEnclaveVerifier": {
"initCodeHash": "0x8cae758a4b1005bf2904e376fff49c2fb44e8d9d7bef1a33e18a85ee23d540a7",
"sourceCodeHash": "0x78d6c704d56ae8de255be71f5cc94e73e0bea1abd5b7e6dfcb4132174f89202b"
"initCodeHash": "0xac14e4b9130c476ba4ab77ecf70b36153921a9fe6ef3ab96c825aba8d9d18473",
"sourceCodeHash": "0x03614e89919c06e56e91b217702345edf74755c12c082475c4c742f45c201415"
},
"src/multiproof/tee/TEEProverRegistry.sol:TEEProverRegistry": {
"initCodeHash": "0x0ed3443601cd3b08c016dbe4a743fb6f1c1800d211e2edd739e588ed455783b1",
"initCodeHash": "0xfaec22f48eeef0f4ee0575b0e91028a1330fbf6faf52c2fce0f68b500a023970",
"sourceCodeHash": "0xf1ec1f02f540da659a204b26acf986fdce7d7d63bba67a87923f52453fb92ccb"
},
"src/multiproof/tee/TEEVerifier.sol:TEEVerifier": {
Expand Down
2 changes: 1 addition & 1 deletion snapshots/storageLayout/NitroEnclaveVerifier.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"label": "trustedIntermediateCerts",
"offset": 0,
"slot": "2",
"type": "mapping(bytes32 => bool)"
"type": "mapping(bytes32 => uint64)"
},
{
"bytes": "8",
Expand Down
28 changes: 19 additions & 9 deletions src/multiproof/tee/NitroEnclaveVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ contract NitroEnclaveVerifier is Ownable, INitroEnclaveVerifier, ISemver {
/// @dev Configuration mapping for each supported ZK coprocessor type
mapping(ZkCoProcessorType => ZkCoProcessorConfig) public zkConfig;

/// @dev Mapping of trusted intermediate certificate hashes (excludes root certificate)
mapping(bytes32 => bool) public trustedIntermediateCerts;
/// @dev Mapping of trusted intermediate certificate hashes to their notAfter timestamps in seconds (0 = not cached)
mapping(bytes32 => uint64) public trustedIntermediateCerts;

/// @dev Maximum allowed time difference in seconds for attestation timestamp validation
uint64 public maxTimeDiff;
Expand Down Expand Up @@ -143,11 +143,15 @@ contract NitroEnclaveVerifier is Ownable, INitroEnclaveVerifier, ISemver {
/// @dev Event emitted when the maximum time difference is updated
event MaxTimeDiffUpdated(uint64 newMaxTimeDiff);

/// @dev Thrown when initializeTrustedCerts and initializeTrustedCertExpiries have different lengths
error CertExpiriesLengthMismatch(uint256 certsLen, uint256 expiriesLen);

/**
* @dev Initializes the contract with owner, time tolerance and initial trusted certificates
* @param owner Address to be set as the contract owner
* @param initialMaxTimeDiff Maximum time difference in seconds for timestamp validation
* @param initializeTrustedCerts Array of initial trusted intermediate certificate hashes
* @param initializeTrustedCertExpiries Array of notAfter timestamps (seconds) for each initial cert
* @param initialRootCert Hash of the AWS Nitro Enclave root certificate
* @param initialProofSubmitter Address that is authorized to submit proofs
* @param zkCoProcessor Type of ZK coprocessor to configure (RiscZero or Succinct)
Expand All @@ -158,16 +162,20 @@ contract NitroEnclaveVerifier is Ownable, INitroEnclaveVerifier, ISemver {
address owner,
uint64 initialMaxTimeDiff,
bytes32[] memory initializeTrustedCerts,
uint64[] memory initializeTrustedCertExpiries,
bytes32 initialRootCert,
address initialProofSubmitter,
ZkCoProcessorType zkCoProcessor,
ZkCoProcessorConfig memory config,
bytes32 verifierProofId
) {
if (initialMaxTimeDiff == 0) revert ZeroMaxTimeDiff();
if (initializeTrustedCerts.length != initializeTrustedCertExpiries.length) {
revert CertExpiriesLengthMismatch(initializeTrustedCerts.length, initializeTrustedCertExpiries.length);
}
maxTimeDiff = initialMaxTimeDiff;
for (uint256 i = 0; i < initializeTrustedCerts.length; i++) {
trustedIntermediateCerts[initializeTrustedCerts[i]] = true;
trustedIntermediateCerts[initializeTrustedCerts[i]] = initializeTrustedCertExpiries[i];
}
_initializeOwner(owner);
_setRootCert(initialRootCert);
Expand Down Expand Up @@ -239,7 +247,8 @@ contract NitroEnclaveVerifier is Ownable, INitroEnclaveVerifier, ISemver {
revert RootCertMismatch(rootCertHash, certs[0]);
}
for (uint256 j = 1; j < certs.length; j++) {
if (!trustedIntermediateCerts[certs[j]]) {
uint64 expiry = trustedIntermediateCerts[certs[j]];
if (block.timestamp > expiry) {
break;
}
trustedCertPrefixLen += 1;
Expand Down Expand Up @@ -319,7 +328,7 @@ contract NitroEnclaveVerifier is Ownable, INitroEnclaveVerifier, ISemver {
* without affecting the root certificate or other trusted certificates.
*/
function revokeCert(bytes32 certHash) external onlyOwner {
if (!trustedIntermediateCerts[certHash]) {
if (trustedIntermediateCerts[certHash] == 0) {
revert CertificateNotFound(certHash);
}
delete trustedIntermediateCerts[certHash];
Expand Down Expand Up @@ -536,7 +545,7 @@ contract NitroEnclaveVerifier is Ownable, INitroEnclaveVerifier, ISemver {
function _cacheNewCert(VerifierJournal memory journal) internal {
for (uint256 i = journal.trustedCertsPrefixLen; i < journal.certs.length; i++) {
bytes32 certHash = journal.certs[i];
trustedIntermediateCerts[certHash] = true;
trustedIntermediateCerts[certHash] = journal.certExpiries[i];
}
}

Expand Down Expand Up @@ -574,7 +583,8 @@ contract NitroEnclaveVerifier is Ownable, INitroEnclaveVerifier, ISemver {
}
continue;
}
if (!trustedIntermediateCerts[certHash]) {
uint64 expiry = trustedIntermediateCerts[certHash];
if (block.timestamp > expiry) {
journal.result = VerificationResult.IntermediateCertsNotTrusted;
return journal;
}
Expand Down Expand Up @@ -652,8 +662,8 @@ contract NitroEnclaveVerifier is Ownable, INitroEnclaveVerifier, ISemver {
}

/// @notice Semantic version.
/// @custom:semver 0.1.0
/// @custom:semver 0.2.0
function version() public pure virtual returns (string memory) {
return "0.1.0";
return "0.2.0";
}
}
Loading
Loading