first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
# inclusion-proof
## Purpose
Verifies an RFC 6962 Merkle inclusion proof as returned by Sigstore Rekor.
Given a leaf (the canonical body a Rekor entry was logged as), a sibling
audit path, the leaf's log index, the tree size at inclusion time, and the
signed root hash, recomputes the root and confirms it matches. This is the
cryptographic half of Rekor trust — once the root matches, the transparency
log has published the entry and cannot later lie about having done so.
## Features
- RFC 6962 hashing with explicit domain separators (`0x00` for leaves,
`0x01` for interior nodes).
- Correct handling of last-node-at-level carrying (odd tree sizes).
- Structured `RekorInclusionError` when `logIndex` is out of range.
- Exposes `rfc6962LeafHash` for batch / cache use-cases.
## Usage: Basic Example
```ts
import { verifyRfc6962InclusionProof } from "@suaveplan/slsa";
const { valid, computedRootHex } = verifyRfc6962InclusionProof({
leafBytes: new TextEncoder().encode(entry.body),
hashes: entry.verification.inclusionProof.hashes,
logIndex: entry.logIndex,
treeSize: entry.verification.inclusionProof.treeSize,
expectedRootHex: entry.verification.inclusionProof.rootHash,
});
```
## Usage: Advanced Example
```ts
import {
RekorClient,
rfc6962LeafHash,
verifyRfc6962InclusionProof,
} from "@suaveplan/slsa";
const client = new RekorClient();
const entry = await client.uploadHashedrekord(rekord);
const leafBytes = new TextEncoder().encode(entry.body);
const leafHex = rfc6962LeafHash(leafBytes);
log.info({ leafHex, logIndex: entry.logIndex }, "rekor entry hashed");
const proof = entry.verification?.inclusionProof;
if (proof) {
const { valid } = verifyRfc6962InclusionProof({
leafBytes,
hashes: proof.hashes,
logIndex: entry.logIndex,
treeSize: proof.treeSize,
expectedRootHex: proof.rootHash,
});
if (!valid) throw new Error("inclusion failed");
}
```
## API Reference
- `verifyRfc6962InclusionProof(args): { valid, computedRootHex }` — returns
whether the computed root matches. Throws `RekorInclusionError` when
`logIndex >= treeSize` or `logIndex < 0`.
- `rfc6962LeafHash(body: Uint8Array): string` — lowercase hex SHA-256 with
the `0x00` leaf prefix.
## Implementation Notes
The carry-up branch (odd-count level) handles trees where the last node at a
given level has no sibling — rather than duplicating, RFC 6962 propagates
the node up unchanged. Rekor's server-side proof generator will either
produce a shorter path for such leaves or include a duplicate; this
implementation tolerates the former. String comparison is
case-insensitive on the expected root to match Sigstore's mixed-case hex
output.