summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGab <24553253+gabrix73@users.noreply.github.com>2025-02-13 15:05:44 +0100
committerGitHub <noreply@github.com>2025-02-13 15:05:44 +0100
commit3069c554969aa0c129b5279192163fa6121a0607 (patch)
tree8ef17786826cf8053d6ad36333ba044645ea02b7
parent2ba87f6b8d199e64a6bf3548077da4ccaf28a32f (diff)
downloadnofuture-go-memguard-3069c554969aa0c129b5279192163fa6121a0607.tar.gz
nofuture-go-memguard-3069c554969aa0c129b5279192163fa6121a0607.tar.xz
nofuture-go-memguard-3069c554969aa0c129b5279192163fa6121a0607.zip
Update nofuture.go
-rw-r--r--nofuture.go525
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")
}