diff options
| author | Gab <24553253+gabrix73@users.noreply.github.com> | 2025-02-13 15:05:44 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-13 15:05:44 +0100 |
| commit | 3069c554969aa0c129b5279192163fa6121a0607 (patch) | |
| tree | 8ef17786826cf8053d6ad36333ba044645ea02b7 | |
| parent | 2ba87f6b8d199e64a6bf3548077da4ccaf28a32f (diff) | |
| download | nofuture-go-memguard-3069c554969aa0c129b5279192163fa6121a0607.tar.gz nofuture-go-memguard-3069c554969aa0c129b5279192163fa6121a0607.tar.xz nofuture-go-memguard-3069c554969aa0c129b5279192163fa6121a0607.zip | |
Update nofuture.go
| -rw-r--r-- | nofuture.go | 525 |
1 files changed, 223 insertions, 302 deletions
diff --git a/nofuture.go b/nofuture.go index 44c02d9..46dd13b 100644 --- a/nofuture.go +++ b/nofuture.go @@ -1,347 +1,268 @@ +// nofuture.go - Post-Quantum Cryptography Core System +// Build: CGO_ENABLED=1 go build -tags="oqs,purego,harden" -trimpath -ldflags="-s -w" package main import ( - "crypto/rand" - "encoding/base64" - "fmt" - "log" - "net/http" - "runtime" - "strings" - "sync" - - "github.com/awnumar/memguard" - "github.com/gin-gonic/gin" - "golang.org/x/crypto/curve25519" - "golang.org/x/crypto/nacl/box" + "crypto/rand" + "encoding/binary" + "fmt" + "io" + "os" + "runtime" + "syscall" + "unsafe" + + "github.com/awnumar/memguard" + "github.com/open-quantum-safe/liboqs-go/oqs" + "golang.org/x/crypto/argon2" + "golang.org/x/crypto/blake2b" + "golang.org/x/sys/unix" ) -type Session struct { - PrivateKey *memguard.LockedBuffer - PublicKey *memguard.LockedBuffer - BuddyPublicKey *memguard.LockedBuffer -} +const ( + KEM_ALG = "Kyber1024-90s" + SIG_ALG = "Dilithium5-AES" + HASH_ALG = "BLAKE2b-512" + SALT_SIZE = 64 + ARGON2_TIME = 4 + ARGON2_MEMORY = 256 * 1024 + ARGON2_THREADS = 4 + ENCLAVE_KEY_LEN = 48 +) var ( - sessions sync.Map + secureEntropy = memguard.NewEnclaveRandom + guard = memguard.NewEnclave ) -const ( - nonceLength = 24 - keyLength = 32 -) +type QuantumSession struct { + sessionKey *memguard.Enclave + remotePubKey *memguard.Enclave + nonce [24]byte + handshake bool +} func init() { - memguard.CatchInterrupt() - runtime.GC() + // Hardening runtime + unix.Mlockall(unix.MCL_CURRENT | unix.MCL_FUTURE) + runtime.GOMAXPROCS(1) + memguard.CatchInterrupt() + memguard.Purge() } -func generateKeyPair() (*memguard.LockedBuffer, *memguard.LockedBuffer, error) { - privateKeyBuf := memguard.NewBuffer(keyLength) - defer privateKeyBuf.Destroy() +func deriveEnclaveKey(passphrase *memguard.Enclave, salt []byte) (*memguard.LockedBuffer, error) { + passBuf, err := passphrase.Open() + if err != nil { + return nil, err + } + defer passBuf.Destroy() + + key := argon2.IDKey(passBuf.Bytes(), salt, ARGON2_TIME, ARGON2_MEMORY, ARGON2_THREADS, ENCLAVE_KEY_LEN) + lockedKey, err := memguard.NewImmutableFromBytes(key) + if err != nil { + return nil, err + } + return lockedKey, nil +} - if _, err := rand.Read(privateKeyBuf.Bytes()); err != nil { - return nil, nil, fmt.Errorf("key generation failed: %w", err) - } +func quantumKEMKeyPair() (*memguard.LockedBuffer, *memguard.LockedBuffer, error) { + kem := oqs.KeyEncapsulation{} + if err := kem.Init(KEM_ALG, nil); err != nil { + return nil, nil, err + } + defer kem.Free() - publicKeyBuf := memguard.NewBuffer(keyLength) - defer publicKeyBuf.Destroy() + pubKey, err := kem.GenerateKeyPair() + if err != nil { + return nil, nil, err + } - publicKey, err := curve25519.X25519(privateKeyBuf.Bytes(), curve25519.Basepoint) - if err != nil { - return nil, nil, fmt.Errorf("public key derivation failed: %w", err) - } + secKey := kem.ExportSecretKey() - privateKeyLocked := memguard.NewBuffer(keyLength) - publicKeyLocked := memguard.NewBuffer(keyLength) + lockedPub, err := memguard.NewImmutableFromBytes(pubKey) + if err != nil { + return nil, nil, err + } - copy(privateKeyLocked.Bytes(), privateKeyBuf.Bytes()) - copy(publicKeyLocked.Bytes(), publicKey) + lockedSec, err := memguard.NewImmutableFromBytes(secKey) + if err != nil { + lockedPub.Destroy() + return nil, nil, err + } - return privateKeyLocked, publicKeyLocked, nil + return lockedPub, lockedSec, nil } -func startSession(c *gin.Context) { - c.Header("Content-Type", "application/json") - log.Printf("Starting new secure session...") - - privateKey, publicKey, err := generateKeyPair() - if err != nil { - log.Printf("Error generating key pair: %v", err) - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - return - } - - sessionIDBuf := memguard.NewBuffer(12) - if _, err := rand.Read(sessionIDBuf.Bytes()); err != nil { - log.Printf("Error generating session ID: %v", err) - c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate session ID"}) - return - } - defer sessionIDBuf.Destroy() - - sessionID := base64.RawURLEncoding.EncodeToString(sessionIDBuf.Bytes()) - - sessions.Store(sessionID, &Session{ - PrivateKey: privateKey, - PublicKey: publicKey, - BuddyPublicKey: nil, - }) - - log.Printf("Session created successfully: %s", sessionID) - - c.JSON(http.StatusOK, gin.H{ - "session_id": sessionID, - "public_key": base64.StdEncoding.EncodeToString(publicKey.Bytes()), - }) - - runtime.GC() -} +func quantumEncapsulate(pubKey *memguard.LockedBuffer) (*memguard.LockedBuffer, *memguard.LockedBuffer, error) { + kem := oqs.KeyEncapsulation{} + defer kem.Free() -func endSession(c *gin.Context) { - c.Header("Content-Type", "application/json") - var req struct { - SessionID string `json:"session_id" binding:"required"` - } - - if err := c.BindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"}) - return - } - - if sess, loaded := sessions.LoadAndDelete(req.SessionID); loaded { - session := sess.(*Session) - if session.PrivateKey != nil { - session.PrivateKey.Destroy() - } - if session.PublicKey != nil { - session.PublicKey.Destroy() - } - if session.BuddyPublicKey != nil { - session.BuddyPublicKey.Destroy() - } - } - - log.Printf("Session ended and cleaned up: %s", req.SessionID) - c.JSON(http.StatusOK, gin.H{"status": "session_ended"}) - - runtime.GC() -} + pubBytes := pubKey.Bytes() + if err := kem.Init(KEM_ALG, pubBytes); err != nil { + return nil, nil, err + } -func pairSessions(c *gin.Context) { - c.Header("Content-Type", "application/json") - var req struct { - SessionIDA string `json:"session_id_A" binding:"required"` - SessionIDB string `json:"session_id_B" binding:"required"` - } - - if err := c.BindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"}) - return - } - - sessionA, ok := sessions.Load(req.SessionIDA) - if !ok { - c.JSON(http.StatusNotFound, gin.H{"error": "session A not found"}) - return - } - - sessionB, ok := sessions.Load(req.SessionIDB) - if !ok { - c.JSON(http.StatusNotFound, gin.H{"error": "session B not found"}) - return - } - - sessA := sessionA.(*Session) - sessB := sessionB.(*Session) - - sessA.BuddyPublicKey = memguard.NewBuffer(keyLength) - sessB.BuddyPublicKey = memguard.NewBuffer(keyLength) - - copy(sessA.BuddyPublicKey.Bytes(), sessB.PublicKey.Bytes()) - copy(sessB.BuddyPublicKey.Bytes(), sessA.PublicKey.Bytes()) - - log.Printf("Sessions paired: %s with %s", req.SessionIDA, req.SessionIDB) - c.JSON(http.StatusOK, gin.H{ - "status": "paired", - "session_id_A": req.SessionIDA, - "session_id_B": req.SessionIDB, - }) - - runtime.GC() -} + ct, ss, err := kem.EncapSecretKey(rand.Reader) + if err != nil { + return nil, nil, err + } -func buddyEncrypt(c *gin.Context) { - c.Header("Content-Type", "application/json") - var req struct { - SessionID string `json:"session_id" binding:"required"` - Plaintext string `json:"plaintext" binding:"required"` - } + lockedCt, err := memguard.NewImmutableFromBytes(ct) + if err != nil { + return nil, nil, err + } - if err := c.BindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"}) - return - } + lockedSs, err := memguard.NewImmutableFromBytes(ss) + if err != nil { + lockedCt.Destroy() + return nil, nil, err + } - session, ok := sessions.Load(req.SessionID) - if !ok { - c.JSON(http.StatusNotFound, gin.H{"error": "session not found"}) - return - } + return lockedCt, lockedSs, nil +} - sess := session.(*Session) - if sess.BuddyPublicKey == nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "session not paired"}) - return - } +func quantumDecapsulate(ct *memguard.LockedBuffer, secKey *memguard.LockedBuffer) (*memguard.LockedBuffer, error) { + kem := oqs.KeyEncapsulation{} + defer kem.Free() - privateKeyArray := memguard.NewBuffer(keyLength) - buddyPubArray := memguard.NewBuffer(keyLength) - defer privateKeyArray.Destroy() - defer buddyPubArray.Destroy() + if err := kem.Init(KEM_ALG, nil); err != nil { + return nil, err + } - copy(privateKeyArray.Bytes(), sess.PrivateKey.Bytes()) - copy(buddyPubArray.Bytes(), sess.BuddyPublicKey.Bytes()) + if err := kem.ImportSecretKey(secKey.Bytes()); err != nil { + return nil, err + } - nonceBuf := memguard.NewBuffer(nonceLength) - defer nonceBuf.Destroy() + ss, err := kem.DecapSecretKey(ct.Bytes()) + if err != nil { + return nil, err + } - if _, err := rand.Read(nonceBuf.Bytes()); err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "nonce generation failed"}) - return - } + lockedSs, err := memguard.NewImmutableFromBytes(ss) + if err != nil { + return nil, err + } - var nonce [nonceLength]byte - copy(nonce[:], nonceBuf.Bytes()) + return lockedSs, nil +} - var privateKeyArr, buddyPubArr [keyLength]byte - copy(privateKeyArr[:], privateKeyArray.Bytes()) - copy(buddyPubArr[:], buddyPubArray.Bytes()) +func quantumSign(msg []byte, secKey *memguard.LockedBuffer) (*memguard.LockedBuffer, error) { + sig := oqs.Signature{} + defer sig.Free() - plaintextBuf := memguard.NewBufferFromBytes([]byte(req.Plaintext)) - defer plaintextBuf.Destroy() + if err := sig.Init(SIG_ALG, nil); err != nil { + return nil, err + } - encrypted := box.Seal(nonce[:], plaintextBuf.Bytes(), &nonce, &buddyPubArr, &privateKeyArr) + signature, err := sig.Sign(msg, secKey.Bytes()) + if err != nil { + return nil, err + } - c.JSON(http.StatusOK, gin.H{ - "encrypted_b64": base64.StdEncoding.EncodeToString(encrypted), - }) + lockedSig, err := memguard.NewImmutableFromBytes(signature) + if err != nil { + return nil, err + } - runtime.GC() + return lockedSig, nil } -func buddyDecrypt(c *gin.Context) { - c.Header("Content-Type", "application/json") - var req struct { - SessionID string `json:"session_id" binding:"required"` - EncryptedB64 string `json:"encrypted_b64" binding:"required"` - } - - if err := c.BindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"}) - return - } - - session, ok := sessions.Load(req.SessionID) - if !ok { - c.JSON(http.StatusNotFound, gin.H{"error": "session not found"}) - return - } - - sess := session.(*Session) - if sess.BuddyPublicKey == nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "session not paired"}) - return - } - - encrypted, err := base64.StdEncoding.DecodeString(req.EncryptedB64) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "invalid base64 encoding"}) - return - } - - if len(encrypted) < nonceLength { - c.JSON(http.StatusBadRequest, gin.H{"error": "invalid ciphertext length"}) - return - } - - privateKeyArray := memguard.NewBuffer(keyLength) - buddyPubArray := memguard.NewBuffer(keyLength) - defer privateKeyArray.Destroy() - defer buddyPubArray.Destroy() - - copy(privateKeyArray.Bytes(), sess.PrivateKey.Bytes()) - copy(buddyPubArray.Bytes(), sess.BuddyPublicKey.Bytes()) - - var privateKeyArr, buddyPubArr [keyLength]byte - var nonce [nonceLength]byte - copy(privateKeyArr[:], privateKeyArray.Bytes()) - copy(buddyPubArr[:], buddyPubArray.Bytes()) - copy(nonce[:], encrypted[:nonceLength]) - - decrypted, ok := box.Open(nil, encrypted[nonceLength:], &nonce, &buddyPubArr, &privateKeyArr) - if !ok { - c.JSON(http.StatusBadRequest, gin.H{"error": "decryption failed"}) - return - } - - c.JSON(http.StatusOK, gin.H{"plaintext": string(decrypted)}) - runtime.GC() +func quantumVerify(msg []byte, sig *memguard.LockedBuffer, pubKey *memguard.LockedBuffer) (bool, error) { + verifier := oqs.Signature{} + defer verifier.Free() + + if err := verifier.Init(SIG_ALG, pubKey.Bytes()); err != nil { + return false, err + } + + isValid, err := verifier.Verify(msg, sig.Bytes(), pubKey.Bytes()) + return isValid, err } -func randomBytes(n int) []byte { - b := make([]byte, n) - if _, err := rand.Read(b); err != nil { - panic(err) - } - return b +func secureTransmission(session *QuantumSession, data []byte) ([]byte, error) { + nonce := make([]byte, 24) + if _, err := rand.Read(nonce); err != nil { + return nil, err + } + + ss, err := session.sessionKey.Open() + if err != nil { + return nil, err + } + defer ss.Destroy() + + hash, err := blake2b.New512(nil) + if err != nil { + return nil, err + } + + hash.Write(ss.Bytes()) + hash.Write(nonce) + hmacKey := hash.Sum(nil) + + sealedData, err := memguard.NewImmutableFromBytes(data) + if err != nil { + return nil, err + } + defer sealedData.Destroy() + + ciphertext := make([]byte, len(data)+blake2b.Size256) + binary.LittleEndian.PutUint64(ciphertext[:8], uint64(len(data))) + + // XChaCha20-Poly1305 implementation here (omitted for brevity) + // ... + + return ciphertext, nil } func main() { - memguard.CatchInterrupt() - defer memguard.Purge() - - log.Printf("Starting Nofuture server with enhanced memory protection...") - - gin.SetMode(gin.ReleaseMode) - r := gin.New() - r.Use(gin.Recovery()) - - // CORS middleware only for API routes - r.Use(func(c *gin.Context) { - if strings.HasPrefix(c.Request.URL.Path, "/api/") { - c.Header("Access-Control-Allow-Origin", "*") - c.Header("Access-Control-Allow-Methods", "POST, OPTIONS") - c.Header("Access-Control-Allow-Headers", "Content-Type") - c.Header("Content-Type", "application/json") - - if c.Request.Method == "OPTIONS" { - c.AbortWithStatus(204) - return - } - } - c.Next() - }) - - // Create API group with its own middleware - api := r.Group("/api") - { - api.POST("/start_session", startSession) - api.POST("/end_session", endSession) - api.POST("/pair_sessions", pairSessions) - api.POST("/buddy_encrypt", buddyEncrypt) - api.POST("/buddy_decrypt", buddyDecrypt) - } - - // Serve static files - r.StaticFile("/", "./index.html") - r.Static("/js", "./js") - r.Static("/static", "./static") - - serverAddr := "127.0.0.1:3000" - log.Printf("Server starting on %s", serverAddr) - - if err := r.Run(serverAddr); err != nil { - log.Fatalf("Server startup failed: %v", err) - } + // Esempio di utilizzo completo + passphrase, err := memguard.NewImmutableRandom(32) + if err != nil { + fmt.Fprintln(os.Stderr, "Critical entropy failure:", err) + os.Exit(1) + } + defer passphrase.Destroy() + + salt := make([]byte, SALT_SIZE) + if _, err := rand.Read(salt); err != nil { + fmt.Fprintln(os.Stderr, "Entropy failure:", err) + os.Exit(1) + } + + // Deriva la chiave dell'enclave + enclaveKey, err := deriveEnclaveKey(guard(passphrase.Bytes()), salt) + if err != nil { + fmt.Fprintln(os.Stderr, "Key derivation failed:", err) + os.Exit(1) + } + defer enclaveKey.Destroy() + + // Genera chiavi PQ + pubKey, secKey, err := quantumKEMKeyPair() + if err != nil { + fmt.Fprintln(os.Stderr, "PQ Keygen failed:", err) + os.Exit(1) + } + defer pubKey.Destroy() + defer secKey.Destroy() + + // Simula trasmissione sicura + ct, ss, err := quantumEncapsulate(pubKey) + if err != nil { + fmt.Fprintln(os.Stderr, "Encapsulation failed:", err) + os.Exit(1) + } + defer ct.Destroy() + defer ss.Destroy() + + // Decapsula il segreto + decryptedSs, err := quantumDecapsulate(ct, secKey) + if err != nil { + fmt.Fprintln(os.Stderr, "Decapsulation failed:", err) + os.Exit(1) + } + defer decryptedSs.Destroy() + + fmt.Println("Post-Quantum Secure Channel Established") } |
