mirror of
https://github.com/syntrex-lab/gomcp.git
synced 2026-04-25 20:36:21 +02:00
204 lines
5.9 KiB
Go
204 lines
5.9 KiB
Go
// Copyright 2026 Syntrex Lab. All rights reserved.
|
|
// Use of this source code is governed by an Apache-2.0 license
|
|
// that can be found in the LICENSE file.
|
|
|
|
// Package pqcrypto implements SEC-013 (Homomorphic Encryption research)
|
|
// and SEC-014 (Post-Quantum Signatures).
|
|
//
|
|
// SEC-013: Provides an interface for future lattice-based HE integration
|
|
// (CKKS/BFV schemes) to enable correlation on encrypted events.
|
|
//
|
|
// SEC-014: Implements CRYSTALS-Dilithium-like post-quantum signatures
|
|
// using a hybrid classical+PQ approach for Decision Logger chain.
|
|
//
|
|
// Current state: Research stubs with interface definitions.
|
|
// Production: requires official NIST PQC library bindings.
|
|
package pqcrypto
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"log/slog"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// --- SEC-014: Post-Quantum Signatures ---
|
|
|
|
// SignatureScheme defines the signature algorithm.
|
|
type SignatureScheme string
|
|
|
|
const (
|
|
SchemeClassical SignatureScheme = "ed25519"
|
|
SchemeHybrid SignatureScheme = "hybrid-ed25519-dilithium"
|
|
SchemeDilithium SignatureScheme = "dilithium3" // CRYSTALS-Dilithium Level 3
|
|
)
|
|
|
|
// HybridSignature combines classical Ed25519 + post-quantum signature.
|
|
type HybridSignature struct {
|
|
ClassicalSig string `json:"classical_sig"` // Ed25519
|
|
PQSig string `json:"pq_sig"` // Dilithium (simulated)
|
|
Scheme SignatureScheme `json:"scheme"`
|
|
Hash string `json:"hash"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
}
|
|
|
|
// HybridSigner provides quantum-resistant signing with classical fallback.
|
|
type HybridSigner struct {
|
|
mu sync.RWMutex
|
|
scheme SignatureScheme
|
|
classicalPub ed25519.PublicKey
|
|
classicalPriv ed25519.PrivateKey
|
|
logger *slog.Logger
|
|
stats SignerStats
|
|
}
|
|
|
|
// SignerStats tracks signing metrics.
|
|
type SignerStats struct {
|
|
mu sync.Mutex
|
|
TotalSigns int64 `json:"total_signs"`
|
|
TotalVerifies int64 `json:"total_verifies"`
|
|
Scheme SignatureScheme `json:"scheme"`
|
|
StartedAt time.Time `json:"started_at"`
|
|
}
|
|
|
|
// NewHybridSigner creates a new post-quantum hybrid signer.
|
|
func NewHybridSigner(scheme SignatureScheme) (*HybridSigner, error) {
|
|
pub, priv, err := ed25519.GenerateKey(nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("pqcrypto: generate ed25519 key: %w", err)
|
|
}
|
|
|
|
signer := &HybridSigner{
|
|
scheme: scheme,
|
|
classicalPub: pub,
|
|
classicalPriv: priv,
|
|
logger: slog.Default().With("component", "sec-014-pqcrypto"),
|
|
stats: SignerStats{
|
|
Scheme: scheme,
|
|
StartedAt: time.Now(),
|
|
},
|
|
}
|
|
|
|
signer.logger.Info("hybrid signer initialized",
|
|
"scheme", scheme,
|
|
"classical", "ed25519",
|
|
)
|
|
|
|
return signer, nil
|
|
}
|
|
|
|
// Sign creates a hybrid (classical + PQ) signature.
|
|
func (hs *HybridSigner) Sign(data []byte) (*HybridSignature, error) {
|
|
hs.stats.mu.Lock()
|
|
hs.stats.TotalSigns++
|
|
hs.stats.mu.Unlock()
|
|
|
|
hash := sha256.Sum256(data)
|
|
hashHex := hex.EncodeToString(hash[:])
|
|
|
|
// Classical Ed25519 signature.
|
|
classicalSig := ed25519.Sign(hs.classicalPriv, hash[:])
|
|
|
|
// Post-quantum signature (simulated — real impl needs CRYSTALS-Dilithium).
|
|
pqSig := simulateDilithiumSign(hash[:])
|
|
|
|
return &HybridSignature{
|
|
ClassicalSig: hex.EncodeToString(classicalSig),
|
|
PQSig: pqSig,
|
|
Scheme: hs.scheme,
|
|
Hash: hashHex,
|
|
Timestamp: time.Now(),
|
|
}, nil
|
|
}
|
|
|
|
// Verify checks both classical and PQ signatures.
|
|
func (hs *HybridSigner) Verify(data []byte, sig *HybridSignature) bool {
|
|
hs.stats.mu.Lock()
|
|
hs.stats.TotalVerifies++
|
|
hs.stats.mu.Unlock()
|
|
|
|
hash := sha256.Sum256(data)
|
|
|
|
// Verify classical signature.
|
|
classicalSigBytes, err := hex.DecodeString(sig.ClassicalSig)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
if !ed25519.Verify(hs.classicalPub, hash[:], classicalSigBytes) {
|
|
return false
|
|
}
|
|
|
|
// Verify PQ signature (simulated).
|
|
if !simulateDilithiumVerify(hash[:], sig.PQSig) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// PublicKeyHex returns the classical public key.
|
|
func (hs *HybridSigner) PublicKeyHex() string {
|
|
return hex.EncodeToString(hs.classicalPub)
|
|
}
|
|
|
|
// Stats returns signer metrics.
|
|
func (hs *HybridSigner) Stats() SignerStats {
|
|
hs.stats.mu.Lock()
|
|
defer hs.stats.mu.Unlock()
|
|
return SignerStats{
|
|
TotalSigns: hs.stats.TotalSigns,
|
|
TotalVerifies: hs.stats.TotalVerifies,
|
|
Scheme: hs.stats.Scheme,
|
|
StartedAt: hs.stats.StartedAt,
|
|
}
|
|
}
|
|
|
|
// --- SEC-013: Homomorphic Encryption (Research Interface) ---
|
|
|
|
// HEScheme defines the homomorphic encryption scheme.
|
|
type HEScheme string
|
|
|
|
const (
|
|
HE_CKKS HEScheme = "CKKS" // Approximate arithmetic (ML-friendly)
|
|
HE_BFV HEScheme = "BFV" // Exact integer arithmetic
|
|
)
|
|
|
|
// EncryptedEvent represents a homomorphically encrypted SOC event.
|
|
type EncryptedEvent struct {
|
|
CiphertextID string `json:"ciphertext_id"`
|
|
Scheme HEScheme `json:"scheme"`
|
|
FieldCount int `json:"field_count"`
|
|
Created time.Time `json:"created"`
|
|
}
|
|
|
|
// HEEngine defines the interface for homomorphic encryption operations.
|
|
// This is a research interface — real implementation requires a lattice-based
|
|
// HE library (e.g., Microsoft SEAL, OpenFHE, or Lattigo for Go).
|
|
type HEEngine interface {
|
|
// Encrypt encrypts event fields for correlation without decryption.
|
|
Encrypt(fields map[string]float64) (*EncryptedEvent, error)
|
|
|
|
// CorrelateEncrypted runs correlation rules on encrypted events.
|
|
CorrelateEncrypted(events []*EncryptedEvent) (float64, error)
|
|
|
|
// Decrypt recovers plaintext (requires private key).
|
|
Decrypt(event *EncryptedEvent) (map[string]float64, error)
|
|
}
|
|
|
|
// --- Simulated PQ functions ---
|
|
|
|
func simulateDilithiumSign(hash []byte) string {
|
|
// Simulated Dilithium signature: SHA-256 of hash with prefix.
|
|
// In production: use circl or pqcrypto-go for real Dilithium.
|
|
prefixed := append([]byte("DILITHIUM3-SIM:"), hash...)
|
|
sig := sha256.Sum256(prefixed)
|
|
return hex.EncodeToString(sig[:])
|
|
}
|
|
|
|
func simulateDilithiumVerify(hash []byte, sigHex string) bool {
|
|
expected := simulateDilithiumSign(hash)
|
|
return expected == sigHex
|
|
}
|