Skip to content

Commit 221ddc5

Browse files
Move cert into standardized part of OSP validation
1 parent 98fd84a commit 221ddc5

File tree

3 files changed

+50
-48
lines changed

3 files changed

+50
-48
lines changed

src/osp/ICustomDAProofValidator.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ pragma solidity ^0.8.0;
77
/**
88
* @title ICustomDAProofValidator
99
* @notice Interface for custom data availability proof validators
10-
* @dev All proofs MUST start with [certKeccak256(32), offset(8), ...] format
11-
* Implementations MUST validate certKeccak256 against the certificate.
10+
* @dev All proofs MUST start with [certKeccak256(32), offset(8), certSize(8), certificate, ...]
11+
* The OSP validates certKeccak256 matches the machine's request before calling this
1212
*/
1313
interface ICustomDAProofValidator {
1414
/**
1515
* @notice Validates a custom DA proof and returns the preimage chunk
16-
* @param proof The complete proof data starting with [certKeccak256(32), offset(8), ...]
16+
* @param proof The complete proof data starting with [certKeccak256(32), offset(8), certSize(8), certificate, ...]
1717
* @return preimageChunk The 32-byte chunk of preimage data
1818
*/
1919
function validateReadPreimage(

src/osp/OneStepProverHostIo.sol

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,18 +236,33 @@ contract OneStepProverHostIo is IOneStepProver {
236236

237237
bytes calldata customProof = proof[proofOffset:];
238238

239-
// All CustomDA proofs must start with [certKeccak256(32), offset(8), ...]
240-
require(customProof.length >= 40, "CUSTOM_DA_PROOF_TOO_SHORT");
239+
// All CustomDA proofs must start with [certKeccak256(32), offset(8), certSize(8), certificate, ...]
240+
require(customProof.length >= 48, "CUSTOM_DA_PROOF_TOO_SHORT");
241241

242+
// Extract standardized header
242243
bytes32 certKeccak256;
244+
uint256 requestedOffsetInProof;
245+
uint256 certSize;
243246
assembly {
244247
certKeccak256 := calldataload(add(customProof.offset, 0))
248+
requestedOffsetInProof := shr(192, calldataload(add(customProof.offset, 32))) // Read 8 bytes at position 32
249+
certSize := shr(192, calldataload(add(customProof.offset, 40))) // Read 8 bytes at position 40
245250
}
246251

247-
// leafContents containts the preimage hash that we have proven to exist in machine memory.
252+
// SECURITY CHECK: Verify the offset in the proof matches what the machine requested
253+
require(requestedOffsetInProof == preimageOffset, "WRONG_OFFSET");
254+
255+
require(customProof.length >= 48 + certSize, "PROOF_TOO_SHORT_FOR_CERT");
256+
257+
// Extract and validate certificate
258+
bytes calldata certificate = customProof[48:48 + certSize];
259+
require(keccak256(certificate) == certKeccak256, "INVALID_CERTIFICATE_HASH");
260+
261+
// SECURITY CHECK: Verify this is the certificate the machine requested
262+
// leafContents contains the preimage hash that we have proven to exist in machine memory
248263
require(certKeccak256 == leafContents, "WRONG_CERTIFICATE_HASH");
249264

250-
// Now delegate to the custom validator
265+
// Now delegate to the custom validator with the full proof
251266
extracted = customDAValidator.validateReadPreimage(customProof);
252267

253268
// Ensure we got a valid response

src/osp/ReferenceDAProofValidator.sol

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,76 +13,63 @@ import "./ICustomDAProofValidator.sol";
1313
contract ReferenceDAProofValidator is ICustomDAProofValidator {
1414
/**
1515
* @notice Validates a ReferenceDA proof and returns the preimage chunk
16-
* @param proof ReferenceDA proof format: [certKeccak256(32), offset(8), Version(1), CertificateSize(8), Certificate, PreimageSize(8), PreimageData]
16+
* @param proof Standardized CustomDA proof format is: [certKeccak256(32), offset(8), certSize(8), certificate]
17+
followed by the ReferenceDA specific: [version(1), preimageSize(8), preimageData]
1718
* @return preimageChunk The 32-byte chunk at the specified offset
1819
*/
1920
function validateReadPreimage(
2021
bytes calldata proof
2122
) external pure override returns (bytes memory preimageChunk) {
22-
// Proof format: [certKeccak256(32), offset(8), Version(1), CertificateSize(8), Certificate, PreimageSize(8), PreimageData]
23-
require(proof.length >= 58, "Proof too short"); // 32 + 8 + 1 + 8 + 8 + at least 1 byte
24-
25-
// Extract certKeccak256 and offset from enhanced proof wrapper
26-
bytes32 certKeccak256;
23+
// Extract offset from standardized header (already validated by OSP)
2724
uint256 offset;
25+
uint256 certSize;
2826
assembly {
29-
certKeccak256 := calldataload(add(proof.offset, 0))
30-
offset := shr(192, calldataload(add(proof.offset, 32))) // Read 8 bytes as uint256
27+
offset := shr(192, calldataload(add(proof.offset, 32))) // Read 8 bytes at position 32
28+
certSize := shr(192, calldataload(add(proof.offset, 40))) // Read 8 bytes at position 40
3129
}
3230

33-
// The actual custom proof starts at offset 40
34-
uint256 customProofStart = 40;
31+
// Certificate has already been validated by OSP, just extract it
32+
uint256 certStart = 48;
33+
require(proof.length >= certStart + certSize, "Proof too short for certificate");
34+
bytes calldata certificate = proof[certStart:certStart + certSize];
3535

36-
// Verify version
37-
require(proof[customProofStart] == 0x01, "Unsupported proof version");
36+
// Validate certificate format for ReferenceDA
37+
require(certificate.length == 33, "Invalid certificate length");
38+
require(certificate[0] == 0x01, "Invalid certificate header");
3839

39-
// Extract certificate size
40-
uint256 certSize;
41-
assembly {
42-
certSize := shr(192, calldataload(add(proof.offset, add(customProofStart, 1)))) // Read 8 bytes as uint256
43-
}
44-
require(certSize == 33, "Certificate must be 33 bytes");
40+
// Extract SHA256 hash from certificate
41+
bytes32 sha256Hash = bytes32(certificate[1:33]);
4542

46-
// Extract and verify certificate
47-
uint256 certStart = customProofStart + 9; // Skip version(1) + certSize(8)
48-
bytes memory certificate = proof[certStart:certStart + certSize];
49-
require(certificate[0] == 0x01, "Invalid certificate header");
50-
require(keccak256(certificate) == certKeccak256, "Invalid certificate hash");
43+
// Custom data starts after certificate
44+
uint256 customDataStart = certStart + certSize;
45+
require(proof.length >= customDataStart + 9, "Proof too short for custom data");
5146

52-
// Extract SHA256 from certificate
53-
bytes32 sha256Hash;
54-
assembly {
55-
sha256Hash := mload(add(certificate, 33)) // Skip length prefix and header byte
56-
}
47+
// Verify version
48+
require(proof[customDataStart] == 0x01, "Unsupported proof version");
5749

5850
// Extract preimage size
59-
uint256 preimageOffset = certStart + certSize;
6051
uint256 preimageSize;
6152
assembly {
62-
preimageSize := shr(192, calldataload(add(proof.offset, preimageOffset))) // Read 8 bytes as uint256
53+
preimageSize := shr(192, calldataload(add(proof.offset, add(customDataStart, 1))))
6354
}
6455

65-
require(proof.length >= preimageOffset + 8 + preimageSize, "Invalid proof length");
66-
67-
// Extract preimage data
68-
bytes memory preimage = proof[preimageOffset + 8:preimageOffset + 8 + preimageSize];
56+
require(proof.length >= customDataStart + 9 + preimageSize, "Invalid proof length");
6957

70-
// Verify SHA256 hash matches
71-
require(sha256(abi.encodePacked(preimage)) == sha256Hash, "Invalid preimage hash");
58+
// Extract and verify preimage
59+
bytes calldata preimage = proof[customDataStart + 9:customDataStart + 9 + preimageSize];
60+
require(sha256(preimage) == sha256Hash, "Invalid preimage hash");
7261

7362
// Extract chunk at offset
74-
uint256 chunkStart = offset;
7563
uint256 chunkEnd = offset + 32;
7664
if (chunkEnd > preimage.length) {
7765
chunkEnd = preimage.length;
7866
}
7967

80-
uint256 chunkSize = chunkEnd - chunkStart;
8168
preimageChunk = new bytes(32);
82-
83-
if (chunkSize > 0) {
69+
if (offset < preimage.length) {
70+
uint256 chunkSize = chunkEnd - offset;
8471
for (uint256 i = 0; i < chunkSize; i++) {
85-
preimageChunk[i] = preimage[chunkStart + i];
72+
preimageChunk[i] = preimage[offset + i];
8673
}
8774
}
8875

0 commit comments

Comments
 (0)