// ----------------------------------------------------------------------------- // VerificationPipelineBenchmarks.cs // Sprint: SPRINT_0501_0001_0001_proof_evidence_chain_master // Task: PROOF-MASTER-0005 // Description: Benchmarks for verification pipeline operations // ----------------------------------------------------------------------------- using System.Security.Cryptography; using System.Text; using System.Text.Json; using BenchmarkDotNet.Attributes; namespace StellaOps.Bench.ProofChain.Benchmarks; /// /// Benchmarks for verification pipeline operations. /// Target: Full verification < 50ms typical. /// [MemoryDiagnoser] [SimpleJob(warmupCount: 3, iterationCount: 10)] public class VerificationPipelineBenchmarks { private TestProofBundle _bundle = null!; private byte[] _dsseEnvelope = null!; private List _merkleProof = null!; [GlobalSetup] public void Setup() { // Create a realistic test bundle var statements = Enumerable.Range(0, 5) .Select(i => new TestStatement { StatementId = GenerateId(), PredicateType = "evidence.stella/v1", Payload = GenerateRandomBytes(1024) }) .ToList(); var envelopes = statements.Select(s => new TestEnvelope { PayloadType = "application/vnd.in-toto+json", Payload = s.Payload, Signature = GenerateRandomBytes(64), KeyId = "test-key-1" }).ToList(); _bundle = new TestProofBundle { BundleId = GenerateId(), Statements = statements, Envelopes = envelopes, MerkleRoot = GenerateRandomBytes(32), LogIndex = 12345, InclusionProof = Enumerable.Range(0, 10).Select(_ => GenerateRandomBytes(32)).ToList() }; // DSSE envelope for signature verification _dsseEnvelope = JsonSerializer.SerializeToUtf8Bytes(new { payloadType = "application/vnd.in-toto+json", payload = Convert.ToBase64String(GenerateRandomBytes(1024)), signatures = new[] { new { keyid = "key-1", sig = Convert.ToBase64String(GenerateRandomBytes(64)) } } }); // Merkle proof (typical depth ~20 for large trees) _merkleProof = Enumerable.Range(0, 20) .Select(_ => GenerateRandomBytes(32)) .ToList(); } /// /// DSSE signature verification (crypto operation). /// Target: < 5ms per envelope. /// [Benchmark] public bool VerifyDsseSignature() { // Simulate signature verification (actual crypto would use ECDsa) foreach (var envelope in _bundle.Envelopes) { var payloadHash = SHA256.HashData(envelope.Payload); // In real impl, verify signature against public key _ = SHA256.HashData(envelope.Signature); } return true; } /// /// ID recomputation verification. /// Target: < 2ms per bundle. /// [Benchmark] public bool VerifyIdRecomputation() { foreach (var statement in _bundle.Statements) { var recomputedId = $"sha256:{Convert.ToHexString(SHA256.HashData(statement.Payload)).ToLowerInvariant()}"; if (!statement.StatementId.Equals(recomputedId, StringComparison.OrdinalIgnoreCase)) { // IDs won't match in this benchmark, but we simulate the work } } return true; } /// /// Merkle proof verification. /// Target: < 1ms per proof. /// [Benchmark] public bool VerifyMerkleProof() { var leafHash = SHA256.HashData(_bundle.Statements[0].Payload); var current = leafHash; foreach (var sibling in _merkleProof) { var combined = new byte[64]; if (current[0] < sibling[0]) { current.CopyTo(combined, 0); sibling.CopyTo(combined, 32); } else { sibling.CopyTo(combined, 0); current.CopyTo(combined, 32); } current = SHA256.HashData(combined); } return current.SequenceEqual(_bundle.MerkleRoot); } /// /// Rekor inclusion proof verification (simulated). /// Target: < 10ms (cached STH). /// [Benchmark] public bool VerifyRekorInclusion() { // Simulate Rekor verification: // 1. Verify entry hash var entryHash = SHA256.HashData(JsonSerializer.SerializeToUtf8Bytes(_bundle)); // 2. Verify inclusion proof against STH return VerifyMerkleProof(); } /// /// Trust anchor key lookup. /// Target: < 500μs. /// [Benchmark] public bool VerifyKeyTrust() { // Simulate trust anchor lookup var trustedKeys = new HashSet { "test-key-1", "test-key-2", "test-key-3" }; foreach (var envelope in _bundle.Envelopes) { if (!trustedKeys.Contains(envelope.KeyId)) return false; } return true; } /// /// Full verification pipeline. /// Target: < 50ms typical. /// [Benchmark] public VerificationResult FullVerification() { var steps = new List(); // Step 1: DSSE signatures var dsseValid = VerifyDsseSignature(); steps.Add(new StepResult { Step = "dsse", Passed = dsseValid }); // Step 2: ID recomputation var idsValid = VerifyIdRecomputation(); steps.Add(new StepResult { Step = "ids", Passed = idsValid }); // Step 3: Merkle proof var merkleValid = VerifyMerkleProof(); steps.Add(new StepResult { Step = "merkle", Passed = merkleValid }); // Step 4: Rekor inclusion var rekorValid = VerifyRekorInclusion(); steps.Add(new StepResult { Step = "rekor", Passed = rekorValid }); // Step 5: Trust anchor var trustValid = VerifyKeyTrust(); steps.Add(new StepResult { Step = "trust", Passed = trustValid }); return new VerificationResult { IsValid = steps.All(s => s.Passed), Steps = steps }; } #region Helpers private static string GenerateId() { var hash = GenerateRandomBytes(32); return $"sha256:{Convert.ToHexString(hash).ToLowerInvariant()}"; } private static byte[] GenerateRandomBytes(int length) { var bytes = new byte[length]; RandomNumberGenerator.Fill(bytes); return bytes; } #endregion } #region Test Types internal sealed class TestProofBundle { public required string BundleId { get; init; } public required List Statements { get; init; } public required List Envelopes { get; init; } public required byte[] MerkleRoot { get; init; } public required long LogIndex { get; init; } public required List InclusionProof { get; init; } } internal sealed class TestStatement { public required string StatementId { get; init; } public required string PredicateType { get; init; } public required byte[] Payload { get; init; } } internal sealed class TestEnvelope { public required string PayloadType { get; init; } public required byte[] Payload { get; init; } public required byte[] Signature { get; init; } public required string KeyId { get; init; } } internal sealed class VerificationResult { public required bool IsValid { get; init; } public required List Steps { get; init; } } internal sealed class StepResult { public required string Step { get; init; } public required bool Passed { get; init; } } #endregion