feat(rate-limiting): Implement core rate limiting functionality with configuration, decision-making, metrics, middleware, and service registration
- Add RateLimitConfig for configuration management with YAML binding support. - Introduce RateLimitDecision to encapsulate the result of rate limit checks. - Implement RateLimitMetrics for OpenTelemetry metrics tracking. - Create RateLimitMiddleware for enforcing rate limits on incoming requests. - Develop RateLimitService to orchestrate instance and environment rate limit checks. - Add RateLimitServiceCollectionExtensions for dependency injection registration.
This commit is contained in:
265
bench/proof-chain/Benchmarks/VerificationPipelineBenchmarks.cs
Normal file
265
bench/proof-chain/Benchmarks/VerificationPipelineBenchmarks.cs
Normal file
@@ -0,0 +1,265 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// 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;
|
||||
|
||||
/// <summary>
|
||||
/// Benchmarks for verification pipeline operations.
|
||||
/// Target: Full verification < 50ms typical.
|
||||
/// </summary>
|
||||
[MemoryDiagnoser]
|
||||
[SimpleJob(warmupCount: 3, iterationCount: 10)]
|
||||
public class VerificationPipelineBenchmarks
|
||||
{
|
||||
private TestProofBundle _bundle = null!;
|
||||
private byte[] _dsseEnvelope = null!;
|
||||
private List<byte[]> _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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DSSE signature verification (crypto operation).
|
||||
/// Target: < 5ms per envelope.
|
||||
/// </summary>
|
||||
[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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ID recomputation verification.
|
||||
/// Target: < 2ms per bundle.
|
||||
/// </summary>
|
||||
[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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merkle proof verification.
|
||||
/// Target: < 1ms per proof.
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rekor inclusion proof verification (simulated).
|
||||
/// Target: < 10ms (cached STH).
|
||||
/// </summary>
|
||||
[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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trust anchor key lookup.
|
||||
/// Target: < 500μs.
|
||||
/// </summary>
|
||||
[Benchmark]
|
||||
public bool VerifyKeyTrust()
|
||||
{
|
||||
// Simulate trust anchor lookup
|
||||
var trustedKeys = new HashSet<string> { "test-key-1", "test-key-2", "test-key-3" };
|
||||
|
||||
foreach (var envelope in _bundle.Envelopes)
|
||||
{
|
||||
if (!trustedKeys.Contains(envelope.KeyId))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Full verification pipeline.
|
||||
/// Target: < 50ms typical.
|
||||
/// </summary>
|
||||
[Benchmark]
|
||||
public VerificationResult FullVerification()
|
||||
{
|
||||
var steps = new List<StepResult>();
|
||||
|
||||
// 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<TestStatement> Statements { get; init; }
|
||||
public required List<TestEnvelope> Envelopes { get; init; }
|
||||
public required byte[] MerkleRoot { get; init; }
|
||||
public required long LogIndex { get; init; }
|
||||
public required List<byte[]> 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<StepResult> Steps { get; init; }
|
||||
}
|
||||
|
||||
internal sealed class StepResult
|
||||
{
|
||||
public required string Step { get; init; }
|
||||
public required bool Passed { get; init; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
Reference in New Issue
Block a user