CipherShift365.Core.Runtime
Package: CipherShift365.Core.Runtime
Target: .NET 9 / .NET 10
Role: Shared runtime — identity service, risk model, policy engine, CBOM serialization, knowledge base interface, signer/verifier infrastructure.
Table of Contents
- What It Does
- Why It's Needed (Value Proposition)
- Installation
- How to Run / Use
- User Manual
- Developer Manual
- Code Examples
- API Reference
- Configuration Options
What It Does
CipherShift365.Core.Runtime is the foundational library consumed by every other component in the CipherShift365 platform. It provides:
Identity Service (
IIdentityService) — Computes deterministicLogicalIdandLocationalIdfor every cryptographic usage. The same algorithm with the same parameters always produces the sameLogicalId, enabling stable comparison, deduplication, and baseline tracking.Risk Model (
IRiskModel) — Classifies cryptographic algorithms into four quantum-resistance tiers:QuantumBroken,QuantumVulnerable,Mitigable, andQuantumSafe. Includes fallback heuristics when the knowledge base has no entry for an algorithm.Policy Engine (
IPolicyEngine) — Evaluates findings against a policy mode (AbsoluteorBaselineAware). Produces aPolicyVerdictwith a compliance boolean, violation list, system score, and human-readable summary.CBOM Serializer (
ICbomSerializer) — Reads and writes CycloneDX 1.6 Cryptography BOMs (CBOMs) in both JSON and XML. Uses deterministic JSON serialization for reproducible, signable output. TheCbomrecord models the full CycloneDX object graph: metadata, components, services, dependencies, compositions, vulnerabilities, properties, and signature.Knowledge Base Interface (
IKnowledgeBase) — Defines the contract for algorithm lookups. The runtime ships withInMemoryKnowledgeBase(for unit testing and simple scenarios) and supports signed KB packages viaKbPackageFormat(AES-256-GCM encryption + HMAC-SHA256 signing).Signer / Verifier (
ISigner,IVerifier) — Contracts for artifact signing and verification.HmacSignerandHmacVerifierprovide HMAC-SHA256 implementations for offline signature generation and validation.Core Types — Defines the shared domain model:
Finding,CryptoParameters,AssetLocation,RiskLevel,Confidence,CryptoRole,PolicyVerdict,Baseline,SignedArtifact,ArtifactHeader,CbomComponent,CryptoProperties,Recommendation,KbEntry,KbVersion, and more.
Why It's Needed
Organizations face a hard deadline: before cryptographically relevant quantum computers (CRQCs) arrive, every asymmetric algorithm in their estate — RSA, ECDSA, ECDH, DSA — must be replaced. CNSA 2.0 mandates migration timelines starting in 2027. The problem breaks down into three questions:
- What crypto do we have? (discovery — handled by
Core.Analysis) - How bad is it? (risk classification — handled by
Core.Runtime) - What do we do about it? (recommendation, policy, plan — handled by
Core.Runtime)
Core.Runtime provides the shared vocabulary and engine for answering questions 2 and 3. Without it, each tool in the platform would duplicate classification logic, producing inconsistent results. The identity model enables every finding to be tracked across time and tools, making incremental scans, baseline comparisons, and CI/CD policy gates possible.
Value Showcase
| Capability | Value |
|---|---|
| Deterministic identity | Finds the same crypto usage in every scan; enables diffs and baselines |
| Quantum risk tiers | Maps every algorithm to an actionable category, with scoring 0–1 |
| Policy with bootstrapping | Start in Absolute mode, later switch to BaselineAware without changing tooling |
| CBOM standard | Output conforms to CycloneDX 1.6, interoperable with SBOM tools |
| Signed knowledge bases | Tamper-evident KB distribution with AES-256-GCM + HMAC-SHA256 |
| Pluggable signers | Swap signer implementations without changing consumers |
Installation
Add the NuGet package reference:
<PackageReference Include="CipherShift365.Core.Runtime" Version="1.0.0" />
Or via CLI:
dotnet add package CipherShift365.Core.Runtime
No additional runtime dependencies beyond System.Text.Json and System.Security.Cryptography.
How to Run / Use
This library is consumed as a dependency — it is not a standalone executable. Typical usage in application startup:
using CipherShift365.Core.Runtime;
// 1. Create knowledge base
var kb = new InMemoryKnowledgeBase(
new KbVersion(1, 0, 0),
new[]
{
new KbEntry("RSA", CryptoRole.Signature, RiskLevel.QuantumBroken,
Recommendations: new[] { new Recommendation("ML-DSA-65") }),
new KbEntry("ECDSA", CryptoRole.Signature, RiskLevel.QuantumBroken,
Recommendations: new[] { new Recommendation("ML-DSA-65") }),
new KbEntry("AES", CryptoRole.Symmetric, RiskLevel.QuantumVulnerable,
Recommendations: new[] { new Recommendation("AES-256-GCM") }),
});
// 2. Wire up services
var identity = new IdentityService();
var riskModel = new RiskModel(kb);
var policyEngine = new PolicyEngine(riskModel);
// 3. Use
var logicalId = identity.ComputeLogicalId(
CryptoRole.Signature, "RSA", new CryptoParameters(KeySize: 2048));
var risk = riskModel.Classify(
CryptoRole.Signature, "RSA", new CryptoParameters(KeySize: 2048), kb.Version);
// risk == RiskLevel.QuantumBroken
User Manual
Risk Classification
The RiskModel classifies algorithms into four ordered tiers (worst to best):
QuantumBroken < QuantumVulnerable < Mitigable < QuantumSafe
QuantumBroken: Algorithms mathematically broken by quantum computers — RSA, ECDSA, ECDH, DSA, DH, ElGamal. Any RSA key below 15,360 bits is classified broken. Score: 1.0.
QuantumVulnerable: Algorithms that survive with doubled key sizes but are not inherently quantum-safe — AES-128, AES with keys below 256 bits, SHA-256. Score: 0.7.
Mitigable: Algorithms that can be mitigated through hybrid constructions — explicitly hybrid-labeled algorithms. Score: 0.3.
QuantumSafe: Post-quantum algorithms — ML-KEM, ML-DSA, SLH-DSA, AES-256, SHA-512, SHA3-512. Score: 0.0.
The ScoreFinding, ScoreComponent, and ScoreSystem methods produce normalized scores between 0 (fully safe) and 1 (fully broken).
Policy Engine Behavior
Absolute mode: Every finding must be QuantumSafe. All non-safe findings are violations.
BaselineAware mode: Compares current findings against a previously accepted Baseline. A finding is a violation if:
- Its
LogicalIdis not in the baseline (new algorithm usage) - Its
LocationalIddiffers from baseline (new location of known algo) - Its
RiskLevelis worse than the baseline - Its
Confidenceis higher than the baseline (more certain of a bad finding)
Bootstrap behavior: When BaselineAware is requested but no baseline is provided, the engine operates in Absolute mode and includes a warning in PolicyVerdict.Summary.
Identity Model
The identity service produces two IDs:
- LogicalId:
"{CryptoRole}|{algorithm}|{parameters-normalized}"— identifies the cryptographic pattern, independent of location. - LocationalId:
"{LogicalId}|{location-normalized}"— identifies a specific occurrence.
These IDs are the backbone of deduplication, baseline tracking, and incremental diffing. The normalization is deterministic and documented — user code can reproduce IDs independently.
CBOM Output
The CbomSerializer writes CycloneDX 1.6 JSON with deterministic key ordering for reproducible output. Each finding becomes a cryptographic-asset component with:
cryptoPropertiescontaining algorithm, parameters, and NIST quantum security levelpropertieswith CipherShift365 custom annotations (ciphershift365:quantumRisk,ciphershift365:confidence,ciphershift365:pqcTarget, etc.)evidencewith detection technique and location
Signed Knowledge Base Packages
KB packages use a binary format with the magic bytes CSKB, followed by versioned JSON metadata, AES-256-GCM encrypted content, and an HMAC-SHA256 signature. The KbPackageFormat.Build and KbPackageFormat.Load methods handle encryption sign/verify in a single call.
Developer Manual
Architecture
CipherShift365.Core.Runtime
├── Contracts/ # Interfaces: IIdentityService, IRiskModel, IPolicyEngine,
│ # ICbomSerializer, IKnowledgeBase, ISigner, IVerifier
├── Services/ # Implementations: IdentityService, RiskModel, PolicyEngine,
│ # CbomSerializer, HmacSigner, HmacVerifier, InMemoryKnowledgeBase
│ # DeterministicCbomJsonWriter, DeterministicCbomXmlWriter, DeterministicCbomXmlReader
├── Cbom/ # CycloneDX data model: Cbom, CbomComponent, CbomMetadata,
│ # CryptoProperties, AlgorithmProperties, CipherShiftAnnotations, etc.
├── Kb/ # Knowledge base package format, builder, loader
├── Types/ # Domain types: Finding, CryptoParameters, RiskLevel, etc.
└── CbomSerializerContext.cs # Source-generated JSON serialization context
Dependency Injection
All contracts should be registered via DI. A typical registration:
services.AddSingleton<IKnowledgeBase>(sp =>
new InMemoryKnowledgeBase(new KbVersion(1, 0, 0), LoadEntries()));
services.AddSingleton<IIdentityService, IdentityService>();
services.AddSingleton<IRiskModel, RiskModel>();
services.AddSingleton<IPolicyEngine, PolicyEngine>();
services.AddSingleton<ICbomSerializer, CbomSerializer>();
Extension Points
Custom
IKnowledgeBase: Implement the interface to load from a database, HTTP endpoint, or file system. TheInMemoryKnowledgeBaseis suitable for small KBs only.Custom
ISigner/IVerifier: Implement for asymmetric signing (e.g., ML-DSA via .NET 10 APIs). The Vault SDK provides richer implementations.Custom
IRiskModel: Override the default risk model to apply organization-specific rules.Custom
IPolicyEngine: Add policy modes (e.g., "RegulatoryCompliance") that check against specific standards.
Signed KB Package Format
[Magic: 4 bytes (0x43534B42)]
[Version: 1 byte]
[HeaderLength: 4 bytes (LE)]
[HeaderJSON: {headerLength} bytes]
[Nonce: 12 bytes]
[Tag: 16 bytes (AES-256-GCM)]
[Ciphertext: variable (AES-256-GCM encrypted KbPackageContent JSON)]
[HMAC: 32 bytes (HMAC-SHA256 over all preceding bytes)]
The KbBuildOutput type wraps the serialized bytes and provides a Metadata property for file naming and distribution tracking.
Important Design Decisions
Deterministic serialization:
DeterministicCbomJsonWritersorts keys alphabetically and uses consistent numeric formatting. This ensures two scans of the same project produce identical CBOMs (modulo timestamps), enabling reliable signature validation and diffing.Confidence is separate from risk: The risk model never folds confidence into the risk score. Callers must read
Finding.Confidenceseparately. The policy engine uses confidence as a worsening signal in baseline mode.No external dependencies: The runtime library has no dependency on external HTTP, database, or cloud services. It is pure C# with BCL types only.
Code Examples
Scoring a Finding
var finding = new Finding(
new LogicalId("Signature|RSA|KeySize=2048"),
new LocationalId("Signature|RSA|KeySize=2048|file=Program.cs;ln=42"),
CryptoRole.Signature, "RSA",
new CryptoParameters(KeySize: 2048),
RiskLevel.QuantumBroken,
Confidence.High,
"RSA.Create() for JWT signing");
double score = riskModel.ScoreFinding(finding);
// score == 1.0
Scoring a System
var findings = new[]
{
new Finding(/* RSA — broken */),
new Finding(/* AES-128 — vulnerable */),
new Finding(/* ML-DSA-65 — safe */),
};
double systemScore = riskModel.ScoreSystem(findings);
// ~0.57 (average of component scores)
Policy Evaluation (Absolute Mode)
var verdict = policyEngine.Evaluate(findings, PolicyMode.Absolute, baseline: null);
Console.WriteLine($"Compliant: {verdict.IsCompliant}");
Console.WriteLine($"Score: {verdict.SystemScore:F2}");
Console.WriteLine(verdict.Summary);
// "3 violation(s) found. 1 broken, 1 vulnerable."
Policy Evaluation (BaselineAware Mode)
var baseline = new Baseline(kb.Version, DateTimeOffset.UtcNow,
previousFindings, "Q1 2026 accepted risks");
var verdict = policyEngine.Evaluate(currentFindings, PolicyMode.BaselineAware, baseline);
// Only new or worsened findings appear in Violations
Serializing a CBOM
var cbom = Cbom.Empty();
var serializer = new CbomSerializer();
// Write to stream
using var stream = new MemoryStream();
serializer.Write(cbom, stream);
// Read from stream
stream.Position = 0;
var deserialized = serializer.Read(stream);
// String round-trip
string json = CbomSerializer.SerializeToString(cbom);
var roundTripped = CbomSerializer.DeserializeFromString(json);
Signing Content with HMAC
var key = RandomNumberGenerator.GetBytes(32);
var signer = new HmacSigner(key);
var verifier = new HmacVerifier(key);
var content = Encoding.UTF8.GetBytes("Hello, PQC");
var signed = await signer.SignAsync(content);
var result = await verifier.VerifyAsync(signed);
Console.WriteLine(result.Outcome); // VerificationOutcome.Valid
Identity Computation
var identity = new IdentityService();
// Same algorithm + params => same LogicalId
var id1 = identity.ComputeLogicalId(
CryptoRole.Signature, "RSA", new CryptoParameters(KeySize: 2048));
var id2 = identity.ComputeLogicalId(
CryptoRole.Signature, "RSA", new CryptoParameters(KeySize: 2048));
Console.WriteLine(id1 == id2); // True
// Different locations => different LocationalIds
var loc1 = identity.ComputeLocationalId(id1,
new AssetLocation(FilePath: "AuthService.cs", LineNumber: 42));
var loc2 = identity.ComputeLocationalId(id1,
new AssetLocation(FilePath: "TokenService.cs", LineNumber: 100));
Console.WriteLine(loc1 == loc2); // False
Building a Signed KB Package
var content = new KbPackageContent(
new KbPackageMetadata(new KbVersion(1, 0, 0), DateTimeOffset.UtcNow, "NIST PQC Initial"),
new[] { new KbEntry("ML-KEM-768", CryptoRole.Kem, RiskLevel.QuantumSafe) });
var encryptionKey = RandomNumberGenerator.GetBytes(32); // AES-256
var signingKey = RandomNumberGenerator.GetBytes(32); // HMAC-SHA256
byte[] package = KbPackageFormat.Build(content, encryptionKey, signingKey);
var result = KbPackageFormat.Load(package, encryptionKey, signingKey);
// result.Outcome == KbLoadOutcome.Valid
API Reference
IIdentityService
| Method | Description |
|---|---|
ComputeLogicalId(CryptoRole, string, CryptoParameters) → LogicalId |
Normalizes and hashes the crypto usage into a stable identifier |
ComputeLocationalId(LogicalId, AssetLocation) → LocationalId |
Combines logical identity with file/assembly location |
IRiskModel
| Method | Description |
|---|---|
Classify(CryptoRole, string, CryptoParameters, KbVersion) → RiskLevel |
Determines quantum risk tier |
ScoreFinding(Finding) → double |
0.0 (safe) to 1.0 (broken) |
ScoreComponent(IReadOnlyList<Finding>) → double |
Average of finding scores, capped at 1.0 |
ScoreSystem(IReadOnlyList<Finding>) → double |
Average of component scores, capped at 1.0 |
IPolicyEngine
| Method | Description |
|---|---|
Evaluate(IReadOnlyList<Finding>, PolicyMode, Baseline?) → PolicyVerdict |
Produces compliance verdict with violations list |
ICbomSerializer
| Method | Description |
|---|---|
Read(Stream) → Cbom |
Auto-detects JSON/XML and deserializes |
Write(Cbom, Stream) → void |
Writes deterministic JSON |
WriteXml(Cbom, Stream) → void |
Writes deterministic XML |
IKnowledgeBase
| Property / Method | Description |
|---|---|
Version → KbVersion |
Semver of the loaded KB |
TryGetEntry(string, out KbEntry) → bool |
Lookup by algorithm name |
Recommend(CryptoRole, string, CryptoParameters) → Recommendation |
Returns PQC target algorithm |
ISigner
| Method | Description |
|---|---|
SignAsync(ReadOnlyMemory<byte>, CancellationToken) → Task<SignedArtifact> |
Signs content |
IVerifier
| Method | Description |
|---|---|
VerifyAsync(SignedArtifact, CancellationToken) → Task<VerificationResult> |
Verifies signature |
Enums
| Enum | Values |
|---|---|
RiskLevel |
QuantumBroken, QuantumVulnerable, Mitigable, QuantumSafe |
Confidence |
Low (0), Medium (1), High (2) |
CryptoRole |
KeyExchange, Kem, Signature, Symmetric, Hash, Mac, Kdf, Rng, Other |
PolicyMode |
Absolute, BaselineAware |
CryptoMode |
Pure, Hybrid |
ValidationStatus |
NotValidated, Validated, Failed |
VerificationOutcome |
Valid, InvalidSignature, Tampered, UnsupportedVersion, UnknownSigner |
Key Types
| Type | Description |
|---|---|
Finding |
Record: LogicalId, LocationalId, Role, Algorithm, Parameters, Risk, Confidence, Description, Location |
CryptoParameters |
Record: KeySize?, Curve?, Mode?, Padding?, SecurityLevel?, ParameterSet? |
AssetLocation |
Value struct: FilePath?, AssemblyName?, LineNumber?, ProjectPath?, etc. |
PolicyVerdict |
Record: IsCompliant, Mode, Violations, SystemScore, Summary |
Baseline |
Record: KbVersion, CreatedAt, AcceptedFindings, Description |
KbEntry |
Record: Algorithm, Role, Risk, Recommendations, StandardsReferences, MigrationNotes |
KbVersion |
Semver record: Major, Minor, Patch, PreRelease; supports parsing and comparison |
Recommendation |
Record: TargetAlgorithm, Parameters?, Rationale? |
VerificationResult |
Record: Outcome, ErrorMessage?; has computed IsValid |
SignedArtifact |
Record: Header, Content, Signature |
ArtifactHeader |
Record: FormatVersion, Algorithm, Mode, SchemeId?, Timestamp, KeyId? |
CipherShift365 CBOM Annotations
All annotations are namespaced under ciphershift365::
| Property | Value |
|---|---|
ciphershift365:quantumRisk |
QuantumBroken / QuantumVulnerable / Mitigable / QuantumSafe |
ciphershift365:confidence |
High / Medium / Low |
ciphershift365:pqcTarget |
Recommended replacement algorithm |
ciphershift365:logicalId |
Stable crypto usage identity |
ciphershift365:locationalId |
Specific occurrence identity |
ciphershift365:locationFile |
Source file path |
ciphershift365:locationLine |
Line number |
ciphershift365:role |
Crypto role |
ciphershift365:kbVersion |
Knowledge base version used |
ciphershift365:runId |
Unique analysis run identifier |
ciphershift365:analysisDuration |
Scan duration in milliseconds |
Configuration Options
The Core.Runtime library itself is configuration-free — all behavior is determined by constructor-injected dependencies.
Knowledge Base Version
The KbVersion follows semver (Major.Minor.Patch[-PreRelease]). It is used to track which KB was used for a given scan. CBOMs embed the KB version in metadata. Parsing:
var version = KbVersion.Parse("1.0.0-preview");
Risk Model Tuning
The default RiskModel uses hardcoded algorithm sets. To customize:
- Override the
Classifymethod, or - Use a data-driven approach via
IKnowledgeBase.TryGetEntry— the risk model checks the KB first before applying heuristics.
Priority order: KB entry > quantum-safe set > broken heuristics > vulnerable heuristics > mitigable heuristics > default safe.
Signer Key Requirements
HmacSigner and HmacVerifier require a minimum 16-byte key. 32 bytes is recommended for HMAC-SHA256. Keys are defensively copied on construction and never exposed.
Generated for CipherShift365 Core.Runtime. Part of the CipherShift365 PQC Readiness Platform.