nip/src/nimpak/crypto_transitions.nim

563 lines
21 KiB
Nim

# SPDX-License-Identifier: LSL-1.0
# Copyright (c) 2026 Markus Maiwald
# Stewardship: Self Sovereign Society Foundation
#
# This file is part of the Nexus Sovereign Core.
# See legal/LICENSE_SOVEREIGN.md for license terms.
## Quantum-Resistant Cryptographic Transitions
##
## This module implements the algorithm migration framework for transitioning
## from current cryptographic algorithms to quantum-resistant alternatives.
## It provides backward compatibility, algorithm detection, validation, and
## upgrade procedures for all package formats.
import std/[times, tables, options, json, strutils, algorithm]
import ./types_fixed
# =============================================================================
# Algorithm Migration Framework
# =============================================================================
type
AlgorithmMigration* = object
## Specification for migrating from one algorithm to another
fromAlgorithm*: string
toAlgorithm*: string
migrationDate*: times.DateTime
mandatory*: bool
compatibility*: bool ## Whether old and new can coexist
description*: string
phaseOutDate*: times.DateTime
MigrationPlan* = object
## Complete migration plan for cryptographic algorithms
hashMigrations*: seq[AlgorithmMigration]
signatureMigrations*: seq[AlgorithmMigration]
targetDate*: times.DateTime
phaseOutDate*: times.DateTime
backwardCompatible*: bool
MigrationStatus* = enum
## Current status of algorithm migration
NotStarted, ## Migration not yet begun
InProgress, ## Migration in progress, dual support
Completed, ## Migration complete, new algorithm preferred
PhaseOut, ## Old algorithm being phased out
Deprecated ## Old algorithm deprecated, should not be used
CryptoTransition* = object
## State of cryptographic algorithm transition
currentAlgorithms*: CryptoAlgorithms
targetAlgorithms*: CryptoAlgorithms
transitionPhase*: TransitionPhase
migrationPlan*: MigrationPlan
compatibilityMode*: bool
TransitionPhase* = enum
## Phases of cryptographic algorithm transition
PreTransition, ## Before transition starts
DualSupport, ## Supporting both old and new algorithms
NewPreferred, ## New algorithms preferred, old still supported
NewOnly, ## Only new algorithms supported
PostTransition ## Transition complete
AlgorithmCompatibility* = object
## Compatibility information between algorithms
algorithm*: string
quantumResistant*: bool
supportedUntil*: times.DateTime
replacementAlgorithm*: string
migrationComplexity*: MigrationComplexity
MigrationComplexity* = enum
## Complexity level of algorithm migration
Simple, ## Drop-in replacement
Moderate, ## Requires format changes
Complex, ## Requires significant restructuring
Breaking ## Incompatible, requires full rebuild
# =============================================================================
# Quantum-Resistant Algorithm Definitions
# =============================================================================
const
## Quantum-resistant algorithm specifications
QUANTUM_RESISTANT_ALGORITHMS* = {
# Hash algorithms
"SHA3-512": AlgorithmCompatibility(
algorithm: "SHA3-512",
quantumResistant: true,
supportedUntil: dateTime(2050, mDec, 31),
replacementAlgorithm: "",
migrationComplexity: Simple
),
"BLAKE3": AlgorithmCompatibility(
algorithm: "BLAKE3",
quantumResistant: true,
supportedUntil: dateTime(2040, mDec, 31),
replacementAlgorithm: "SHA3-512",
migrationComplexity: Simple
),
# Signature algorithms
"Dilithium": AlgorithmCompatibility(
algorithm: "Dilithium",
quantumResistant: true,
supportedUntil: dateTime(2050, mDec, 31),
replacementAlgorithm: "",
migrationComplexity: Moderate
),
"SPHINCS+": AlgorithmCompatibility(
algorithm: "SPHINCS+",
quantumResistant: true,
supportedUntil: dateTime(2050, mDec, 31),
replacementAlgorithm: "",
migrationComplexity: Complex
)
}.toTable()
## Legacy algorithm migration paths
LEGACY_ALGORITHM_MIGRATIONS* = {
# Hash algorithm transitions
"BLAKE2b": AlgorithmCompatibility(
algorithm: "BLAKE2b",
quantumResistant: false,
supportedUntil: dateTime(2030, mDec, 31),
replacementAlgorithm: "BLAKE3",
migrationComplexity: Simple
),
"SHA256": AlgorithmCompatibility(
algorithm: "SHA256",
quantumResistant: false,
supportedUntil: dateTime(2028, mDec, 31),
replacementAlgorithm: "SHA3-512",
migrationComplexity: Simple
),
# Signature algorithm transitions
"Ed25519": AlgorithmCompatibility(
algorithm: "Ed25519",
quantumResistant: false,
supportedUntil: dateTime(2030, mDec, 31),
replacementAlgorithm: "Dilithium",
migrationComplexity: Moderate
),
"RSA-4096": AlgorithmCompatibility(
algorithm: "RSA-4096",
quantumResistant: false,
supportedUntil: dateTime(2028, mDec, 31),
replacementAlgorithm: "Dilithium",
migrationComplexity: Complex
)
}.toTable()
## Complete migration timeline
QUANTUM_MIGRATION_TIMELINE* = MigrationPlan(
hashMigrations: @[
AlgorithmMigration(
fromAlgorithm: "BLAKE2b",
toAlgorithm: "BLAKE3",
migrationDate: dateTime(2025, mJan, 1),
mandatory: false,
compatibility: true,
description: "Performance and quantum-resistance improvement",
phaseOutDate: dateTime(2030, mDec, 31)
),
AlgorithmMigration(
fromAlgorithm: "BLAKE3",
toAlgorithm: "SHA3-512",
migrationDate: dateTime(2030, mJan, 1),
mandatory: true,
compatibility: true,
description: "Full quantum resistance transition",
phaseOutDate: dateTime(2035, mDec, 31)
),
AlgorithmMigration(
fromAlgorithm: "SHA256",
toAlgorithm: "SHA3-512",
migrationDate: dateTime(2028, mJan, 1),
mandatory: true,
compatibility: false,
description: "Direct quantum resistance upgrade",
phaseOutDate: dateTime(2030, mDec, 31)
)
],
signatureMigrations: @[
AlgorithmMigration(
fromAlgorithm: "Ed25519",
toAlgorithm: "Dilithium",
migrationDate: dateTime(2028, mJan, 1),
mandatory: true,
compatibility: false,
description: "Quantum-resistant signature transition",
phaseOutDate: dateTime(2032, mDec, 31)
),
AlgorithmMigration(
fromAlgorithm: "RSA-4096",
toAlgorithm: "Dilithium",
migrationDate: dateTime(2026, mJan, 1),
mandatory: true,
compatibility: false,
description: "Legacy RSA to quantum-resistant transition",
phaseOutDate: dateTime(2030, mDec, 31)
)
],
targetDate: dateTime(2030, mDec, 31),
phaseOutDate: dateTime(2035, mDec, 31),
backwardCompatible: true
)
# =============================================================================
# Algorithm Detection and Validation
# =============================================================================
proc isQuantumResistant*(algorithm: string): bool =
## Check if an algorithm is quantum-resistant
algorithm in QUANTUM_RESISTANT_ALGORITHMS
proc isQuantumResistant*(algorithms: CryptoAlgorithms): bool =
## Check if cryptographic algorithms are quantum-resistant
isQuantumResistant(algorithms.hashAlgorithm) and
isQuantumResistant(algorithms.signatureAlgorithm)
proc getAlgorithmCompatibility*(algorithm: string): Option[AlgorithmCompatibility] =
## Get compatibility information for an algorithm
if algorithm in QUANTUM_RESISTANT_ALGORITHMS:
return some(QUANTUM_RESISTANT_ALGORITHMS[algorithm])
elif algorithm in LEGACY_ALGORITHM_MIGRATIONS:
return some(LEGACY_ALGORITHM_MIGRATIONS[algorithm])
else:
return none(AlgorithmCompatibility)
proc getMigrationStatus*(algorithm: string, currentDate: times.DateTime = now()): MigrationStatus =
## Get current migration status for an algorithm
let compatInfo = getAlgorithmCompatibility(algorithm)
if compatInfo.isNone:
return NotStarted
let compat = compatInfo.get()
if compat.quantumResistant:
return Completed
let timeToSupport = compat.supportedUntil - currentDate
let gracePeriod = initDuration(days = 365) # 1 year grace period
if timeToSupport > initDuration(days = 730): # 2+ years
return NotStarted
elif timeToSupport > initDuration(days = 365): # 1-2 years
return InProgress
elif timeToSupport > initDuration(days = 0): # 0-1 year
return Completed
elif timeToSupport > -gracePeriod: # Grace period
return PhaseOut
else:
return Deprecated
proc validateAlgorithmSupport*(algorithms: CryptoAlgorithms,
currentDate: times.DateTime = now()): seq[string] =
## Validate algorithm support and return warnings/errors
var issues: seq[string] = @[]
# Check hash algorithm
let hashStatus = getMigrationStatus(algorithms.hashAlgorithm, currentDate)
case hashStatus:
of Deprecated:
issues.add("CRITICAL: Hash algorithm " & algorithms.hashAlgorithm & " is deprecated")
of PhaseOut:
issues.add("WARNING: Hash algorithm " & algorithms.hashAlgorithm & " is being phased out")
of InProgress:
issues.add("INFO: Hash algorithm " & algorithms.hashAlgorithm & " migration in progress")
else:
discard
# Check signature algorithm
let sigStatus = getMigrationStatus(algorithms.signatureAlgorithm, currentDate)
case sigStatus:
of Deprecated:
issues.add("CRITICAL: Signature algorithm " & algorithms.signatureAlgorithm & " is deprecated")
of PhaseOut:
issues.add("WARNING: Signature algorithm " & algorithms.signatureAlgorithm & " is being phased out")
of InProgress:
issues.add("INFO: Signature algorithm " & algorithms.signatureAlgorithm & " migration in progress")
else:
discard
# Check version compatibility
if algorithms.version == "1.0" and isQuantumResistant(algorithms):
issues.add("INFO: Quantum-resistant algorithms should use version 2.0 or higher")
return issues
# =============================================================================
# Algorithm Migration and Upgrade Procedures
# =============================================================================
proc getRecommendedAlgorithms*(currentAlgorithms: CryptoAlgorithms,
targetDate: times.DateTime = now()): CryptoAlgorithms =
## Get recommended algorithms for the target date
var recommended = currentAlgorithms
# Find appropriate hash algorithm migration
for migration in QUANTUM_MIGRATION_TIMELINE.hashMigrations:
if migration.fromAlgorithm == currentAlgorithms.hashAlgorithm and
targetDate >= migration.migrationDate:
recommended.hashAlgorithm = migration.toAlgorithm
break
# Find appropriate signature algorithm migration
for migration in QUANTUM_MIGRATION_TIMELINE.signatureMigrations:
if migration.fromAlgorithm == currentAlgorithms.signatureAlgorithm and
targetDate >= migration.migrationDate:
recommended.signatureAlgorithm = migration.toAlgorithm
break
# Update version if algorithms changed
if recommended.hashAlgorithm != currentAlgorithms.hashAlgorithm or
recommended.signatureAlgorithm != currentAlgorithms.signatureAlgorithm:
if isQuantumResistant(recommended):
recommended.version = "2.0"
else:
recommended.version = "1.5" # Intermediate version
return recommended
proc migrateToQuantumResistant*(algorithms: var CryptoAlgorithms): bool =
## Migrate algorithms to quantum-resistant alternatives
let original = algorithms
algorithms = getRecommendedAlgorithms(algorithms, dateTime(2030, mDec, 31))
return algorithms.hashAlgorithm != original.hashAlgorithm or
algorithms.signatureAlgorithm != original.signatureAlgorithm
proc createMigrationPlan*(currentAlgorithms: CryptoAlgorithms,
targetDate: times.DateTime): CryptoTransition =
## Create comprehensive migration plan for current algorithms
let targetAlgorithms = getRecommendedAlgorithms(currentAlgorithms, targetDate)
let phase = getCurrentTransitionPhase(currentAlgorithms, targetDate)
CryptoTransition(
currentAlgorithms: currentAlgorithms,
targetAlgorithms: targetAlgorithms,
transitionPhase: phase,
migrationPlan: QUANTUM_MIGRATION_TIMELINE,
compatibilityMode: currentAlgorithms.hashAlgorithm != targetAlgorithms.hashAlgorithm or
currentAlgorithms.signatureAlgorithm != targetAlgorithms.signatureAlgorithm
)
proc getCurrentTransitionPhase*(algorithms: CryptoAlgorithms,
currentDate: times.DateTime = now()): TransitionPhase =
## Determine current transition phase based on algorithms and date
if isQuantumResistant(algorithms):
return PostTransition
let hashStatus = getMigrationStatus(algorithms.hashAlgorithm, currentDate)
let sigStatus = getMigrationStatus(algorithms.signatureAlgorithm, currentDate)
# Determine overall phase based on most restrictive status
let overallStatus = if hashStatus > sigStatus: hashStatus else: sigStatus
case overallStatus:
of NotStarted:
return PreTransition
of InProgress:
return DualSupport
of Completed:
return NewPreferred
of PhaseOut:
return NewOnly
of Deprecated:
return PostTransition
# =============================================================================
# Backward Compatibility Management
# =============================================================================
type
CompatibilityLayer* = object
## Compatibility layer for mixed-algorithm environments
primaryAlgorithms*: CryptoAlgorithms
fallbackAlgorithms*: seq[CryptoAlgorithms]
verificationStrategy*: VerificationStrategy
migrationDeadline*: times.DateTime
VerificationStrategy* = enum
## Strategy for verifying signatures in mixed environments
PrimaryOnly, ## Only use primary algorithms
TryPrimaryThenFallback, ## Try primary, fall back to legacy
RequireBoth, ## Require both primary and fallback verification
LegacyOnly ## Only use legacy algorithms (deprecated)
proc createCompatibilityLayer*(primaryAlgorithms: CryptoAlgorithms,
fallbackAlgorithms: seq[CryptoAlgorithms]): CompatibilityLayer =
## Create compatibility layer for mixed-algorithm environments
let migrationDeadline =
if primaryAlgorithms.hashAlgorithm in LEGACY_ALGORITHM_MIGRATIONS:
LEGACY_ALGORITHM_MIGRATIONS[primaryAlgorithms.hashAlgorithm].supportedUntil
else:
dateTime(2030, mDec, 31)
CompatibilityLayer(
primaryAlgorithms: primaryAlgorithms,
fallbackAlgorithms: fallbackAlgorithms,
verificationStrategy: TryPrimaryThenFallback,
migrationDeadline: migrationDeadline
)
proc validateCompatibilityLayer*(layer: CompatibilityLayer): seq[string] =
## Validate compatibility layer configuration
var warnings: seq[string] = @[]
# Check if primary algorithms are quantum-resistant
if not isQuantumResistant(layer.primaryAlgorithms):
warnings.add("Primary algorithms are not quantum-resistant")
# Check for deprecated fallback algorithms
for fallback in layer.fallbackAlgorithms:
let hashStatus = getMigrationStatus(fallback.hashAlgorithm)
let sigStatus = getMigrationStatus(fallback.signatureAlgorithm)
if hashStatus == Deprecated:
warnings.add("Fallback hash algorithm " & fallback.hashAlgorithm & " is deprecated")
if sigStatus == Deprecated:
warnings.add("Fallback signature algorithm " & fallback.signatureAlgorithm & " is deprecated")
# Check migration deadline
if layer.migrationDeadline < now():
warnings.add("Migration deadline has passed")
return warnings
# =============================================================================
# Package Format Algorithm Upgrade Procedures
# =============================================================================
proc upgradePackageAlgorithms*(packageFormat: PackageFormat,
currentAlgorithms: CryptoAlgorithms): Result[CryptoAlgorithms, string] =
## Upgrade algorithms for a specific package format
try:
var upgraded = currentAlgorithms
let recommended = getRecommendedAlgorithms(currentAlgorithms)
case packageFormat:
of NprRecipe:
# NPR recipes prefer BLAKE2b for compatibility, but can use quantum-resistant
if not isQuantumResistant(upgraded):
upgraded.hashAlgorithm = "BLAKE3"
upgraded.signatureAlgorithm = "Dilithium"
upgraded.version = "2.0"
of NpkBinary:
# NPK packages prefer BLAKE3/Dilithium for security
upgraded = recommended
of NcaChunk:
# NCA chunks use BLAKE3 for Merkle trees
upgraded.hashAlgorithm = "BLAKE3"
if not isQuantumResistant(upgraded.signatureAlgorithm):
upgraded.signatureAlgorithm = "Dilithium"
upgraded.version = "2.0"
of NssSnapshot:
# Snapshots need maximum security
upgraded = recommended
of NofOverlay:
# Overlays prefer compatibility but support quantum-resistant
if getMigrationStatus(upgraded.hashAlgorithm) in [PhaseOut, Deprecated]:
upgraded = recommended
return ok[CryptoAlgorithms, string](upgraded)
except Exception as e:
return err[CryptoAlgorithms, string]("Failed to upgrade algorithms: " & e.msg)
# =============================================================================
# Algorithm Transition Reporting
# =============================================================================
proc createTransitionReport*(packages: seq[CryptoAlgorithms]): JsonNode =
## Create comprehensive transition report
var algorithmCounts: Table[string, int] = initTable[string, int]()
var statusCounts: Table[MigrationStatus, int] = initTable[MigrationStatus, int]()
var quantumReadyCount = 0
for algorithms in packages:
let algoKey = algorithms.hashAlgorithm & "/" & algorithms.signatureAlgorithm
algorithmCounts[algoKey] = algorithmCounts.getOrDefault(algoKey, 0) + 1
let hashStatus = getMigrationStatus(algorithms.hashAlgorithm)
let sigStatus = getMigrationStatus(algorithms.signatureAlgorithm)
let overallStatus = if hashStatus > sigStatus: hashStatus else: sigStatus
statusCounts[overallStatus] = statusCounts.getOrDefault(overallStatus, 0) + 1
if isQuantumResistant(algorithms):
quantumReadyCount += 1
let totalPackages = packages.len
let quantumReadyPercent = if totalPackages > 0: (quantumReadyCount * 100) div totalPackages else: 0
%*{
"summary": {
"total_packages": totalPackages,
"quantum_ready": quantumReadyCount,
"quantum_ready_percent": quantumReadyPercent,
"migration_deadline": $QUANTUM_MIGRATION_TIMELINE.targetDate
},
"algorithm_usage": algorithmCounts,
"migration_status": statusCounts,
"recommendations": [
if quantumReadyPercent < 50: "Prioritize quantum-resistant algorithm adoption" else: "",
if statusCounts.getOrDefault(Deprecated, 0) > 0: "Immediately upgrade deprecated algorithms" else: "",
if statusCounts.getOrDefault(PhaseOut, 0) > 0: "Plan migration for algorithms in phase-out" else: "",
"Test quantum-resistant algorithms in development environment",
"Implement gradual migration to avoid compatibility issues"
].filterIt(it.len > 0),
"generated": $now()
}
# =============================================================================
# Utility Functions
# =============================================================================
proc getDefaultQuantumAlgorithms*(): CryptoAlgorithms =
## Get default quantum-resistant algorithms
CryptoAlgorithms(
hashAlgorithm: "SHA3-512",
signatureAlgorithm: "Dilithium",
version: "2.0"
)
proc getTransitionTimelineForAlgorithm*(algorithm: string): Option[AlgorithmMigration] =
## Get migration timeline for a specific algorithm
for migration in QUANTUM_MIGRATION_TIMELINE.hashMigrations:
if migration.fromAlgorithm == algorithm:
return some(migration)
for migration in QUANTUM_MIGRATION_TIMELINE.signatureMigrations:
if migration.fromAlgorithm == algorithm:
return some(migration)
return none(AlgorithmMigration)
proc estimateMigrationEffort*(currentAlgorithms: CryptoAlgorithms,
targetAlgorithms: CryptoAlgorithms): MigrationComplexity =
## Estimate effort required for algorithm migration
if currentAlgorithms.hashAlgorithm == targetAlgorithms.hashAlgorithm and
currentAlgorithms.signatureAlgorithm == targetAlgorithms.signatureAlgorithm:
return Simple
let hashCompat = getAlgorithmCompatibility(currentAlgorithms.hashAlgorithm)
let sigCompat = getAlgorithmCompatibility(currentAlgorithms.signatureAlgorithm)
var maxComplexity = Simple
if hashCompat.isSome and hashCompat.get().migrationComplexity > maxComplexity:
maxComplexity = hashCompat.get().migrationComplexity
if sigCompat.isSome and sigCompat.get().migrationComplexity > maxComplexity:
maxComplexity = sigCompat.get().migrationComplexity
return maxComplexity