diff --git a/aead/aead.go b/aead/aead.go index 62774ae..2e9c087 100644 --- a/aead/aead.go +++ b/aead/aead.go @@ -14,25 +14,25 @@ import ( type AeadID string const ( - AES256GCM AeadID = "aes256gcm" - ChaCha20Poly1305 AeadID = "chacha20poly1305" - AES256GCMSIV AeadID = "aes256gcmsiv" + AES256GCM AeadID = "aes256gcm" + ChaCha20Poly1305 AeadID = "chacha20poly1305" + AES256GCMSIV AeadID = "aes256gcmsiv" ) // AEAD interface for authenticated encryption type AEAD interface { // Seal encrypts and authenticates plaintext Seal(dst, nonce, plaintext, aad []byte) []byte - + // Open decrypts and authenticates ciphertext Open(dst, nonce, ciphertext, aad []byte) ([]byte, error) - + // NonceSize returns the nonce size in bytes NonceSize() int - + // Overhead returns the authentication tag size Overhead() int - + // KeySize returns the key size in bytes KeySize() int } @@ -47,17 +47,17 @@ func NewAES256GCM(key []byte) (AEAD, error) { if len(key) != 32 { return nil, errors.New("AES-256-GCM requires 32-byte key") } - + block, err := aes.NewCipher(key) if err != nil { return nil, err } - + aead, err := cipher.NewGCM(block) if err != nil { return nil, err } - + return &AES256GCMImpl{aead: aead}, nil } @@ -66,7 +66,7 @@ func (a *AES256GCMImpl) Seal(dst, nonce, plaintext, aad []byte) []byte { if len(nonce) != a.NonceSize() { panic(fmt.Sprintf("invalid nonce size: got %d, want %d", len(nonce), a.NonceSize())) } - + // GCM handles AAD internally return a.aead.Seal(dst, nonce, plaintext, aad) } @@ -76,7 +76,7 @@ func (a *AES256GCMImpl) Open(dst, nonce, ciphertext, aad []byte) ([]byte, error) if len(nonce) != a.NonceSize() { return nil, fmt.Errorf("invalid nonce size: got %d, want %d", len(nonce), a.NonceSize()) } - + return a.aead.Open(dst, nonce, ciphertext, aad) } @@ -105,12 +105,12 @@ func NewChaCha20Poly1305(key []byte) (AEAD, error) { if len(key) != 32 { return nil, errors.New("ChaCha20-Poly1305 requires 32-byte key") } - + aead, err := chacha20poly1305.New(key) if err != nil { return nil, err } - + return &ChaCha20Poly1305Impl{aead: aead}, nil } @@ -119,7 +119,7 @@ func (c *ChaCha20Poly1305Impl) Seal(dst, nonce, plaintext, aad []byte) []byte { if len(nonce) != c.NonceSize() { panic(fmt.Sprintf("invalid nonce size: got %d, want %d", len(nonce), c.NonceSize())) } - + return c.aead.Seal(dst, nonce, plaintext, aad) } @@ -128,7 +128,7 @@ func (c *ChaCha20Poly1305Impl) Open(dst, nonce, ciphertext, aad []byte) ([]byte, if len(nonce) != c.NonceSize() { return nil, fmt.Errorf("invalid nonce size: got %d, want %d", len(nonce), c.NonceSize()) } - + return c.aead.Open(dst, nonce, ciphertext, aad) } @@ -179,13 +179,13 @@ func NewNonceGenerator(streamID uint32) *NonceGenerator { // Next returns the next nonce and increments sequence number func (ng *NonceGenerator) Next() []byte { nonce := make([]byte, 12) // 96-bit nonce - + // First 4 bytes: stream ID nonce[0] = byte(ng.streamID >> 24) nonce[1] = byte(ng.streamID >> 16) nonce[2] = byte(ng.streamID >> 8) nonce[3] = byte(ng.streamID) - + // Next 8 bytes: sequence number nonce[4] = byte(ng.seqNo >> 56) nonce[5] = byte(ng.seqNo >> 48) @@ -195,9 +195,9 @@ func (ng *NonceGenerator) Next() []byte { nonce[9] = byte(ng.seqNo >> 16) nonce[10] = byte(ng.seqNo >> 8) nonce[11] = byte(ng.seqNo) - + ng.seqNo++ - + return nonce } @@ -209,4 +209,4 @@ func (ng *NonceGenerator) SetSeqNo(seqNo uint64) { // GetSeqNo returns the current sequence number func (ng *NonceGenerator) GetSeqNo() uint64 { return ng.seqNo -} \ No newline at end of file +} diff --git a/aggregated/managers.go b/aggregated/managers.go index 0b71a78..894cdfc 100644 --- a/aggregated/managers.go +++ b/aggregated/managers.go @@ -7,11 +7,11 @@ import ( "errors" "sync" + "github.com/luxfi/crypto/bls" + "github.com/luxfi/crypto/cggmp21" + "github.com/luxfi/crypto/corona" "github.com/luxfi/ids" "github.com/luxfi/log" - "github.com/luxfi/crypto/bls" - "github.com/luxfi/crypto/corona" - "github.com/luxfi/crypto/cggmp21" ) // BLSManager manages BLS signature operations @@ -33,7 +33,7 @@ func (m *BLSManager) CreateKeyPair() (*bls.SecretKey, *bls.PublicKey, error) { if err != nil { return nil, nil, err } - + pk := sk.PublicKey() return sk, pk, nil } @@ -67,12 +67,12 @@ func (m *CoronaManager) CreateKeyPair() (*corona.PrivateKey, *corona.PublicKey, if err != nil { return nil, nil, err } - + pubKey, err := factory.ToPublicKey(privKey) if err != nil { return nil, nil, err } - + return privKey, pubKey, nil } @@ -109,15 +109,15 @@ func (m *CGGMP21Manager) InitializeParty( ) error { m.mu.Lock() defer m.mu.Unlock() - + party, err := cggmp21.NewParty(partyID, index, config, m.log) if err != nil { return err } - + m.parties[index] = party m.config = config - + return nil } @@ -125,12 +125,12 @@ func (m *CGGMP21Manager) InitializeParty( func (m *CGGMP21Manager) GetParty(index int) (*cggmp21.Party, error) { m.mu.RLock() defer m.mu.RUnlock() - + party, exists := m.parties[index] if !exists { return nil, errors.New("party not found") } - + return party, nil } @@ -151,7 +151,7 @@ func NewFeeCollector() FeeCollector { func (fc *FeeCollector) CollectFee(sigType SignatureType, amount uint64) { fc.mu.Lock() defer fc.mu.Unlock() - + fc.collectedFees[sigType] += amount } @@ -159,12 +159,12 @@ func (fc *FeeCollector) CollectFee(sigType SignatureType, amount uint64) { func (fc *FeeCollector) GetCollectedFees() map[SignatureType]uint64 { fc.mu.RLock() defer fc.mu.RUnlock() - + fees := make(map[SignatureType]uint64) for k, v := range fc.collectedFees { fees[k] = v } - + return fees } @@ -172,12 +172,12 @@ func (fc *FeeCollector) GetCollectedFees() map[SignatureType]uint64 { func (fc *FeeCollector) GetTotalFees() uint64 { fc.mu.RLock() defer fc.mu.RUnlock() - + var total uint64 for _, amount := range fc.collectedFees { total += amount } - + return total } @@ -185,9 +185,9 @@ func (fc *FeeCollector) GetTotalFees() uint64 { func (fc *FeeCollector) ResetFees() map[SignatureType]uint64 { fc.mu.Lock() defer fc.mu.Unlock() - + oldFees := fc.collectedFees fc.collectedFees = make(map[SignatureType]uint64) - + return oldFees -} \ No newline at end of file +} diff --git a/aggregated/signature_aggregator.go b/aggregated/signature_aggregator.go index 038aba5..ebc57e5 100644 --- a/aggregated/signature_aggregator.go +++ b/aggregated/signature_aggregator.go @@ -10,10 +10,10 @@ import ( "sync" "time" + "github.com/luxfi/crypto/bls" + "github.com/luxfi/crypto/corona" "github.com/luxfi/ids" "github.com/luxfi/log" - "github.com/luxfi/crypto/corona" - "github.com/luxfi/crypto/bls" ) // Import log field helpers @@ -36,78 +36,78 @@ const ( // SignatureConfig contains configuration for signature aggregation type SignatureConfig struct { // Network-wide signature type preference - PreferredType SignatureType `json:"preferredType"` - + PreferredType SignatureType `json:"preferredType"` + // Enable specific signature types - EnableBLS bool `json:"enableBLS"` - EnableCorona bool `json:"enableCorona"` - EnableCGGMP21 bool `json:"enableCGGMP21"` - + EnableBLS bool `json:"enableBLS"` + EnableCorona bool `json:"enableCorona"` + EnableCGGMP21 bool `json:"enableCGGMP21"` + // Fee configuration (in nLUX - nano LUX) - BLSFee uint64 `json:"blsFee"` // 0 = free - CoronaFee uint64 `json:"coronaFee"` // Premium for enhanced privacy - CGGMP21Fee uint64 `json:"cggmp21Fee"` // Premium for threshold signatures - + BLSFee uint64 `json:"blsFee"` // 0 = free + CoronaFee uint64 `json:"coronaFee"` // Premium for enhanced privacy + CGGMP21Fee uint64 `json:"cggmp21Fee"` // Premium for threshold signatures + // Performance settings - ParallelAggregation bool `json:"parallelAggregation"` - MaxSignersPerRound int `json:"maxSignersPerRound"` - + ParallelAggregation bool `json:"parallelAggregation"` + MaxSignersPerRound int `json:"maxSignersPerRound"` + // Security settings - MinSigners int `json:"minSigners"` - ThresholdRatio float64 `json:"thresholdRatio"` // e.g., 0.67 for 2/3 + MinSigners int `json:"minSigners"` + ThresholdRatio float64 `json:"thresholdRatio"` // e.g., 0.67 for 2/3 } // AggregatedSignature represents an aggregated signature with metadata type AggregatedSignature struct { - Type SignatureType `json:"type"` - Signature []byte `json:"signature"` - SignerIDs []ids.NodeID `json:"signerIds,omitempty"` - SignerCount int `json:"signerCount"` - RingPublicKeys []*corona.PublicKey `json:"ringPublicKeys,omitempty"` // For Corona - AggregateKey []byte `json:"aggregateKey,omitempty"` // For BLS - Threshold int `json:"threshold,omitempty"` // For CGGMP21 - TotalFee uint64 `json:"totalFee"` + Type SignatureType `json:"type"` + Signature []byte `json:"signature"` + SignerIDs []ids.NodeID `json:"signerIds,omitempty"` + SignerCount int `json:"signerCount"` + RingPublicKeys []*corona.PublicKey `json:"ringPublicKeys,omitempty"` // For Corona + AggregateKey []byte `json:"aggregateKey,omitempty"` // For BLS + Threshold int `json:"threshold,omitempty"` // For CGGMP21 + TotalFee uint64 `json:"totalFee"` } // SignatureAggregator manages network-wide signature aggregation type SignatureAggregator struct { - config SignatureConfig - log log.Logger - + config SignatureConfig + log log.Logger + // Signature managers blsManager *BLSManager coronaManager *CoronaManager cggmpManager *CGGMP21Manager - + // Active aggregation sessions - sessions map[string]*AggregationSession - + sessions map[string]*AggregationSession + // Fee collector feeCollector FeeCollector - - mu sync.RWMutex + + mu sync.RWMutex } // AggregationSession represents an active signature aggregation type AggregationSession struct { - SessionID string - Message []byte + SessionID string + Message []byte SignatureType SignatureType - + // Collected signatures BLSSignatures []*bls.Signature BLSPublicKeys []*bls.PublicKey CoronaSignatures []*corona.RingSignature CoronaRing []*corona.PublicKey - + // Signers - Signers map[ids.NodeID]bool - SignerCount int - + Signers map[ids.NodeID]bool + SignerCount int + // Status - StartTime int64 - Completed bool - Result *AggregatedSignature + StartTime int64 + Completed bool + Result *AggregatedSignature } // NewSignatureAggregator creates a new signature aggregator @@ -117,22 +117,22 @@ func NewSignatureAggregator(config SignatureConfig, log log.Logger) (*SignatureA log: log, sessions: make(map[string]*AggregationSession), } - + // Initialize signature managers based on config if config.EnableBLS { sa.blsManager = NewBLSManager(log) } - + if config.EnableCorona { sa.coronaManager = NewCoronaManager(log) } - + if config.EnableCGGMP21 { sa.cggmpManager = NewCGGMP21Manager(log) } - + sa.feeCollector = NewFeeCollector() - + log.Info("Signature aggregator initialized", logUint8("preferredType", uint8(config.PreferredType)), logBool("blsEnabled", config.EnableBLS), @@ -141,7 +141,7 @@ func NewSignatureAggregator(config SignatureConfig, log log.Logger) (*SignatureA logUint64("blsFee", config.BLSFee), logUint64("coronaFee", config.CoronaFee), ) - + return sa, nil } @@ -154,11 +154,11 @@ func (sa *SignatureAggregator) StartAggregation( ) error { sa.mu.Lock() defer sa.mu.Unlock() - + if _, exists := sa.sessions[sessionID]; exists { return errors.New("session already exists") } - + // Validate signature type is enabled switch sigType { case SignatureTypeBLS: @@ -176,7 +176,7 @@ func (sa *SignatureAggregator) StartAggregation( default: return errors.New("unknown signature type") } - + session := &AggregationSession{ SessionID: sessionID, Message: message, @@ -184,15 +184,15 @@ func (sa *SignatureAggregator) StartAggregation( Signers: make(map[ids.NodeID]bool), StartTime: getCurrentTime(), } - + sa.sessions[sessionID] = session - + sa.log.Debug("Started aggregation session", log.String("sessionID", sessionID), log.Uint8("type", uint8(sigType)), log.Int("expectedSigners", expectedSigners), ) - + return nil } @@ -205,32 +205,32 @@ func (sa *SignatureAggregator) AddSignature( ) error { sa.mu.Lock() defer sa.mu.Unlock() - + session, exists := sa.sessions[sessionID] if !exists { return errors.New("session not found") } - + if session.Completed { return errors.New("session already completed") } - + // Check if signer already contributed if session.Signers[signerID] { return errors.New("signer already contributed") } - + // Add signature based on type switch session.SignatureType { case SignatureTypeBLS: return sa.addBLSSignature(session, signerID, signature, publicKey) - + case SignatureTypeCorona: return sa.addCoronaSignature(session, signerID, signature, publicKey) - + case SignatureTypeCGGMP21: return errors.New("CGGMP21 uses different protocol flow") - + default: return errors.New("unknown signature type") } @@ -248,24 +248,24 @@ func (sa *SignatureAggregator) addBLSSignature( if err != nil { return fmt.Errorf("invalid BLS signature: %w", err) } - + pk, err := bls.PublicKeyFromCompressedBytes(publicKey) if err != nil { return fmt.Errorf("invalid BLS public key: %w", err) } - + // Verify individual signature valid := bls.Verify(pk, sig, session.Message) if !valid { return fmt.Errorf("BLS signature verification failed") } - + // Add to session session.BLSSignatures = append(session.BLSSignatures, sig) session.BLSPublicKeys = append(session.BLSPublicKeys, pk) session.Signers[signerID] = true session.SignerCount++ - + return nil } @@ -284,7 +284,7 @@ func (sa *SignatureAggregator) addCoronaSignature( S: make([]*big.Int, corona.DefaultRingSize), KeyImage: &corona.Point{X: big.NewInt(0), Y: big.NewInt(0)}, } - + // Parse public key // For now, create from bytes // In production, implement proper deserialization @@ -294,7 +294,7 @@ func (sa *SignatureAggregator) addCoronaSignature( Y: new(big.Int).SetBytes(publicKey[32:64]), }, } - + // Add to ring if not already present inRing := false for _, ringPK := range session.CoronaRing { @@ -306,12 +306,12 @@ func (sa *SignatureAggregator) addCoronaSignature( if !inRing { session.CoronaRing = append(session.CoronaRing, pk) } - + // Store signature session.CoronaSignatures = append(session.CoronaSignatures, ringSig) session.Signers[signerID] = true session.SignerCount++ - + return nil } @@ -322,53 +322,53 @@ func (sa *SignatureAggregator) FinalizeAggregation( ) (*AggregatedSignature, error) { sa.mu.Lock() defer sa.mu.Unlock() - + session, exists := sa.sessions[sessionID] if !exists { return nil, errors.New("session not found") } - + if session.Completed { return session.Result, nil } - + // Check minimum signers if session.SignerCount < requiredSigners { return nil, fmt.Errorf("insufficient signers: %d < %d", session.SignerCount, requiredSigners) } - + var result *AggregatedSignature var err error - + switch session.SignatureType { case SignatureTypeBLS: result, err = sa.finalizeBLS(session) - + case SignatureTypeCorona: result, err = sa.finalizeCorona(session) - + default: return nil, errors.New("unknown signature type") } - + if err != nil { return nil, err } - + // Calculate total fee result.TotalFee = sa.calculateFee(session.SignatureType, session.SignerCount) - + // Mark session as completed session.Completed = true session.Result = result - + sa.log.Info("Finalized aggregation", log.String("sessionID", sessionID), log.Uint8("type", uint8(session.SignatureType)), log.Int("signers", session.SignerCount), log.Uint64("totalFee", result.TotalFee), ) - + return result, nil } @@ -377,34 +377,34 @@ func (sa *SignatureAggregator) finalizeBLS(session *AggregationSession) (*Aggreg if len(session.BLSSignatures) == 0 { return nil, errors.New("no BLS signatures to aggregate") } - + // Aggregate signatures aggSig, err := bls.AggregateSignatures(session.BLSSignatures) if err != nil { return nil, fmt.Errorf("BLS aggregation failed: %w", err) } - + // Aggregate public keys aggPK, err := bls.AggregatePublicKeys(session.BLSPublicKeys) if err != nil { return nil, fmt.Errorf("BLS public key aggregation failed: %w", err) } - + // Verify aggregate signature valid := bls.Verify(aggPK, aggSig, session.Message) if !valid { return nil, fmt.Errorf("aggregate signature verification failed") } - + sigBytes := bls.SignatureToBytes(aggSig) pkBytes := bls.PublicKeyToCompressedBytes(aggPK) - + // Extract signer IDs signerIDs := make([]ids.NodeID, 0, len(session.Signers)) for id := range session.Signers { signerIDs = append(signerIDs, id) } - + return &AggregatedSignature{ Type: SignatureTypeBLS, Signature: sigBytes, @@ -419,11 +419,11 @@ func (sa *SignatureAggregator) finalizeCorona(session *AggregationSession) (*Agg if len(session.CoronaSignatures) == 0 { return nil, errors.New("no Corona signatures collected") } - + // For Corona, we use the first signature as the aggregated result // since ring signatures provide anonymity within the ring ringSig := session.CoronaSignatures[0] - + // Serialize signature (simplified for now) // In production, implement proper serialization sigBytes := make([]byte, 0) @@ -433,13 +433,13 @@ func (sa *SignatureAggregator) finalizeCorona(session *AggregationSession) (*Agg sigBytes = append(sigBytes, s.Bytes()...) } } - + // Verify against the full ring valid := ringSig.Verify(session.Message) if !valid { return nil, fmt.Errorf("ring signature verification failed") } - + return &AggregatedSignature{ Type: SignatureTypeCorona, Signature: sigBytes, @@ -451,7 +451,7 @@ func (sa *SignatureAggregator) finalizeCorona(session *AggregationSession) (*Agg // calculateFee calculates the total fee for signature aggregation func (sa *SignatureAggregator) calculateFee(sigType SignatureType, signerCount int) uint64 { var feePerSigner uint64 - + switch sigType { case SignatureTypeBLS: feePerSigner = sa.config.BLSFee // 0 for free @@ -462,7 +462,7 @@ func (sa *SignatureAggregator) calculateFee(sigType SignatureType, signerCount i default: feePerSigner = 0 } - + return feePerSigner * uint64(signerCount) } @@ -474,13 +474,13 @@ func (sa *SignatureAggregator) VerifyAggregatedSignature( switch aggSig.Type { case SignatureTypeBLS: return sa.verifyBLSAggregate(message, aggSig) - + case SignatureTypeCorona: return sa.verifyCoronaAggregate(message, aggSig) - + case SignatureTypeCGGMP21: return errors.New("CGGMP21 verification not implemented") - + default: return errors.New("unknown signature type") } @@ -492,17 +492,17 @@ func (sa *SignatureAggregator) verifyBLSAggregate(message []byte, aggSig *Aggreg if err != nil { return err } - + pk, err := bls.PublicKeyFromCompressedBytes(aggSig.AggregateKey) if err != nil { return err } - + valid := bls.Verify(pk, sig, message) if !valid { return errors.New("BLS signature verification failed") } - + return nil } @@ -513,7 +513,7 @@ func (sa *SignatureAggregator) verifyCoronaAggregate(message []byte, aggSig *Agg if len(aggSig.Signature) < 256 { return errors.New("invalid ring signature") } - + return nil } @@ -521,12 +521,12 @@ func (sa *SignatureAggregator) verifyCoronaAggregate(message []byte, aggSig *Agg func (sa *SignatureAggregator) GetSessionStatus(sessionID string) (map[string]interface{}, error) { sa.mu.RLock() defer sa.mu.RUnlock() - + session, exists := sa.sessions[sessionID] if !exists { return nil, errors.New("session not found") } - + status := map[string]interface{}{ "sessionID": session.SessionID, "signatureType": session.SignatureType, @@ -534,11 +534,11 @@ func (sa *SignatureAggregator) GetSessionStatus(sessionID string) (map[string]in "completed": session.Completed, "startTime": session.StartTime, } - + if session.Completed && session.Result != nil { status["totalFee"] = session.Result.TotalFee } - + return status, nil } @@ -546,9 +546,9 @@ func (sa *SignatureAggregator) GetSessionStatus(sessionID string) (map[string]in func (sa *SignatureAggregator) Cleanup(maxAge int64) { sa.mu.Lock() defer sa.mu.Unlock() - + currentTime := getCurrentTime() - + for sessionID, session := range sa.sessions { if currentTime-session.StartTime > maxAge { delete(sa.sessions, sessionID) @@ -559,4 +559,4 @@ func (sa *SignatureAggregator) Cleanup(maxAge int64) { // Helper function func getCurrentTime() int64 { return time.Now().Unix() -} \ No newline at end of file +} diff --git a/audit_test.go b/audit_test.go index d362336..e565fde 100644 --- a/audit_test.go +++ b/audit_test.go @@ -41,24 +41,24 @@ func TestMLKEMEdgeCases(t *testing.T) { modes := []mlkem.Mode{mlkem.MLKEM512, mlkem.MLKEM768, mlkem.MLKEM1024} for _, mode := range modes { priv1, _, _ := mlkem.GenerateKeyPair(rand.Reader, mode) - + // Serialize privBytes := priv1.Bytes() pubBytes := priv1.PublicKey.Bytes() - + // Deserialize priv2, err := mlkem.PrivateKeyFromBytes(privBytes, mode) require.NoError(t, err) pub2, err := mlkem.PublicKeyFromBytes(pubBytes, mode) require.NoError(t, err) - + // Verify they work the same result1, _ := priv1.PublicKey.Encapsulate(rand.Reader) secret1, _ := priv1.Decapsulate(result1.Ciphertext) - + result2, _ := pub2.Encapsulate(rand.Reader) secret2, _ := priv2.Decapsulate(result2.Ciphertext) - + // Both should produce valid shared secrets assert.Len(t, secret1, 32) assert.Len(t, secret2, 32) @@ -69,10 +69,10 @@ func TestMLKEMEdgeCases(t *testing.T) { // Same private key seed should generate same public key privBytes := make([]byte, mlkem.MLKEM768PrivateKeySize) copy(privBytes, []byte("deterministic seed for testing")) - + priv1, _ := mlkem.PrivateKeyFromBytes(privBytes, mlkem.MLKEM768) priv2, _ := mlkem.PrivateKeyFromBytes(privBytes, mlkem.MLKEM768) - + assert.Equal(t, priv1.PublicKey.Bytes(), priv2.PublicKey.Bytes()) }) } @@ -95,7 +95,7 @@ func TestMLDSAEdgeCases(t *testing.T) { priv, _ := mldsa.GenerateKey(rand.Reader, mldsa.MLDSA65) largeMsg := make([]byte, 10000) rand.Read(largeMsg) - + sig, err := priv.Sign(rand.Reader, largeMsg, nil) require.NoError(t, err) assert.True(t, priv.PublicKey.Verify(largeMsg, sig, nil)) @@ -104,10 +104,10 @@ func TestMLDSAEdgeCases(t *testing.T) { t.Run("Signature Malleability", func(t *testing.T) { priv, _ := mldsa.GenerateKey(rand.Reader, mldsa.MLDSA65) msg := []byte("test message") - + sig1, _ := priv.Sign(rand.Reader, msg, nil) sig2, _ := priv.Sign(rand.Reader, msg, nil) - + // Signatures should be deterministic in our implementation assert.Equal(t, sig1, sig2) }) @@ -115,7 +115,7 @@ func TestMLDSAEdgeCases(t *testing.T) { t.Run("Wrong Signature Size", func(t *testing.T) { priv, _ := mldsa.GenerateKey(rand.Reader, mldsa.MLDSA65) msg := []byte("test") - + wrongSig := make([]byte, 100) // Wrong size assert.False(t, priv.PublicKey.Verify(msg, wrongSig, nil)) }) @@ -124,9 +124,9 @@ func TestMLDSAEdgeCases(t *testing.T) { priv44, _ := mldsa.GenerateKey(rand.Reader, mldsa.MLDSA44) priv65, _ := mldsa.GenerateKey(rand.Reader, mldsa.MLDSA65) msg := []byte("test") - + sig44, _ := priv44.Sign(rand.Reader, msg, nil) - + // ML-DSA65 key shouldn't verify ML-DSA44 signature assert.False(t, priv65.PublicKey.Verify(msg, sig44, nil)) }) @@ -137,10 +137,10 @@ func TestSLHDSAEdgeCases(t *testing.T) { t.Run("Deterministic Signatures", func(t *testing.T) { priv, _ := slhdsa.GenerateKey(rand.Reader, slhdsa.SLHDSA128f) msg := []byte("deterministic test") - + sig1, _ := priv.Sign(rand.Reader, msg, nil) sig2, _ := priv.Sign(rand.Reader, msg, nil) - + // SLH-DSA is deterministic - same message should produce same signature assert.Equal(t, sig1, sig2) }) @@ -154,13 +154,13 @@ func TestSLHDSAEdgeCases(t *testing.T) { {slhdsa.SLHDSA128f, "128f", slhdsa.SLHDSA128fSignatureSize}, {slhdsa.SLHDSA192f, "192f", slhdsa.SLHDSA192fSignatureSize}, } - + for _, m := range modes { t.Run(m.name, func(t *testing.T) { priv, _ := slhdsa.GenerateKey(rand.Reader, m.mode) msg := []byte("test") sig, _ := priv.Sign(rand.Reader, msg, nil) - + assert.Len(t, sig, m.size) }) } @@ -171,7 +171,7 @@ func TestSLHDSAEdgeCases(t *testing.T) { func TestConcurrency(t *testing.T) { t.Run("ML-KEM Concurrent Operations", func(t *testing.T) { priv, _, _ := mlkem.GenerateKeyPair(rand.Reader, mlkem.MLKEM768) - + // Run concurrent encapsulations done := make(chan bool, 10) for i := 0; i < 10; i++ { @@ -184,7 +184,7 @@ func TestConcurrency(t *testing.T) { done <- true }() } - + for i := 0; i < 10; i++ { <-done } @@ -192,7 +192,7 @@ func TestConcurrency(t *testing.T) { t.Run("ML-DSA Concurrent Signing", func(t *testing.T) { priv, _ := mldsa.GenerateKey(rand.Reader, mldsa.MLDSA65) - + done := make(chan bool, 10) for i := 0; i < 10; i++ { go func(id int) { @@ -203,7 +203,7 @@ func TestConcurrency(t *testing.T) { done <- true }(i) } - + for i := 0; i < 10; i++ { <-done } @@ -229,11 +229,11 @@ func TestParameterValidation(t *testing.T) { assert.Equal(t, 800, mlkem.MLKEM512PublicKeySize) assert.Equal(t, 1632, mlkem.MLKEM512PrivateKeySize) assert.Equal(t, 768, mlkem.MLKEM512CiphertextSize) - + assert.Equal(t, 1184, mlkem.MLKEM768PublicKeySize) assert.Equal(t, 2400, mlkem.MLKEM768PrivateKeySize) assert.Equal(t, 1088, mlkem.MLKEM768CiphertextSize) - + assert.Equal(t, 1568, mlkem.MLKEM1024PublicKeySize) assert.Equal(t, 3168, mlkem.MLKEM1024PrivateKeySize) assert.Equal(t, 1568, mlkem.MLKEM1024CiphertextSize) @@ -242,12 +242,12 @@ func TestParameterValidation(t *testing.T) { assert.Equal(t, 1312, mldsa.MLDSA44PublicKeySize) assert.Equal(t, 2528, mldsa.MLDSA44PrivateKeySize) assert.Equal(t, 2420, mldsa.MLDSA44SignatureSize) - + assert.Equal(t, 1952, mldsa.MLDSA65PublicKeySize) assert.Equal(t, 4000, mldsa.MLDSA65PrivateKeySize) assert.Equal(t, 3293, mldsa.MLDSA65SignatureSize) - + assert.Equal(t, 2592, mldsa.MLDSA87PublicKeySize) assert.Equal(t, 4864, mldsa.MLDSA87PrivateKeySize) assert.Equal(t, 4595, mldsa.MLDSA87SignatureSize) -} \ No newline at end of file +} diff --git a/bls/bls.go b/bls/bls.go index 374ee15..e900b81 100644 --- a/bls/bls.go +++ b/bls/bls.go @@ -106,7 +106,7 @@ func (pk *PublicKey) From(blstSK interface{}) *PublicKey { Compress() []byte } } - + if sk, ok := blstSK.(blstSecretKey); ok { pkBytes := sk.PublicKey().Compress() newPk, err := PublicKeyFromCompressedBytes(pkBytes) @@ -115,7 +115,7 @@ func (pk *PublicKey) From(blstSK interface{}) *PublicKey { } return newPk } - + return nil } @@ -268,7 +268,7 @@ func SignatureFromBytes(sigBytes []byte) (*Signature, error) { allSame = false } } - + // Reject signatures that are all zeros or all the same byte (e.g., all 0xFF) if allZero || allSame { return nil, ErrFailedSignatureDecompress @@ -285,7 +285,7 @@ func (sig *Signature) Sign(blstSK interface{}, msg []byte, dst []byte) *Signatur Compress() []byte } } - + if sk, ok := blstSK.(blstSecretKey); ok { blstSig := sk.Sign(msg, dst, nil) sigBytes := blstSig.Compress() @@ -295,7 +295,7 @@ func (sig *Signature) Sign(blstSK interface{}, msg []byte, dst []byte) *Signatur } return newSig } - + return nil } diff --git a/bls/bls_extended_test.go b/bls/bls_extended_test.go index 1f10f2f..ef31589 100644 --- a/bls/bls_extended_test.go +++ b/bls/bls_extended_test.go @@ -18,13 +18,13 @@ func TestNewSecretKeyExtended(t *testing.T) { if sk.sk == nil { t.Fatal("Internal secret key is nil") } - + // Verify keys are different sk2, err := NewSecretKey() if err != nil { t.Fatalf("Failed to generate second secret key: %v", err) } - + bytes1 := SecretKeyToBytes(sk) bytes2 := SecretKeyToBytes(sk2) if bytes.Equal(bytes1, bytes2) { @@ -39,32 +39,32 @@ func TestSecretKeyBytes(t *testing.T) { if err != nil { t.Fatalf("Failed to generate secret key: %v", err) } - + // Convert to bytes skBytes := SecretKeyToBytes(sk) if len(skBytes) == 0 { t.Fatal("Secret key bytes should not be empty") } - + // Test nil secret key nilBytes := SecretKeyToBytes(nil) if nilBytes != nil { t.Fatal("Nil secret key should return nil bytes") } - + // Test secret key with nil internal emptyKey := &SecretKey{} emptyBytes := SecretKeyToBytes(emptyKey) if emptyBytes != nil { t.Fatal("Secret key with nil internal should return nil bytes") } - + // Round-trip test sk2, err := SecretKeyFromBytes(skBytes) if err != nil { t.Fatalf("Failed to deserialize secret key: %v", err) } - + skBytes2 := SecretKeyToBytes(sk2) if !bytes.Equal(skBytes, skBytes2) { t.Fatal("Round-trip secret key bytes should match") @@ -78,13 +78,13 @@ func TestSecretKeyFromBytesErrors(t *testing.T) { if err == nil { t.Fatal("Should fail with invalid bytes") } - + // Test with nil bytes _, err = SecretKeyFromBytes(nil) if err == nil { t.Fatal("Should fail with nil bytes") } - + // Test with empty bytes _, err = SecretKeyFromBytes([]byte{}) if err == nil { @@ -97,7 +97,7 @@ func TestPublicKeyOperations(t *testing.T) { if err != nil { t.Fatalf("Failed to generate secret key: %v", err) } - + // Get public key pk := sk.PublicKey() if pk == nil { @@ -106,14 +106,14 @@ func TestPublicKeyOperations(t *testing.T) { if pk.pk == nil { t.Fatal("Internal public key should not be nil") } - + // Test nil secret key var nilSk *SecretKey nilPk := nilSk.PublicKey() if nilPk != nil { t.Fatal("Nil secret key should return nil public key") } - + // Test secret key with nil internal emptySk := &SecretKey{} emptyPk := emptySk.PublicKey() @@ -127,27 +127,27 @@ func TestPublicKeyBytes(t *testing.T) { if err != nil { t.Fatalf("Failed to generate secret key: %v", err) } - + pk := sk.PublicKey() - + // Test compressed bytes compressedBytes := PublicKeyToCompressedBytes(pk) if len(compressedBytes) != PublicKeyLen { t.Fatalf("Compressed public key should be %d bytes, got %d", PublicKeyLen, len(compressedBytes)) } - + // Test uncompressed bytes (should be same as compressed for circl) uncompressedBytes := PublicKeyToUncompressedBytes(pk) if !bytes.Equal(compressedBytes, uncompressedBytes) { t.Fatal("Compressed and uncompressed should be equal for circl BLS") } - + // Test nil public key nilBytes := PublicKeyToCompressedBytes(nil) if nilBytes != nil { t.Fatal("Nil public key should return nil bytes") } - + // Test public key with nil internal emptyPk := &PublicKey{} emptyBytes := PublicKeyToCompressedBytes(emptyPk) @@ -161,21 +161,21 @@ func TestPublicKeyFromBytes(t *testing.T) { if err != nil { t.Fatalf("Failed to generate secret key: %v", err) } - + pk := sk.PublicKey() pkBytes := PublicKeyToCompressedBytes(pk) - + // Test valid deserialization pk2, err := PublicKeyFromCompressedBytes(pkBytes) if err != nil { t.Fatalf("Failed to deserialize public key: %v", err) } - + pkBytes2 := PublicKeyToCompressedBytes(pk2) if !bytes.Equal(pkBytes, pkBytes2) { t.Fatal("Round-trip public key bytes should match") } - + // Test from valid uncompressed bytes pk3 := PublicKeyFromValidUncompressedBytes(pkBytes) if pk3 == nil { @@ -194,13 +194,13 @@ func TestPublicKeyFromBytesErrors(t *testing.T) { if err == nil { t.Fatal("Should fail with wrong size bytes") } - + // Test with nil _, err = PublicKeyFromCompressedBytes(nil) if err == nil { t.Fatal("Should fail with nil bytes") } - + // Test with invalid point (all zeros) zeroBytes := make([]byte, PublicKeyLen) _, err = PublicKeyFromCompressedBytes(zeroBytes) @@ -214,10 +214,10 @@ func TestSignAndVerify(t *testing.T) { if err != nil { t.Fatalf("Failed to generate secret key: %v", err) } - + pk := sk.PublicKey() msg := []byte("test message") - + // Sign message sig, err := sk.Sign(msg) if err != nil { @@ -226,20 +226,20 @@ func TestSignAndVerify(t *testing.T) { if sig == nil { t.Fatal("Signature should not be nil") } - + // Verify signature valid := Verify(pk, sig, msg) if !valid { t.Fatal("Signature should be valid") } - + // Verify with wrong message wrongMsg := []byte("wrong message") valid = Verify(pk, sig, wrongMsg) if valid { t.Fatal("Signature should be invalid for wrong message") } - + // Verify with wrong public key sk2, _ := NewSecretKey() pk2 := sk2.PublicKey() @@ -247,7 +247,7 @@ func TestSignAndVerify(t *testing.T) { if valid { t.Fatal("Signature should be invalid for wrong public key") } - + // Test nil cases nilSig, err := sk.Sign(nil) if err != nil { @@ -256,7 +256,7 @@ func TestSignAndVerify(t *testing.T) { if nilSig == nil { t.Fatal("Should handle nil message") } - + var nilSk *SecretKey nilSig2, err := nilSk.Sign(msg) if err == nil { @@ -265,7 +265,7 @@ func TestSignAndVerify(t *testing.T) { if nilSig2 != nil { t.Fatal("Nil secret key should return nil signature") } - + emptySk := &SecretKey{} emptySig, err := emptySk.Sign(msg) if err == nil { @@ -281,20 +281,20 @@ func TestVerifyEdgeCases(t *testing.T) { pk := sk.PublicKey() msg := []byte("test") sig, _ := sk.Sign(msg) - + // Test nil public key valid := Verify(nil, sig, msg) if valid { t.Fatal("Should fail with nil public key") } - + // Test public key with nil internal emptyPk := &PublicKey{} valid = Verify(emptyPk, sig, msg) if valid { t.Fatal("Should fail with empty public key") } - + // Test nil signature valid = Verify(pk, nil, msg) if valid { @@ -307,10 +307,10 @@ func TestProofOfPossession(t *testing.T) { if err != nil { t.Fatalf("Failed to generate secret key: %v", err) } - + pk := sk.PublicKey() msg := []byte("proof of possession") - + // Sign proof of possession sig, err := sk.SignProofOfPossession(msg) if err != nil { @@ -319,20 +319,20 @@ func TestProofOfPossession(t *testing.T) { if sig == nil { t.Fatal("PoP signature should not be nil") } - + // Verify proof of possession valid := VerifyProofOfPossession(pk, sig, msg) if !valid { t.Fatal("PoP should be valid") } - + // Test with wrong message wrongMsg := []byte("wrong") valid = VerifyProofOfPossession(pk, sig, wrongMsg) if valid { t.Fatal("PoP should be invalid for wrong message") } - + // Test nil cases var nilSk *SecretKey nilSig, err := nilSk.SignProofOfPossession(msg) @@ -342,7 +342,7 @@ func TestProofOfPossession(t *testing.T) { if nilSig != nil { t.Fatal("Nil secret key should return nil PoP") } - + emptySk := &SecretKey{} emptySig, err := emptySk.SignProofOfPossession(msg) if err == nil { @@ -361,25 +361,25 @@ func TestSignatureBytes(t *testing.T) { msg := []byte("test") sig, _ := sk.Sign(msg) - + // Convert to bytes sigBytes := SignatureToBytes(sig) if len(sigBytes) != SignatureLen { t.Fatalf("Signature should be %d bytes, got %d", SignatureLen, len(sigBytes)) } - + // Test nil signature nilBytes := SignatureToBytes(nil) if nilBytes != nil { t.Fatal("Nil signature should return nil bytes") } - + // Round-trip test sig2, err := SignatureFromBytes(sigBytes) if err != nil { t.Fatalf("Failed to deserialize signature: %v", err) } - + sigBytes2 := SignatureToBytes(sig2) if !bytes.Equal(sigBytes, sigBytes2) { t.Fatal("Round-trip signature bytes should match") @@ -393,14 +393,14 @@ func TestSignatureFromBytesErrors(t *testing.T) { if err == nil { t.Fatal("Should fail with wrong size") } - + // Test all zeros (invalid signature) zeroBytes := make([]byte, SignatureLen) _, err = SignatureFromBytes(zeroBytes) if err == nil { t.Fatal("Should fail with all zero bytes") } - + // Test nil _, err = SignatureFromBytes(nil) if err == nil { @@ -414,16 +414,16 @@ func TestAggregatePublicKeysEdgeCases(t *testing.T) { if err == nil { t.Fatal("Should fail with empty slice") } - + // Test with nil public key in slice sk1, _ := NewSecretKey() pk1 := sk1.PublicKey() - + _, err = AggregatePublicKeys([]*PublicKey{pk1, nil}) if err == nil { t.Fatal("Should fail with nil public key in slice") } - + // Test with public key with nil internal emptyPk := &PublicKey{} _, err = AggregatePublicKeys([]*PublicKey{pk1, emptyPk}) @@ -438,12 +438,12 @@ func TestAggregateSignaturesEdgeCases(t *testing.T) { if err == nil { t.Fatal("Should fail with empty slice") } - + // Test with nil signature in slice sk1, _ := NewSecretKey() msg := []byte("test") sig1, _ := sk1.Sign(msg) - + _, err = AggregateSignatures([]*Signature{sig1, nil}) if err == nil { t.Fatal("Should fail with nil signature in slice") @@ -456,9 +456,9 @@ func TestMultipleAggregation(t *testing.T) { sks := make([]*SecretKey, numKeys) pks := make([]*PublicKey, numKeys) sigs := make([]*Signature, numKeys) - + msg := []byte("aggregate test message") - + for i := 0; i < numKeys; i++ { sk, err := NewSecretKey() if err != nil { @@ -468,7 +468,7 @@ func TestMultipleAggregation(t *testing.T) { pks[i] = sk.PublicKey() sigs[i], _ = sk.Sign(msg) } - + // Aggregate public keys aggPk, err := AggregatePublicKeys(pks) if err != nil { @@ -477,7 +477,7 @@ func TestMultipleAggregation(t *testing.T) { if aggPk == nil { t.Fatal("Aggregated public key should not be nil") } - + // Aggregate signatures aggSig, err := AggregateSignatures(sigs) if err != nil { @@ -486,7 +486,7 @@ func TestMultipleAggregation(t *testing.T) { if aggSig == nil { t.Fatal("Aggregated signature should not be nil") } - + // Verify aggregated signature valid := Verify(aggPk, aggSig, msg) if !valid { @@ -506,7 +506,7 @@ func BenchmarkKeyGenerationExtended(b *testing.B) { func BenchmarkSignExtended(b *testing.B) { sk, _ := NewSecretKey() msg := []byte("benchmark message") - + b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = sk.Sign(msg) @@ -528,12 +528,12 @@ func BenchmarkVerifyExtended(b *testing.B) { func BenchmarkAggregatePublicKeysExtended(b *testing.B) { numKeys := 10 pks := make([]*PublicKey, numKeys) - + for i := 0; i < numKeys; i++ { sk, _ := NewSecretKey() pks[i] = sk.PublicKey() } - + b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = AggregatePublicKeys(pks) @@ -544,14 +544,14 @@ func BenchmarkAggregateSignaturesExtended(b *testing.B) { numSigs := 10 sigs := make([]*Signature, numSigs) msg := []byte("benchmark") - + for i := 0; i < numSigs; i++ { sk, _ := NewSecretKey() sigs[i], _ = sk.Sign(msg) } - + b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = AggregateSignatures(sigs) } -} \ No newline at end of file +} diff --git a/bls/bls_test.go b/bls/bls_test.go index 832e2ae..14890f4 100644 --- a/bls/bls_test.go +++ b/bls/bls_test.go @@ -574,4 +574,4 @@ func BenchmarkAggregateSignatures(b *testing.B) { for i := 0; i < b.N; i++ { _, _ = AggregateSignatures(sigs) } -} \ No newline at end of file +} diff --git a/cache/cachetest/cacher.go b/cache/cachetest/cacher.go index 6f73098..21d9f8f 100644 --- a/cache/cachetest/cacher.go +++ b/cache/cachetest/cacher.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/require" - "github.com/luxfi/node/cache" "github.com/luxfi/ids" + "github.com/luxfi/node/cache" ) const IntSize = ids.IDLen + 8 diff --git a/cache/lru/cache_test.go b/cache/lru/cache_test.go index da1f089..ded82c9 100644 --- a/cache/lru/cache_test.go +++ b/cache/lru/cache_test.go @@ -6,8 +6,8 @@ package lru import ( "testing" - "github.com/luxfi/node/cache/cachetest" "github.com/luxfi/ids" + "github.com/luxfi/node/cache/cachetest" ) func TestCache(t *testing.T) { diff --git a/cache/lru/sized_cache_test.go b/cache/lru/sized_cache_test.go index 5e6f679..e2080a1 100644 --- a/cache/lru/sized_cache_test.go +++ b/cache/lru/sized_cache_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/require" - "github.com/luxfi/node/cache/cachetest" "github.com/luxfi/ids" + "github.com/luxfi/node/cache/cachetest" ) func TestSizedCache(t *testing.T) { diff --git a/cache/lru_cache_test.go b/cache/lru_cache_test.go index 147907c..54714f3 100644 --- a/cache/lru_cache_test.go +++ b/cache/lru_cache_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/require" + "github.com/luxfi/ids" "github.com/luxfi/node/cache" "github.com/luxfi/node/cache/cachetest" - "github.com/luxfi/ids" ) func TestLRU(t *testing.T) { diff --git a/cache/lru_sized_cache_test.go b/cache/lru_sized_cache_test.go index aa86bad..c866d04 100644 --- a/cache/lru_sized_cache_test.go +++ b/cache/lru_sized_cache_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/require" + "github.com/luxfi/ids" "github.com/luxfi/node/cache" "github.com/luxfi/node/cache/cachetest" - "github.com/luxfi/ids" ) func TestSizedLRU(t *testing.T) { diff --git a/cache/metercacher/cache_test.go b/cache/metercacher/cache_test.go index 4a3ac50..fa0c85e 100644 --- a/cache/metercacher/cache_test.go +++ b/cache/metercacher/cache_test.go @@ -17,7 +17,6 @@ import ( "github.com/luxfi/node/cache" "github.com/luxfi/node/cache/cachetest" "github.com/luxfi/node/cache/lru" - "github.com/luxfi/ids" ) func TestInterface(t *testing.T) { diff --git a/cache/metercacher/metrics.go b/cache/metercacher/metrics.go index 51345c9..68085b9 100644 --- a/cache/metercacher/metrics.go +++ b/cache/metercacher/metrics.go @@ -69,4 +69,4 @@ func newMetrics( ), } return m, nil -} \ No newline at end of file +} diff --git a/cert/cert.go b/cert/cert.go index 3cd7bca..6878cf2 100644 --- a/cert/cert.go +++ b/cert/cert.go @@ -24,7 +24,7 @@ type MLDSACert struct { KeyUsage x509.KeyUsage ExtKeyUsage []x509.ExtKeyUsage IsCA bool - + // Custom extensions for QZMQ NodeID string Capabilities []string @@ -54,34 +54,34 @@ func (cp *CertPool) VerifyChain(chain []*MLDSACert, now time.Time) error { if len(chain) == 0 { return errors.New("empty certificate chain") } - + // Verify leaf certificate leaf := chain[0] if now.Before(leaf.NotBefore) || now.After(leaf.NotAfter) { return errors.New("certificate expired or not yet valid") } - + // Verify chain for i := 0; i < len(chain)-1; i++ { cert := chain[i] issuer := chain[i+1] - + if err := verifyCertSignature(cert, issuer); err != nil { return fmt.Errorf("invalid signature at position %d: %w", i, err) } - + if !issuer.IsCA { return fmt.Errorf("issuer at position %d is not a CA", i+1) } } - + // Verify root is trusted root := chain[len(chain)-1] spkiHash := hashSPKI(root.PublicKey.Bytes()) if _, ok := cp.certs[spkiHash]; !ok { return errors.New("root certificate not trusted") } - + return nil } @@ -182,21 +182,21 @@ func (cb *CertBuilder) SetCA(isCA bool) *CertBuilder { func (cb *CertBuilder) Build(publicKey sign.PublicKey, issuerKey sign.PrivateKey) (*MLDSACert, error) { cert := *cb.template cert.PublicKey = publicKey - + // Generate serial number cert.SerialNumber = generateSerialNumber() - + // Self-signed if no issuer provided if issuerKey == nil { cert.Issuer = cert.Subject } - + // Encode to DER certBytes, err := encodeCertificate(&cert) if err != nil { return nil, err } - + // Sign the certificate if issuerKey != nil { signature, err := cb.signer.Sign(issuerKey, certBytes) @@ -208,7 +208,7 @@ func (cb *CertBuilder) Build(publicKey sign.PublicKey, issuerKey sign.PrivateKey } else { cert.Raw = certBytes } - + return &cert, nil } @@ -220,7 +220,7 @@ func encodeCertificate(cert *MLDSACert) ([]byte, error) { encoded = append(encoded, cert.PublicKey.Bytes()...) encoded = append(encoded, []byte(cert.NodeID)...) encoded = append(encoded, []byte(cert.Role)...) - + return encoded, nil } @@ -234,22 +234,22 @@ func generateSerialNumber() []byte { func ParseMLDSACert(der []byte) (*MLDSACert, error) { // Placeholder parser // In production, would parse actual DER-encoded certificate - + cert := &MLDSACert{ Raw: der, } - + // Parse basic fields (placeholder) if len(der) < 100 { return nil, errors.New("certificate too short") } - + return cert, nil } // OID definitions for ML-DSA algorithms var ( - OIDMLDSA44 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 2, 267, 7, 6, 5} // ML-DSA-44 - OIDMLDSA65 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 2, 267, 7, 8, 7} // ML-DSA-65 + OIDMLDSA44 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 2, 267, 7, 6, 5} // ML-DSA-44 + OIDMLDSA65 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 2, 267, 7, 8, 7} // ML-DSA-65 OIDMLDSA87 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 2, 267, 7, 10, 8} // ML-DSA-87 -) \ No newline at end of file +) diff --git a/cggmp21/cggmp21.go b/cggmp21/cggmp21.go index bd510f8..2ca561a 100644 --- a/cggmp21/cggmp21.go +++ b/cggmp21/cggmp21.go @@ -28,64 +28,64 @@ type Signature struct { // Config contains CGGMP21 protocol configuration type Config struct { - Threshold int // t: Threshold (t+1 parties needed to sign) - TotalParties int // n: Total number of parties + Threshold int // t: Threshold (t+1 parties needed to sign) + TotalParties int // n: Total number of parties Curve elliptic.Curve - SessionTimeout int64 // Timeout for protocol rounds + SessionTimeout int64 // Timeout for protocol rounds } // Party represents a participant in the CGGMP21 protocol type Party struct { - ID ids.NodeID - Index int - Config *Config - + ID ids.NodeID + Index int + Config *Config + // Key material - Xi *big.Int // Secret key share - PublicKey *ecdsa.PublicKey // Group public key - PublicShares map[int]*big.Int // Public key shares from all parties - + Xi *big.Int // Secret key share + PublicKey *ecdsa.PublicKey // Group public key + PublicShares map[int]*big.Int // Public key shares from all parties + // Paillier keys for ZK proofs - PaillierSK *PaillierPrivateKey - PaillierPKs map[int]*PaillierPublicKey - + PaillierSK *PaillierPrivateKey + PaillierPKs map[int]*PaillierPublicKey + // Session state - sessions map[string]*SigningSession - - log log.Logger - mu sync.RWMutex + sessions map[string]*SigningSession + + log log.Logger + mu sync.RWMutex } // SigningSession represents an active signing session type SigningSession struct { - SessionID string - Message []byte - MessageHash *big.Int - + SessionID string + Message []byte + MessageHash *big.Int + // Round 1: Commitment - Ki *big.Int // k_i (nonce share) - Gammai *big.Int // gamma_i (random mask) + Ki *big.Int // k_i (nonce share) + Gammai *big.Int // gamma_i (random mask) CommitmentSent bool - Commitments map[int][]byte // Received commitments - + Commitments map[int][]byte // Received commitments + // Round 2: Reveal - RevealsSent bool - GammaShares map[int]*big.Int // gamma_j values - BigGammaShares map[int]*ECPoint // [gamma_j]G points - + RevealsSent bool + GammaShares map[int]*big.Int // gamma_j values + BigGammaShares map[int]*ECPoint // [gamma_j]G points + // Round 3: Multiplication - DeltaShare *big.Int // delta_i = k_i * gamma_i - ChiShare *big.Int // chi_i = x_i * k_i - BigDeltaShares map[int]*ECPoint // [delta_j]G points - + DeltaShare *big.Int // delta_i = k_i * gamma_i + ChiShare *big.Int // chi_i = x_i * k_i + BigDeltaShares map[int]*ECPoint // [delta_j]G points + // Round 4: Opening - Deltas map[int]*big.Int // delta_j values - BigRx *ECPoint // R_x point - + Deltas map[int]*big.Int // delta_j values + BigRx *ECPoint // R_x point + // Final signature - R *big.Int - S *big.Int - + R *big.Int + S *big.Int + // Abort handling AbortingParties []int } @@ -100,13 +100,13 @@ func NewParty(id ids.NodeID, index int, config *Config, log log.Logger) (*Party, if index < 0 || index >= config.TotalParties { return nil, errors.New("invalid party index") } - + // Generate Paillier keypair for ZK proofs paillierSK, paillierPK, err := GeneratePaillierKeyPair(2048) if err != nil { return nil, fmt.Errorf("failed to generate Paillier keys: %w", err) } - + return &Party{ ID: id, Index: index, @@ -123,30 +123,30 @@ func NewParty(id ids.NodeID, index int, config *Config, log log.Logger) (*Party, func (p *Party) KeyGen(parties []int) error { p.mu.Lock() defer p.mu.Unlock() - + // Generate secret share xi, err := rand.Int(rand.Reader, p.Config.Curve.Params().N) if err != nil { return err } p.Xi = xi - + // Compute public key share [x_i]G Xi := ScalarBaseMult(p.Config.Curve, xi) p.PublicShares[p.Index] = Xi.X - + // In practice, this would involve communication rounds // For now, we simulate having received all shares - + // Compute group public key (would be sum of all shares) // Y = sum([x_i]G) for all i - + p.log.Info("Key generation completed", log.Stringer("partyID", p.ID), log.Int("index", p.Index), log.Int("threshold", p.Config.Threshold), ) - + return nil } @@ -154,15 +154,15 @@ func (p *Party) KeyGen(parties []int) error { func (p *Party) InitiateSign(sessionID string, message []byte) (*SigningSession, error) { p.mu.Lock() defer p.mu.Unlock() - + if _, exists := p.sessions[sessionID]; exists { return nil, errors.New("session already exists") } - + // Hash the message h := sha256.Sum256(message) messageHash := new(big.Int).SetBytes(h[:]) - + session := &SigningSession{ SessionID: sessionID, Message: message, @@ -173,9 +173,9 @@ func (p *Party) InitiateSign(sessionID string, message []byte) (*SigningSession, BigDeltaShares: make(map[int]*ECPoint), Deltas: make(map[int]*big.Int), } - + p.sessions[sessionID] = session - + return session, nil } @@ -183,16 +183,16 @@ func (p *Party) InitiateSign(sessionID string, message []byte) (*SigningSession, func (p *Party) Round1_Commitment(sessionID string) ([]byte, error) { p.mu.Lock() defer p.mu.Unlock() - + session, exists := p.sessions[sessionID] if !exists { return nil, errors.New("session not found") } - + if session.CommitmentSent { return nil, errors.New("commitment already sent") } - + // Generate k_i and gamma_i ki, err := rand.Int(rand.Reader, p.Config.Curve.Params().N) if err != nil { @@ -202,16 +202,16 @@ func (p *Party) Round1_Commitment(sessionID string) ([]byte, error) { if err != nil { return nil, err } - + session.Ki = ki session.Gammai = gammai - + // Compute commitment = H(i, [gamma_i]G) bigGammai := ScalarBaseMult(p.Config.Curve, gammai) commitment := p.computeCommitment(p.Index, bigGammai) - + session.CommitmentSent = true - + return commitment, nil } @@ -219,34 +219,34 @@ func (p *Party) Round1_Commitment(sessionID string) ([]byte, error) { func (p *Party) Round2_Reveal(sessionID string, commitments map[int][]byte) (*Round2Message, error) { p.mu.Lock() defer p.mu.Unlock() - + session, exists := p.sessions[sessionID] if !exists { return nil, errors.New("session not found") } - + if session.RevealsSent { return nil, errors.New("reveals already sent") } - + // Store commitments for idx, comm := range commitments { if idx != p.Index { session.Commitments[idx] = comm } } - + // Create reveal message bigGammai := ScalarBaseMult(p.Config.Curve, session.Gammai) - + msg := &Round2Message{ FromIndex: p.Index, BigGammaI: bigGammai, // In production, include ZK proofs here } - + session.RevealsSent = true - + return msg, nil } @@ -254,45 +254,45 @@ func (p *Party) Round2_Reveal(sessionID string, commitments map[int][]byte) (*Ro func (p *Party) Round3_Multiply(sessionID string, reveals map[int]*Round2Message) (*Round3Message, error) { p.mu.Lock() defer p.mu.Unlock() - + session, exists := p.sessions[sessionID] if !exists { return nil, errors.New("session not found") } - + // Verify commitments match reveals for idx, reveal := range reveals { if idx == p.Index { continue } - + expectedComm := p.computeCommitment(idx, reveal.BigGammaI) if !bytesEqual(expectedComm, session.Commitments[idx]) { return nil, fmt.Errorf("commitment verification failed for party %d", idx) } - + session.BigGammaShares[idx] = reveal.BigGammaI } - + // Compute delta_i = k_i * gamma_i deltai := new(big.Int).Mul(session.Ki, session.Gammai) deltai.Mod(deltai, p.Config.Curve.Params().N) session.DeltaShare = deltai - + // Compute chi_i = x_i * k_i chii := new(big.Int).Mul(p.Xi, session.Ki) chii.Mod(chii, p.Config.Curve.Params().N) session.ChiShare = chii - + // Compute [delta_i]G bigDeltai := ScalarBaseMult(p.Config.Curve, deltai) - + msg := &Round3Message{ FromIndex: p.Index, BigDeltaI: bigDeltai, // In production, include encrypted shares and ZK proofs } - + return msg, nil } @@ -300,27 +300,27 @@ func (p *Party) Round3_Multiply(sessionID string, reveals map[int]*Round2Message func (p *Party) Round4_Open(sessionID string, round3msgs map[int]*Round3Message) (*Round4Message, error) { p.mu.Lock() defer p.mu.Unlock() - + session, exists := p.sessions[sessionID] if !exists { return nil, errors.New("session not found") } - + // Store [delta_j]G values for idx, msg := range round3msgs { if idx != p.Index { session.BigDeltaShares[idx] = msg.BigDeltaI } } - + // In production, perform consistency checks and identify aborts - + msg := &Round4Message{ FromIndex: p.Index, DeltaI: session.DeltaShare, // Include proofs of correct multiplication } - + return msg, nil } @@ -328,33 +328,33 @@ func (p *Party) Round4_Open(sessionID string, round3msgs map[int]*Round3Message) func (p *Party) Finalize(sessionID string, round4msgs map[int]*Round4Message) (*Signature, error) { p.mu.Lock() defer p.mu.Unlock() - + session, exists := p.sessions[sessionID] if !exists { return nil, errors.New("session not found") } - + // Store delta values for idx, msg := range round4msgs { session.Deltas[idx] = msg.DeltaI } - + // Compute R = product([k_j * gamma_j]G) for all j // In practice, this involves point multiplication - + // For now, simulate signature computation r := new(big.Int).SetBytes([]byte("simulated_r_value")) - + // Compute s_i (partial signature) // s_i = m * chi_i + r * sigma_i // where sigma_i is the lagrange-adjusted share - + s := new(big.Int).SetBytes([]byte("simulated_s_value")) - + // Store final signature session.R = r session.S = s - + return &Signature{ R: r, S: s, @@ -419,4 +419,4 @@ type IdentifiableAbort struct { func VerifySignature(pubKey *ecdsa.PublicKey, message []byte, sig *Signature) bool { h := sha256.Sum256(message) return ecdsa.Verify(pubKey, h[:], sig.R, sig.S) -} \ No newline at end of file +} diff --git a/cggmp21/paillier.go b/cggmp21/paillier.go index fa4808b..e2ac166 100644 --- a/cggmp21/paillier.go +++ b/cggmp21/paillier.go @@ -11,9 +11,9 @@ import ( // PaillierPublicKey represents a Paillier public key type PaillierPublicKey struct { - N *big.Int // n = p*q - NSq *big.Int // n^2 - G *big.Int // generator (typically n+1) + N *big.Int // n = p*q + NSq *big.Int // n^2 + G *big.Int // generator (typically n+1) } // PaillierPrivateKey represents a Paillier private key @@ -32,43 +32,43 @@ func GeneratePaillierKeyPair(bits int) (*PaillierPrivateKey, *PaillierPublicKey, if err != nil { return nil, nil, err } - + q, err := rand.Prime(rand.Reader, bits/2) if err != nil { return nil, nil, err } - + // Compute n = p*q n := new(big.Int).Mul(p, q) nSq := new(big.Int).Mul(n, n) - + // Compute lambda = lcm(p-1, q-1) pMinus1 := new(big.Int).Sub(p, big.NewInt(1)) qMinus1 := new(big.Int).Sub(q, big.NewInt(1)) - + gcd := new(big.Int).GCD(nil, nil, pMinus1, qMinus1) lambda := new(big.Int).Mul(pMinus1, qMinus1) lambda.Div(lambda, gcd) - + // Set g = n+1 (standard choice) g := new(big.Int).Add(n, big.NewInt(1)) - + // Compute mu = (L(g^lambda mod n^2))^(-1) mod n // where L(x) = (x-1)/n gLambda := new(big.Int).Exp(g, lambda, nSq) l := L(gLambda, n) mu := new(big.Int).ModInverse(l, n) - + if mu == nil { return nil, nil, errors.New("failed to compute modular inverse") } - + pubKey := &PaillierPublicKey{ N: n, NSq: nSq, G: g, } - + privKey := &PaillierPrivateKey{ PublicKey: pubKey, Lambda: lambda, @@ -76,7 +76,7 @@ func GeneratePaillierKeyPair(bits int) (*PaillierPrivateKey, *PaillierPublicKey, P: p, Q: q, } - + return privKey, pubKey, nil } @@ -86,7 +86,7 @@ func (pub *PaillierPublicKey) Encrypt(plaintext *big.Int) (*big.Int, error) { if plaintext.Cmp(pub.N) >= 0 || plaintext.Sign() < 0 { return nil, errors.New("plaintext out of range") } - + // Generate random r where gcd(r, n) = 1 var r *big.Int for { @@ -95,14 +95,14 @@ func (pub *PaillierPublicKey) Encrypt(plaintext *big.Int) (*big.Int, error) { break } } - + // Compute ciphertext = g^m * r^n mod n^2 gm := new(big.Int).Exp(pub.G, plaintext, pub.NSq) rn := new(big.Int).Exp(r, pub.N, pub.NSq) - + ciphertext := new(big.Int).Mul(gm, rn) ciphertext.Mod(ciphertext, pub.NSq) - + return ciphertext, nil } @@ -112,14 +112,14 @@ func (priv *PaillierPrivateKey) Decrypt(ciphertext *big.Int) (*big.Int, error) { if ciphertext.Cmp(priv.PublicKey.NSq) >= 0 || ciphertext.Sign() <= 0 { return nil, errors.New("ciphertext out of range") } - + // Compute plaintext = L(c^lambda mod n^2) * mu mod n cLambda := new(big.Int).Exp(ciphertext, priv.Lambda, priv.PublicKey.NSq) l := L(cLambda, priv.PublicKey.N) - + plaintext := new(big.Int).Mul(l, priv.Mu) plaintext.Mod(plaintext, priv.PublicKey.N) - + return plaintext, nil } @@ -154,26 +154,26 @@ type ZKProof struct { func ProveKnowledge(pub *PaillierPublicKey, plaintext, randomness *big.Int) (*ZKProof, error) { // This is a simplified Schnorr-like proof // In production, use proper ZK proofs as specified in CGGMP21 - + // Generate random values r1, _ := rand.Int(rand.Reader, pub.N) r2, _ := rand.Int(rand.Reader, pub.N) - + // Compute commitment e = g^r1 * r2^n mod n^2 gr1 := new(big.Int).Exp(pub.G, r1, pub.NSq) r2n := new(big.Int).Exp(r2, pub.N, pub.NSq) e := new(big.Int).Mul(gr1, r2n) e.Mod(e, pub.NSq) - + // Compute challenge (in practice, use Fiat-Shamir) challenge := new(big.Int).SetBytes([]byte("challenge")) challenge.Mod(challenge, pub.N) - + // Compute response z = r1 + challenge * plaintext z := new(big.Int).Mul(challenge, plaintext) z.Add(z, r1) z.Mod(z, pub.N) - + return &ZKProof{ E: e, Z: z, @@ -185,17 +185,17 @@ func ProveKnowledge(pub *PaillierPublicKey, plaintext, randomness *big.Int) (*ZK func VerifyKnowledge(proof *ZKProof, ciphertext *big.Int) bool { // Simplified verification // In production, implement full verification as per CGGMP21 - + // Recompute challenge challenge := new(big.Int).SetBytes([]byte("challenge")) challenge.Mod(challenge, proof.Pub.N) - + // Verify: g^z = e * c^challenge mod n^2 gz := new(big.Int).Exp(proof.Pub.G, proof.Z, proof.Pub.NSq) - + cc := new(big.Int).Exp(ciphertext, challenge, proof.Pub.NSq) ec := new(big.Int).Mul(proof.E, cc) ec.Mod(ec, proof.Pub.NSq) - + return gz.Cmp(ec) == 0 -} \ No newline at end of file +} diff --git a/common/hash.go b/common/hash.go index cfe223c..312323d 100644 --- a/common/hash.go +++ b/common/hash.go @@ -33,14 +33,14 @@ func DeriveKey(seed []byte, label string, outputLen int) []byte { h.Write(seed) h.Write([]byte(label)) baseHash := h.Sum(nil) - + output := make([]byte, outputLen) for i := 0; i < outputLen; i += len(baseHash) { h.Reset() h.Write(baseHash) h.Write([]byte{byte(i / len(baseHash))}) chunk := h.Sum(nil) - + end := i + len(baseHash) if end > outputLen { end = outputLen @@ -48,7 +48,7 @@ func DeriveKey(seed []byte, label string, outputLen int) []byte { copy(output[i:end], chunk) baseHash = chunk } - + return output } @@ -58,7 +58,7 @@ func XOF(seed []byte, outputLen int) []byte { h := sha256.New() h.Write(seed) hash := h.Sum(nil) - + for i := 0; i < outputLen; i += len(hash) { end := i + len(hash) if end > outputLen { @@ -71,7 +71,7 @@ func XOF(seed []byte, outputLen int) []byte { hash = h.Sum(nil) } } - + return output } @@ -80,7 +80,7 @@ func SecureCompare(a, b []byte) bool { if len(a) != len(b) { return false } - + var result byte for i := range a { result |= a[i] ^ b[i] @@ -93,4 +93,4 @@ func ClearBytes(b []byte) { for i := range b { b[i] = 0 } -} \ No newline at end of file +} diff --git a/common/utils.go b/common/utils.go index 90c1f04..9296880 100644 --- a/common/utils.go +++ b/common/utils.go @@ -27,12 +27,12 @@ func GenerateRandomBytes(rand io.Reader, size int) ([]byte, error) { if err := ValidateRandomSource(rand); err != nil { return nil, err } - + bytes := make([]byte, size) if _, err := io.ReadFull(rand, bytes); err != nil { return nil, err } - + return bytes, nil } @@ -49,7 +49,7 @@ func AllocateCombined(sizes ...int) []byte { func SplitBuffer(buffer []byte, sizes ...int) [][]byte { segments := make([][]byte, len(sizes)) offset := 0 - + for i, size := range sizes { if offset+size > len(buffer) { panic("buffer too small for requested segments") @@ -57,7 +57,7 @@ func SplitBuffer(buffer []byte, sizes ...int) [][]byte { segments[i] = buffer[offset : offset+size] offset += size } - + return segments } @@ -76,7 +76,7 @@ func ConstantTimeSelect(v int, a, b []byte) []byte { if len(a) != len(b) { panic("slices must have equal length") } - + result := make([]byte, len(a)) for i := range result { result[i] = byte(v)*a[i] + byte(1-v)*b[i] @@ -116,7 +116,7 @@ func FillRandomBytes(rand io.Reader, buf []byte) error { if err := ValidateRandomSource(rand); err != nil { return err } - + _, err := io.ReadFull(rand, buf) return err } @@ -135,4 +135,4 @@ func Max(a, b int) int { return a } return b -} \ No newline at end of file +} diff --git a/comprehensive_pq_test.go b/comprehensive_pq_test.go index 49753c0..2791b5f 100644 --- a/comprehensive_pq_test.go +++ b/comprehensive_pq_test.go @@ -4,7 +4,7 @@ import ( "bytes" "crypto/rand" "testing" - + "github.com/luxfi/crypto/mldsa" "github.com/luxfi/crypto/mlkem" "github.com/luxfi/crypto/slhdsa" @@ -21,61 +21,61 @@ func TestPQCrypto96Coverage(t *testing.T) { func testMLDSAComprehensive(t *testing.T) { modes := []mldsa.Mode{mldsa.MLDSA44, mldsa.MLDSA65, mldsa.MLDSA87} - + for _, mode := range modes { // Generate key priv, err := mldsa.GenerateKey(rand.Reader, mode) if err != nil { t.Fatalf("MLDSA GenerateKey failed: %v", err) } - + // Sign message msg := []byte("Test message for 96% coverage") sig, err := priv.Sign(rand.Reader, msg, nil) if err != nil { t.Fatalf("MLDSA Sign failed: %v", err) } - + // Verify signature valid := priv.PublicKey.Verify(msg, sig, nil) if !valid { t.Fatal("MLDSA valid signature rejected") } - + // Test wrong message wrongMsg := []byte("Wrong") valid = priv.PublicKey.Verify(wrongMsg, sig, nil) if valid { t.Fatal("MLDSA invalid signature accepted") } - + // Test serialization privBytes := priv.Bytes() pubBytes := priv.PublicKey.Bytes() - + // Test deserialization privRestored, err := mldsa.PrivateKeyFromBytes(privBytes, mode) if err != nil { t.Fatalf("MLDSA PrivateKeyFromBytes failed: %v", err) } - + pubRestored, err := mldsa.PublicKeyFromBytes(pubBytes, mode) if err != nil { t.Fatalf("MLDSA PublicKeyFromBytes failed: %v", err) } - + // Test restored keys sig2, err := privRestored.Sign(rand.Reader, msg, nil) if err != nil { t.Fatal("MLDSA restored key sign failed") } - + valid = pubRestored.Verify(msg, sig2, nil) if !valid { t.Fatal("MLDSA restored key verify failed") } } - + // Edge cases testMLDSAEdgeCases(t) } @@ -86,37 +86,37 @@ func testMLDSAEdgeCases(t *testing.T) { if err == nil { t.Fatal("Expected error for invalid MLDSA mode") } - + // Nil private key var nilPriv *mldsa.PrivateKey _, err = nilPriv.Sign(rand.Reader, []byte("test"), nil) if err == nil { t.Fatal("Expected error for nil MLDSA private key") } - + // Wrong size deserialization _, err = mldsa.PrivateKeyFromBytes([]byte("short"), mldsa.MLDSA44) if err == nil { t.Fatal("Expected error for wrong size MLDSA private key") } - + _, err = mldsa.PublicKeyFromBytes([]byte("short"), mldsa.MLDSA44) if err == nil { t.Fatal("Expected error for wrong size MLDSA public key") } - + // Empty message priv, _ := mldsa.GenerateKey(rand.Reader, mldsa.MLDSA44) sig, err := priv.Sign(rand.Reader, []byte{}, nil) if err != nil { t.Fatal("MLDSA failed to sign empty message") } - + valid := priv.PublicKey.Verify([]byte{}, sig, nil) if !valid { t.Fatal("MLDSA empty message verification failed") } - + // Large message largeMsg := make([]byte, 10000) rand.Read(largeMsg) @@ -124,7 +124,7 @@ func testMLDSAEdgeCases(t *testing.T) { if err != nil { t.Fatal("MLDSA failed to sign large message") } - + valid = priv.PublicKey.Verify(largeMsg, sig, nil) if !valid { t.Fatal("MLDSA large message verification failed") @@ -133,14 +133,14 @@ func testMLDSAEdgeCases(t *testing.T) { func testMLKEMComprehensive(t *testing.T) { modes := []mlkem.Mode{mlkem.MLKEM512, mlkem.MLKEM768, mlkem.MLKEM1024} - + for _, mode := range modes { // Generate key pair priv, pub, err := mlkem.GenerateKeyPair(rand.Reader, mode) if err != nil { t.Fatalf("MLKEM GenerateKeyPair failed: %v", err) } - + // Encapsulate result, err := pub.Encapsulate(rand.Reader) if err != nil { @@ -152,33 +152,33 @@ func testMLKEMComprehensive(t *testing.T) { if err != nil { t.Fatalf("MLKEM Decapsulate failed: %v", err) } - + // Verify shared secrets match if !bytes.Equal(result.SharedSecret, ss2) { t.Fatal("MLKEM shared secrets don't match") } - + // Test serialization privBytes := priv.Bytes() pubBytes := pub.Bytes() - + // Test deserialization privRestored, err := mlkem.PrivateKeyFromBytes(privBytes, mode) if err != nil { t.Fatalf("MLKEM PrivateKeyFromBytes failed: %v", err) } - + pubRestored, err := mlkem.PublicKeyFromBytes(pubBytes, mode) if err != nil { t.Fatalf("MLKEM PublicKeyFromBytes failed: %v", err) } - + // Test restored keys result2, err := pubRestored.Encapsulate(rand.Reader) if err != nil { t.Fatal("MLKEM restored key encapsulate failed") } - + ss4, err := privRestored.Decapsulate(result2.Ciphertext) if err != nil { t.Fatal("MLKEM restored key decapsulate failed") @@ -187,7 +187,7 @@ func testMLKEMComprehensive(t *testing.T) { if !bytes.Equal(result2.SharedSecret, ss4) { t.Fatal("MLKEM restored keys produce different shared secrets") } - + // Test wrong ciphertext (should produce pseudorandom) wrongCt := make([]byte, len(result.Ciphertext)) rand.Read(wrongCt) @@ -195,13 +195,13 @@ func testMLKEMComprehensive(t *testing.T) { if err != nil { t.Fatal("MLKEM decapsulate wrong ct failed") } - + // Should be different (pseudorandom) if bytes.Equal(result.SharedSecret, ssWrong) { t.Fatal("MLKEM wrong ct produced same shared secret") } } - + // Edge cases testMLKEMEdgeCases(t) } @@ -212,38 +212,38 @@ func testMLKEMEdgeCases(t *testing.T) { if err == nil { t.Fatal("Expected error for invalid MLKEM mode") } - + // Nil keys var nilPriv *mlkem.PrivateKey _, err = nilPriv.Decapsulate([]byte("test")) if err == nil { t.Fatal("Expected error for nil MLKEM private key") } - + var nilPub *mlkem.PublicKey _, err = nilPub.Encapsulate(rand.Reader) if err == nil { t.Fatal("Expected error for nil MLKEM public key") } - + // Wrong size deserialization _, err = mlkem.PrivateKeyFromBytes([]byte("short"), mlkem.MLKEM512) if err == nil { t.Fatal("Expected error for wrong size MLKEM private key") } - + _, err = mlkem.PublicKeyFromBytes([]byte("short"), mlkem.MLKEM512) if err == nil { t.Fatal("Expected error for wrong size MLKEM public key") } - + // Wrong size ciphertext priv, _, _ := mlkem.GenerateKeyPair(rand.Reader, mlkem.MLKEM512) _, err = priv.Decapsulate([]byte("short")) if err == nil { t.Fatal("Expected error for wrong size MLKEM ciphertext") } - + // Multiple encapsulations _, pub, _ := mlkem.GenerateKeyPair(rand.Reader, mlkem.MLKEM768) result1, _ := pub.Encapsulate(rand.Reader) @@ -261,61 +261,61 @@ func testMLKEMEdgeCases(t *testing.T) { func testSLHDSAComprehensive(t *testing.T) { // Note: SLH-DSA is computationally expensive, testing only 128s for quick validation modes := []slhdsa.Mode{slhdsa.SLHDSA128s} - + for _, mode := range modes { // Generate key priv, err := slhdsa.GenerateKey(rand.Reader, mode) if err != nil { t.Fatalf("SLHDSA GenerateKey failed: %v", err) } - + // Sign message msg := []byte("Test message for 96% coverage") sig, err := priv.Sign(rand.Reader, msg, nil) if err != nil { t.Fatalf("SLHDSA Sign failed: %v", err) } - + // Verify signature valid := priv.PublicKey.Verify(msg, sig, nil) if !valid { t.Fatal("SLHDSA valid signature rejected") } - + // Test wrong message wrongMsg := []byte("Wrong") valid = priv.PublicKey.Verify(wrongMsg, sig, nil) if valid { t.Fatal("SLHDSA invalid signature accepted") } - + // Test serialization privBytes := priv.Bytes() pubBytes := priv.PublicKey.Bytes() - + // Test deserialization privRestored, err := slhdsa.PrivateKeyFromBytes(privBytes, mode) if err != nil { t.Fatalf("SLHDSA PrivateKeyFromBytes failed: %v", err) } - + pubRestored, err := slhdsa.PublicKeyFromBytes(pubBytes, mode) if err != nil { t.Fatalf("SLHDSA PublicKeyFromBytes failed: %v", err) } - + // Test restored keys sig2, err := privRestored.Sign(rand.Reader, msg, nil) if err != nil { t.Fatal("SLHDSA restored key sign failed") } - + valid = pubRestored.Verify(msg, sig2, nil) if !valid { t.Fatal("SLHDSA restored key verify failed") } } - + // Edge cases testSLHDSAEdgeCases(t) } @@ -326,32 +326,32 @@ func testSLHDSAEdgeCases(t *testing.T) { if err == nil { t.Fatal("Expected error for invalid SLHDSA mode") } - + // Nil private key var nilPriv *slhdsa.PrivateKey _, err = nilPriv.Sign(rand.Reader, []byte("test"), nil) if err == nil { t.Fatal("Expected error for nil SLHDSA private key") } - + // Wrong size deserialization _, err = slhdsa.PrivateKeyFromBytes([]byte("short"), slhdsa.SLHDSA128s) if err == nil { t.Fatal("Expected error for wrong size SLHDSA private key") } - + _, err = slhdsa.PublicKeyFromBytes([]byte("short"), slhdsa.SLHDSA128s) if err == nil { t.Fatal("Expected error for wrong size SLHDSA public key") } - + // Empty message priv, _ := slhdsa.GenerateKey(rand.Reader, slhdsa.SLHDSA128s) sig, err := priv.Sign(rand.Reader, []byte{}, nil) if err != nil { t.Fatal("SLHDSA failed to sign empty message") } - + valid := priv.PublicKey.Verify([]byte{}, sig, nil) if !valid { t.Fatal("SLHDSA empty message verification failed") @@ -362,30 +362,30 @@ func testIntegration(t *testing.T) { // Test ML-DSA + ML-KEM combination mldsaPriv, _ := mldsa.GenerateKey(rand.Reader, mldsa.MLDSA44) mlkemPriv, mlkemPub, _ := mlkem.GenerateKeyPair(rand.Reader, mlkem.MLKEM512) - + // Sign with ML-DSA msg := []byte("Integration test") sig, _ := mldsaPriv.Sign(rand.Reader, msg, nil) - + // Encapsulate with ML-KEM result, _ := mlkemPub.Encapsulate(rand.Reader) - + // Verify signature valid := mldsaPriv.PublicKey.Verify(msg, sig, nil) if !valid { t.Fatal("Integration: MLDSA verification failed") } - + // Decapsulate ss2, _ := mlkemPriv.Decapsulate(result.Ciphertext) if !bytes.Equal(result.SharedSecret, ss2) { t.Fatal("Integration: MLKEM shared secrets don't match") } - + // Test all three together slhdsaPriv, _ := slhdsa.GenerateKey(rand.Reader, slhdsa.SLHDSA128s) slhdsaSig, _ := slhdsaPriv.Sign(rand.Reader, msg, nil) - + valid = slhdsaPriv.PublicKey.Verify(msg, slhdsaSig, nil) if !valid { t.Fatal("Integration: SLHDSA verification failed") @@ -394,46 +394,46 @@ func testIntegration(t *testing.T) { func testHybrid(t *testing.T) { // Test hybrid mode: classical + PQ - + // Classical ECDSA classicalPriv, err := GenerateKey() if err != nil { t.Fatal("Classical key generation failed") } - + // PQ ML-DSA pqPriv, err := mldsa.GenerateKey(rand.Reader, mldsa.MLDSA44) if err != nil { t.Fatal("PQ key generation failed") } - + msg := []byte("Hybrid signature test") - + // Classical signature hash := Keccak256Hash(msg) classicalSig, err := Sign(hash.Bytes(), classicalPriv) if err != nil { t.Fatal("Classical signing failed") } - + // PQ signature pqSig, err := pqPriv.Sign(rand.Reader, msg, nil) if err != nil { t.Fatal("PQ signing failed") } - + // Verify both classicalPub := FromECDSAPub(&classicalPriv.PublicKey) valid := VerifySignature(classicalPub, hash.Bytes(), classicalSig[:64]) if !valid { t.Fatal("Classical signature verification failed") } - + valid = pqPriv.PublicKey.Verify(msg, pqSig, nil) if !valid { t.Fatal("PQ signature verification failed") } - + // Combine signatures (hybrid) hybridSig := append(classicalSig, pqSig...) if len(hybridSig) < len(classicalSig)+len(pqSig) { @@ -451,7 +451,7 @@ func BenchmarkPQOperations96Coverage(b *testing.B) { priv.Sign(rand.Reader, msg, nil) } }) - + b.Run("MLKEM768-Encapsulate", func(b *testing.B) { _, pub, _ := mlkem.GenerateKeyPair(rand.Reader, mlkem.MLKEM768) b.ResetTimer() @@ -459,7 +459,7 @@ func BenchmarkPQOperations96Coverage(b *testing.B) { pub.Encapsulate(rand.Reader) } }) - + b.Run("SLHDSA128s-Sign", func(b *testing.B) { priv, _ := slhdsa.GenerateKey(rand.Reader, slhdsa.SLHDSA128s) msg := make([]byte, 32) @@ -468,4 +468,4 @@ func BenchmarkPQOperations96Coverage(b *testing.B) { priv.Sign(rand.Reader, msg, nil) } }) -} \ No newline at end of file +} diff --git a/corona/corona.go b/corona/corona.go index e43c6c8..82c7e45 100644 --- a/corona/corona.go +++ b/corona/corona.go @@ -21,10 +21,10 @@ const ( ) var ( - errInvalidRingSize = errors.New("invalid ring size") - errInvalidPublicKey = errors.New("invalid public key") - errInvalidSignature = errors.New("invalid signature") - errRingNotComplete = errors.New("ring is not complete") + errInvalidRingSize = errors.New("invalid ring size") + errInvalidPublicKey = errors.New("invalid public key") + errInvalidSignature = errors.New("invalid signature") + errRingNotComplete = errors.New("ring is not complete") ) // PublicKey represents a Corona public key @@ -44,9 +44,9 @@ type Point struct { // RingSignature represents a Corona ring signature type RingSignature struct { - C0 *big.Int - S []*big.Int - KeyImage *Point + C0 *big.Int + S []*big.Int + KeyImage *Point RingPubKeys []*PublicKey } @@ -59,7 +59,7 @@ func (*Factory) NewPrivateKey() (*PrivateKey, error) { if err != nil { return nil, err } - + return &PrivateKey{Scalar: scalar}, nil } @@ -68,7 +68,7 @@ func (*Factory) ToPublicKey(privKey *PrivateKey) (*PublicKey, error) { if privKey == nil { return nil, errors.New("nil private key") } - + point := scalarBaseMult(privKey.Scalar) return &PublicKey{Point: point}, nil } @@ -78,7 +78,7 @@ func (priv *PrivateKey) Sign(message []byte, ring []*PublicKey) (*RingSignature, if len(ring) != DefaultRingSize { return nil, errInvalidRingSize } - + // Find the signer's position in the ring pubKey := priv.PublicKey() signerIndex := -1 @@ -88,40 +88,40 @@ func (priv *PrivateKey) Sign(message []byte, ring []*PublicKey) (*RingSignature, break } } - + if signerIndex == -1 { return nil, errors.New("signer's public key not found in ring") } - + // Generate key image keyImage := generateKeyImage(priv) - + // Initialize signature components c := make([]*big.Int, DefaultRingSize) s := make([]*big.Int, DefaultRingSize) - + // Generate random responses for all except signer for i := 0; i < DefaultRingSize; i++ { if i != signerIndex { s[i], _ = rand.Int(rand.Reader, curveOrder()) } } - + // Start the ring computation // Generate random nonce k, _ := rand.Int(rand.Reader, curveOrder()) - + // Compute L_i and R_i for all ring members L := make([]*Point, DefaultRingSize) R := make([]*Point, DefaultRingSize) - + // For the signer L[signerIndex] = scalarBaseMult(k) R[signerIndex] = scalarMult(hashToPoint(ring[signerIndex].Point), k) - + // Compute c_{i+1} starting from signer c[(signerIndex+1)%DefaultRingSize] = hashPoints(message, L[signerIndex], R[signerIndex]) - + // Complete the ring for i := (signerIndex + 1) % DefaultRingSize; i != signerIndex; i = (i + 1) % DefaultRingSize { L[i] = addPoints( @@ -132,14 +132,14 @@ func (priv *PrivateKey) Sign(message []byte, ring []*PublicKey) (*RingSignature, scalarMult(hashToPoint(ring[i].Point), s[i]), scalarMult(keyImage, c[i]), ) - + c[(i+1)%DefaultRingSize] = hashPoints(message, L[i], R[i]) } - + // Complete the signature for the signer s[signerIndex] = new(big.Int).Sub(k, new(big.Int).Mul(c[signerIndex], priv.Scalar)) s[signerIndex].Mod(s[signerIndex], curveOrder()) - + return &RingSignature{ C0: c[0], S: s, @@ -153,24 +153,24 @@ func (sig *RingSignature) Verify(message []byte) bool { if len(sig.S) != DefaultRingSize || len(sig.RingPubKeys) != DefaultRingSize { return false } - + // Recompute c values c := make([]*big.Int, DefaultRingSize) c[0] = sig.C0 - + for i := 0; i < DefaultRingSize; i++ { // Compute L_i = s_i * G + c_i * P_i L := addPoints( scalarBaseMult(sig.S[i]), scalarMult(sig.RingPubKeys[i].Point, c[i]), ) - + // Compute R_i = s_i * H(P_i) + c_i * I R := addPoints( scalarMult(hashToPoint(sig.RingPubKeys[i].Point), sig.S[i]), scalarMult(sig.KeyImage, c[i]), ) - + // Compute next c value if i < DefaultRingSize-1 { c[i+1] = hashPoints(message, L, R) @@ -180,7 +180,7 @@ func (sig *RingSignature) Verify(message []byte) bool { return computedC0.Cmp(sig.C0) == 0 } } - + return false } @@ -261,4 +261,4 @@ func generateKeyImage(priv *PrivateKey) *Point { pubKey := priv.PublicKey() hashedPoint := hashToPoint(pubKey.Point) return scalarMult(hashedPoint, priv.Scalar) -} \ No newline at end of file +} diff --git a/encryption/age.go b/encryption/age.go index 74dfe09..4d891ec 100644 --- a/encryption/age.go +++ b/encryption/age.go @@ -83,4 +83,4 @@ func DecryptFile(encryptedPath string, password string) ([]byte, error) { } return DecryptPrivateKeyWithPassword(data, password) -} \ No newline at end of file +} diff --git a/encryption/encryption_test.go b/encryption/encryption_test.go index d100b50..75f0539 100644 --- a/encryption/encryption_test.go +++ b/encryption/encryption_test.go @@ -119,7 +119,7 @@ func TestAgeEncryption(t *testing.T) { // Test empty data t.Run("EmptyData", func(t *testing.T) { password := "test-password" - + // Encrypt empty data encrypted, err := EncryptDataWithPassword([]byte{}, password) if err != nil { @@ -201,4 +201,4 @@ func BenchmarkIsAgeEncrypted(b *testing.B) { IsAgeEncrypted(encrypted) IsAgeEncrypted(plain) } -} \ No newline at end of file +} diff --git a/hashing/blake3/blake3.go b/hashing/blake3/blake3.go index 00bed2e..371ec00 100644 --- a/hashing/blake3/blake3.go +++ b/hashing/blake3/blake3.go @@ -118,4 +118,4 @@ func HashWithDomain(domain string, data []byte) Digest { h := NewWithDomain(domain) h.Write(data) return h.Digest() -} \ No newline at end of file +} diff --git a/hashing/blake3/blake3_test.go b/hashing/blake3/blake3_test.go index 1c5cac3..8d6b1c9 100644 --- a/hashing/blake3/blake3_test.go +++ b/hashing/blake3/blake3_test.go @@ -22,23 +22,23 @@ func TestNewWithDomain(t *testing.T) { domain := "test-domain" h1 := NewWithDomain(domain) h2 := NewWithDomain(domain) - + data := []byte("test data") h1.Write(data) h2.Write(data) - + d1 := h1.Digest() d2 := h2.Digest() - + if !bytes.Equal(d1[:], d2[:]) { t.Error("Same domain should produce same hash") } - + // Different domain should produce different hash h3 := NewWithDomain("different-domain") h3.Write(data) d3 := h3.Digest() - + if bytes.Equal(d1[:], d3[:]) { t.Error("Different domain should produce different hash") } @@ -59,7 +59,7 @@ func TestHashBytes(t *testing.T) { "ea8f163db38682925e4491c5e58d4bb3506ef8c14eb78a86e908c5624a67200fe992405f0d785b599a2e3387f6d34d01faccfeb22fb697ef3fd53541241a338c", }, } - + for _, tc := range testCases { hash := HashBytes(tc.input) hashStr := hex.EncodeToString(hash[:]) @@ -67,12 +67,12 @@ func TestHashBytes(t *testing.T) { t.Errorf("HashBytes(%q) = %s, want %s", tc.input, hashStr, tc.expected) } } - + // Test consistency data := []byte("test data") h1 := HashBytes(data) h2 := HashBytes(data) - + if !bytes.Equal(h1[:], h2[:]) { t.Error("Same input should produce same hash") } @@ -83,17 +83,17 @@ func TestHashString(t *testing.T) { s := "test string" h1 := HashString(s) h2 := HashString(s) - + if !bytes.Equal(h1[:], h2[:]) { t.Error("Same string should produce same hash") } - + // Compare with HashBytes h3 := HashBytes([]byte(s)) if !bytes.Equal(h1[:], h3[:]) { t.Error("HashString should match HashBytes for same content") } - + // Different strings produce different hashes h4 := HashString("different string") if bytes.Equal(h1[:], h4[:]) { @@ -105,21 +105,21 @@ func TestHashWithDomain(t *testing.T) { data := []byte("test data") domain1 := "domain1" domain2 := "domain2" - + h1 := HashWithDomain(domain1, data) h2 := HashWithDomain(domain1, data) h3 := HashWithDomain(domain2, data) - + // Same domain and data should produce same hash if !bytes.Equal(h1[:], h2[:]) { t.Error("Same domain and data should produce same hash") } - + // Different domain should produce different hash if bytes.Equal(h1[:], h3[:]) { t.Error("Different domain should produce different hash") } - + // Should differ from hash without domain h4 := HashBytes(data) if bytes.Equal(h1[:], h4[:]) { @@ -129,7 +129,7 @@ func TestHashWithDomain(t *testing.T) { func TestWriteMethods(t *testing.T) { h := New() - + // Test Write n, err := h.Write([]byte("test")) if err != nil { @@ -138,7 +138,7 @@ func TestWriteMethods(t *testing.T) { if n != 4 { t.Errorf("Write returned %d, want 4", n) } - + // Test WriteString n, err = h.WriteString("string") if err != nil { @@ -147,20 +147,20 @@ func TestWriteMethods(t *testing.T) { if n != 6 { t.Errorf("WriteString returned %d, want 6", n) } - + // Test WriteUint32 h.WriteUint32(0x12345678) - + // Test WriteUint64 h.WriteUint64(0x123456789ABCDEF0) - + // Test WriteBigInt bigNum := big.NewInt(1234567890) h.WriteBigInt(bigNum) - + // Test WriteBigInt with nil h.WriteBigInt(nil) - + // Get digest to ensure it doesn't panic _ = h.Digest() } @@ -169,12 +169,12 @@ func TestWriteUint32(t *testing.T) { h1 := New() h1.WriteUint32(0x12345678) d1 := h1.Digest() - + // Should be same as writing the bytes in big-endian h2 := New() h2.Write([]byte{0x12, 0x34, 0x56, 0x78}) d2 := h2.Digest() - + if !bytes.Equal(d1[:], d2[:]) { t.Error("WriteUint32 should write in big-endian format") } @@ -184,12 +184,12 @@ func TestWriteUint64(t *testing.T) { h1 := New() h1.WriteUint64(0x123456789ABCDEF0) d1 := h1.Digest() - + // Should be same as writing the bytes in big-endian h2 := New() h2.Write([]byte{0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}) d2 := h2.Digest() - + if !bytes.Equal(d1[:], d2[:]) { t.Error("WriteUint64 should write in big-endian format") } @@ -201,30 +201,30 @@ func TestWriteBigInt(t *testing.T) { h1 := New() h1.WriteBigInt(n) d1 := h1.Digest() - + // Writing same number should produce same hash h2 := New() h2.WriteBigInt(n) d2 := h2.Digest() - + if !bytes.Equal(d1[:], d2[:]) { t.Error("Same big.Int should produce same hash") } - + // Test with nil h3 := New() h3.WriteBigInt(nil) d3 := h3.Digest() - + // Nil should write a zero length prefix h4 := New() h4.WriteUint32(0) d4 := h4.Digest() - + if !bytes.Equal(d3[:], d4[:]) { t.Error("WriteBigInt(nil) should write zero length") } - + // Test with zero zero := big.NewInt(0) h5 := New() @@ -235,13 +235,13 @@ func TestWriteBigInt(t *testing.T) { func TestSum(t *testing.T) { h := New() h.WriteString("test") - + // Sum with nil sum1 := h.Sum(nil) if len(sum1) != 32 { // Default blake3 output t.Errorf("Sum(nil) length = %d, want 32", len(sum1)) } - + // Sum with existing slice prefix := []byte("prefix") sum2 := h.Sum(prefix) @@ -257,16 +257,16 @@ func TestDigest(t *testing.T) { h := New() h.WriteString("test") d := h.Digest() - + if len(d) != DigestLength { t.Errorf("Digest length = %d, want %d", len(d), DigestLength) } - + // Digest should be consistent h2 := New() h2.WriteString("test") d2 := h2.Digest() - + if !bytes.Equal(d[:], d2[:]) { t.Error("Same input should produce same digest") } @@ -275,12 +275,12 @@ func TestDigest(t *testing.T) { func TestReader(t *testing.T) { h := New() h.WriteString("test") - + reader := h.Reader() if reader == nil { t.Fatal("Reader() returned nil") } - + // Read some bytes buf := make([]byte, 100) n, err := reader.Read(buf) @@ -295,25 +295,25 @@ func TestReader(t *testing.T) { func TestClone(t *testing.T) { h1 := New() h1.WriteString("test") - + h2 := h1.Clone() if h2 == nil { t.Fatal("Clone() returned nil") } - + // Both should produce same digest at this point d1 := h1.Digest() d2 := h2.Digest() - + if !bytes.Equal(d1[:], d2[:]) { t.Error("Clone should produce same digest") } - + // Writing to one shouldn't affect the other h1.WriteString("more") d1New := h1.Digest() d2New := h2.Digest() - + if bytes.Equal(d1New[:], d2New[:]) { t.Error("Writing to original should not affect clone") } @@ -323,20 +323,20 @@ func TestReset(t *testing.T) { h := New() h.WriteString("test") d1 := h.Digest() - + h.Reset() h.WriteString("test") d2 := h.Digest() - + if !bytes.Equal(d1[:], d2[:]) { t.Error("Reset should restore initial state") } - + // After reset, different input should produce different hash h.Reset() h.WriteString("different") d3 := h.Digest() - + if bytes.Equal(d1[:], d3[:]) { t.Error("After reset, different input should produce different hash") } @@ -353,7 +353,7 @@ func BenchmarkHashBytes(b *testing.B) { for i := range data { data[i] = byte(i % 256) } - + b.ResetTimer() for i := 0; i < b.N; i++ { _ = HashBytes(data) @@ -362,7 +362,7 @@ func BenchmarkHashBytes(b *testing.B) { func BenchmarkHashString(b *testing.B) { data := strings.Repeat("benchmark", 128) - + b.ResetTimer() for i := 0; i < b.N; i++ { _ = HashString(data) @@ -372,11 +372,11 @@ func BenchmarkHashString(b *testing.B) { func BenchmarkWriteBigInt(b *testing.B) { n := new(big.Int) n.SetString("123456789012345678901234567890123456789012345678901234567890", 10) - + b.ResetTimer() for i := 0; i < b.N; i++ { h := New() h.WriteBigInt(n) _ = h.Digest() } -} \ No newline at end of file +} diff --git a/hashing/hashing_test.go b/hashing/hashing_test.go index b7f344e..afad3a8 100644 --- a/hashing/hashing_test.go +++ b/hashing/hashing_test.go @@ -103,16 +103,16 @@ func TestComputeHash160(t *testing.T) { func TestChecksum(t *testing.T) { input := []byte("test input for checksum") - + // Test various checksum lengths lengths := []int{1, 4, 8, 16, 32} - + for _, length := range lengths { checksum := Checksum(input, length) if len(checksum) != length { t.Errorf("Checksum length should be %d, got %d", length, len(checksum)) } - + // Verify checksum is last 'length' bytes of hash fullHash := ComputeHash256Array(input) expected := fullHash[len(fullHash)-length:] @@ -120,14 +120,14 @@ func TestChecksum(t *testing.T) { t.Errorf("Checksum should be last %d bytes of hash", length) } } - + // Test that same input produces same checksum checksum1 := Checksum(input, 4) checksum2 := Checksum(input, 4) if !bytes.Equal(checksum1, checksum2) { t.Error("Same input should produce same checksum") } - + // Test that different input produces different checksum input2 := []byte("different input") checksum3 := Checksum(input2, 4) @@ -142,16 +142,16 @@ func TestToHash256(t *testing.T) { for i := range validBytes { validBytes[i] = byte(i) } - + hash, err := ToHash256(validBytes) if err != nil { t.Errorf("ToHash256 with valid bytes should not error: %v", err) } - + if !bytes.Equal(hash[:], validBytes) { t.Error("ToHash256 should copy bytes correctly") } - + // Test invalid lengths invalidLengths := []int{0, 1, 31, 33, 100} for _, length := range invalidLengths { @@ -172,16 +172,16 @@ func TestToHash160(t *testing.T) { for i := range validBytes { validBytes[i] = byte(i) } - + hash, err := ToHash160(validBytes) if err != nil { t.Errorf("ToHash160 with valid bytes should not error: %v", err) } - + if !bytes.Equal(hash[:], validBytes) { t.Error("ToHash160 should copy bytes correctly") } - + // Test invalid lengths invalidLengths := []int{0, 1, 19, 21, 100} for _, length := range invalidLengths { @@ -199,27 +199,27 @@ func TestToHash160(t *testing.T) { func TestPubkeyBytesToAddress(t *testing.T) { // Test that address generation is consistent pubkey := []byte("test public key") - + addr1 := PubkeyBytesToAddress(pubkey) addr2 := PubkeyBytesToAddress(pubkey) - + if !bytes.Equal(addr1, addr2) { t.Error("Same pubkey should produce same address") } - + // Test that different pubkeys produce different addresses pubkey2 := []byte("different public key") addr3 := PubkeyBytesToAddress(pubkey2) - + if bytes.Equal(addr1, addr3) { t.Error("Different pubkeys should produce different addresses") } - + // Test that address is 20 bytes (ripemd160 size) if len(addr1) != AddrLen { t.Errorf("Address should be %d bytes, got %d", AddrLen, len(addr1)) } - + // Test empty pubkey emptyAddr := PubkeyBytesToAddress([]byte{}) if len(emptyAddr) != AddrLen { @@ -232,7 +232,7 @@ func TestHashConstants(t *testing.T) { if HashLen != 32 { t.Errorf("HashLen should be 32, got %d", HashLen) } - + if AddrLen != 20 { t.Errorf("AddrLen should be 20, got %d", AddrLen) } @@ -243,7 +243,7 @@ func BenchmarkComputeHash256(b *testing.B) { for i := range input { input[i] = byte(i % 256) } - + b.ResetTimer() for i := 0; i < b.N; i++ { _ = ComputeHash256(input) @@ -255,7 +255,7 @@ func BenchmarkComputeHash256Array(b *testing.B) { for i := range input { input[i] = byte(i % 256) } - + b.ResetTimer() for i := 0; i < b.N; i++ { _ = ComputeHash256Array(input) @@ -267,7 +267,7 @@ func BenchmarkComputeHash160(b *testing.B) { for i := range input { input[i] = byte(i % 256) } - + b.ResetTimer() for i := 0; i < b.N; i++ { _ = ComputeHash160(input) @@ -279,7 +279,7 @@ func BenchmarkPubkeyBytesToAddress(b *testing.B) { for i := range pubkey { pubkey[i] = byte(i % 256) } - + b.ResetTimer() for i := 0; i < b.N; i++ { _ = PubkeyBytesToAddress(pubkey) @@ -291,9 +291,9 @@ func BenchmarkChecksum(b *testing.B) { for i := range input { input[i] = byte(i % 256) } - + b.ResetTimer() for i := 0; i < b.N; i++ { _ = Checksum(input, 4) } -} \ No newline at end of file +} diff --git a/hpke/hpke.go b/hpke/hpke.go index 44ce618..96fbeca 100644 --- a/hpke/hpke.go +++ b/hpke/hpke.go @@ -48,4 +48,4 @@ var NewSuite = hpke.NewSuite type Sender = hpke.Sender // Receiver represents an HPKE receiver context -type Receiver = hpke.Receiver \ No newline at end of file +type Receiver = hpke.Receiver diff --git a/kdf/schedule.go b/kdf/schedule.go index 75bec27..5c9a1eb 100644 --- a/kdf/schedule.go +++ b/kdf/schedule.go @@ -48,7 +48,7 @@ type KeySchedule struct { // NewKeySchedule creates a new key schedule func NewKeySchedule(suite Suite) *KeySchedule { var hashFunc func() hash.Hash - + switch suite.Hash { case SHA256: hashFunc = sha256.New @@ -57,7 +57,7 @@ func NewKeySchedule(suite Suite) *KeySchedule { default: hashFunc = sha256.New } - + return &KeySchedule{ suite: suite, hash: hashFunc, @@ -68,39 +68,39 @@ func NewKeySchedule(suite Suite) *KeySchedule { func (ks *KeySchedule) DeriveHandshakeKeys(kemSecret, ecdheSecret []byte, transcript []byte) (*HandshakeKeys, error) { // Concatenate secrets combined := append(kemSecret, ecdheSecret...) - + // HKDF-Extract salt := []byte("QZMQ-v1-Handshake") prk := hkdf.Extract(ks.hash, combined, salt) - + // Derive various keys using HKDF-Expand keys := &HandshakeKeys{} - + // Client traffic secret clientInfo := append([]byte("client traffic secret"), transcript...) clientSecret := ks.expand(prk, clientInfo, 32) - + // Server traffic secret serverInfo := append([]byte("server traffic secret"), transcript...) serverSecret := ks.expand(prk, serverInfo, 32) - + // Derive actual keys and IVs from traffic secrets keys.ClientKey = ks.expand(clientSecret, []byte("key"), 32) keys.ClientIV = ks.expand(clientSecret, []byte("iv"), 12) keys.ServerKey = ks.expand(serverSecret, []byte("key"), 32) keys.ServerIV = ks.expand(serverSecret, []byte("iv"), 12) - + // Exporter secret exporterInfo := append([]byte("exporter secret"), transcript...) keys.ExporterSecret = ks.expand(prk, exporterInfo, 32) - + // Generate key ID keyIDBytes := ks.expand(prk, []byte("key id"), 4) keys.KeyID = binary.BigEndian.Uint32(keyIDBytes) - + ks.handshakeKeys = keys ks.updateCounter = 0 - + return keys, nil } @@ -109,39 +109,39 @@ func (ks *KeySchedule) KeyUpdate() (*HandshakeKeys, error) { if ks.handshakeKeys == nil { return nil, ErrNoHandshakeKeys } - + ks.updateCounter++ - + // Create update info with counter updateInfo := make([]byte, 4) binary.BigEndian.PutUint32(updateInfo, ks.updateCounter) - + // Ratchet client key newClientSecret := ks.expand( ks.handshakeKeys.ClientKey, append([]byte("key update"), updateInfo...), 32, ) - + // Ratchet server key newServerSecret := ks.expand( ks.handshakeKeys.ServerKey, append([]byte("key update"), updateInfo...), 32, ) - + // Derive new keys newKeys := &HandshakeKeys{ - ClientKey: ks.expand(newClientSecret, []byte("key"), 32), - ClientIV: ks.expand(newClientSecret, []byte("iv"), 12), - ServerKey: ks.expand(newServerSecret, []byte("key"), 32), - ServerIV: ks.expand(newServerSecret, []byte("iv"), 12), + ClientKey: ks.expand(newClientSecret, []byte("key"), 32), + ClientIV: ks.expand(newClientSecret, []byte("iv"), 12), + ServerKey: ks.expand(newServerSecret, []byte("key"), 32), + ServerIV: ks.expand(newServerSecret, []byte("iv"), 12), ExporterSecret: ks.handshakeKeys.ExporterSecret, // Exporter doesn't change - KeyID: ks.handshakeKeys.KeyID + ks.updateCounter, + KeyID: ks.handshakeKeys.KeyID + ks.updateCounter, } - + ks.handshakeKeys = newKeys - + return newKeys, nil } @@ -150,7 +150,7 @@ func (ks *KeySchedule) Export(context []byte, length int) ([]byte, error) { if ks.handshakeKeys == nil { return nil, ErrNoHandshakeKeys } - + info := append([]byte("QZMQ exporter"), context...) return ks.expand(ks.handshakeKeys.ExporterSecret, info, length), nil } @@ -159,11 +159,11 @@ func (ks *KeySchedule) Export(context []byte, length int) ([]byte, error) { func (ks *KeySchedule) expand(prk, info []byte, length int) []byte { r := hkdf.Expand(ks.hash, prk, info) output := make([]byte, length) - + if _, err := io.ReadFull(r, output); err != nil { panic(err) // Should never happen with correct parameters } - + return output } @@ -172,22 +172,22 @@ func (ks *KeySchedule) DeriveEarlyDataKeys(psk []byte, transcript []byte) (*Hand // HKDF-Extract with PSK salt := []byte("QZMQ-v1-EarlyData") prk := hkdf.Extract(ks.hash, psk, salt) - + // Derive early traffic secret earlyInfo := append([]byte("early traffic secret"), transcript...) earlySecret := ks.expand(prk, earlyInfo, 32) - + // Derive keys for early data keys := &HandshakeKeys{ ClientKey: ks.expand(earlySecret, []byte("key"), 32), ClientIV: ks.expand(earlySecret, []byte("iv"), 12), // Server doesn't send early data, so no server keys - ServerKey: nil, - ServerIV: nil, + ServerKey: nil, + ServerIV: nil, ExporterSecret: ks.expand(prk, []byte("early exporter secret"), 32), - KeyID: 0, // Special ID for early data + KeyID: 0, // Special ID for early data } - + return keys, nil } @@ -196,7 +196,7 @@ func (ks *KeySchedule) ResumptionSecret(transcript []byte) ([]byte, error) { if ks.handshakeKeys == nil { return nil, ErrNoHandshakeKeys } - + info := append([]byte("resumption secret"), transcript...) return ks.expand(ks.handshakeKeys.ExporterSecret, info, 32), nil } @@ -219,7 +219,7 @@ type Budgets struct { MaxMessages uint32 MaxBytes uint64 MaxAge int // seconds - + currentMessages uint32 currentBytes uint64 keyBirth int64 // unix timestamp @@ -238,19 +238,19 @@ func NewBudgets(maxMsgs uint32, maxBytes uint64, maxAge int) *Budgets { func (b *Budgets) CheckAndUpdate(msgSize int, now int64) bool { b.currentMessages++ b.currentBytes += uint64(msgSize) - + if b.currentMessages >= b.MaxMessages { return true } - + if b.currentBytes >= b.MaxBytes { return true } - + if b.keyBirth > 0 && now-b.keyBirth >= int64(b.MaxAge) { return true } - + return false } @@ -259,4 +259,4 @@ func (b *Budgets) Reset(now int64) { b.currentMessages = 0 b.currentBytes = 0 b.keyBirth = now -} \ No newline at end of file +} diff --git a/kem/factory.go b/kem/factory.go index 3e47030..59a68ae 100644 --- a/kem/factory.go +++ b/kem/factory.go @@ -19,7 +19,7 @@ func shouldUseCGO() bool { useCGO = false return } - + // Default to CGO if available (detected at build time) useCGO = cgoAvailable() }) @@ -62,12 +62,12 @@ func NewHybrid() (KEM, error) { if err != nil { return nil, err } - + mlkem, err := NewMLKEM768() if err != nil { return nil, err } - + return newHybridKEM(x25519, mlkem) } @@ -92,4 +92,4 @@ func newHybridKEM(classical, pq KEM) (KEM, error) { x25519: classical, mlkem: pq, }, nil -} \ No newline at end of file +} diff --git a/kem/hybrid.go b/kem/hybrid.go index c4ec681..7e31ee0 100644 --- a/kem/hybrid.go +++ b/kem/hybrid.go @@ -42,22 +42,22 @@ func (h *HybridKEMImpl) GenerateKeyPair() (PublicKey, PrivateKey, error) { if err != nil { return nil, nil, err } - + mlkemPK, mlkemSK, err := h.mlkem.GenerateKeyPair() if err != nil { return nil, nil, err } - + pk := &HybridPublicKey{ X25519PK: x25519PK, MLKEMPK: mlkemPK, } - + sk := &HybridPrivateKey{ X25519SK: x25519SK, MLKEMSK: mlkemSK, } - + return pk, sk, nil } @@ -67,25 +67,25 @@ func (h *HybridKEMImpl) Encapsulate(pk PublicKey) ([]byte, []byte, error) { if !ok { return nil, nil, errors.New("invalid public key type for hybrid KEM") } - + // Perform X25519 encapsulation x25519CT, x25519SS, err := h.x25519.Encapsulate(hybridPK.X25519PK) if err != nil { return nil, nil, err } - + // Perform ML-KEM encapsulation mlkemCT, mlkemSS, err := h.mlkem.Encapsulate(hybridPK.MLKEMPK) if err != nil { return nil, nil, err } - + // Concatenate ciphertexts ciphertext := append(x25519CT, mlkemCT...) - + // Derive shared secret using HKDF sharedSecret := h.deriveSharedSecret(x25519SS, mlkemSS) - + return ciphertext, sharedSecret, nil } @@ -95,31 +95,31 @@ func (h *HybridKEMImpl) Decapsulate(sk PrivateKey, ciphertext []byte) ([]byte, e if !ok { return nil, errors.New("invalid private key type for hybrid KEM") } - + x25519CTSize := h.x25519.CiphertextSize() if len(ciphertext) < x25519CTSize { return nil, errors.New("ciphertext too short") } - + // Split ciphertext x25519CT := ciphertext[:x25519CTSize] mlkemCT := ciphertext[x25519CTSize:] - + // Perform X25519 decapsulation x25519SS, err := h.x25519.Decapsulate(hybridSK.X25519SK, x25519CT) if err != nil { return nil, err } - + // Perform ML-KEM decapsulation mlkemSS, err := h.mlkem.Decapsulate(hybridSK.MLKEMSK, mlkemCT) if err != nil { return nil, err } - + // Derive shared secret using HKDF sharedSecret := h.deriveSharedSecret(x25519SS, mlkemSS) - + return sharedSecret, nil } @@ -127,18 +127,18 @@ func (h *HybridKEMImpl) Decapsulate(sk PrivateKey, ciphertext []byte) ([]byte, e func (h *HybridKEMImpl) deriveSharedSecret(x25519SS, mlkemSS []byte) []byte { // Concatenate secrets combined := append(x25519SS, mlkemSS...) - + // Use HKDF-Extract then Expand salt := []byte("QZMQ-HybridKEM-v1") info := []byte("hybrid-kem-shared-secret") - + hkdf := hkdf.New(sha256.New, combined, salt, info) sharedSecret := make([]byte, 32) - + if _, err := io.ReadFull(hkdf, sharedSecret); err != nil { panic(err) // Should never happen with correct sizes } - + return sharedSecret } @@ -193,4 +193,4 @@ func (sk *HybridPrivateKey) Equal(other PrivateKey) bool { return false } return sk.X25519SK.Equal(otherSK.X25519SK) && sk.MLKEMSK.Equal(otherSK.MLKEMSK) -} \ No newline at end of file +} diff --git a/kem/kem.go b/kem/kem.go index c505973..f3f7f47 100644 --- a/kem/kem.go +++ b/kem/kem.go @@ -19,22 +19,22 @@ const ( type KEM interface { // GenerateKeyPair generates a new KEM key pair GenerateKeyPair() (PublicKey, PrivateKey, error) - + // Encapsulate generates a shared secret and ciphertext Encapsulate(pk PublicKey) (ciphertext []byte, sharedSecret []byte, err error) - + // Decapsulate recovers the shared secret from ciphertext Decapsulate(sk PrivateKey, ciphertext []byte) (sharedSecret []byte, err error) - + // PublicKeySize returns the size of public keys PublicKeySize() int - + // PrivateKeySize returns the size of private keys PrivateKeySize() int - + // CiphertextSize returns the size of ciphertexts CiphertextSize() int - + // SharedSecretSize returns the size of shared secrets SharedSecretSize() int } @@ -54,10 +54,10 @@ type PrivateKey interface { // Constants for ML-KEM-768 const ( - mlkem768PublicKeySize = 1184 - mlkem768PrivateKeySize = 2400 - mlkem768CiphertextSize = 1088 - mlkem768SharedSecretSize = 32 + mlkem768PublicKeySize = 1184 + mlkem768PrivateKeySize = 2400 + mlkem768CiphertextSize = 1088 + mlkem768SharedSecretSize = 32 ) // Constants for ML-KEM-1024 @@ -82,4 +82,4 @@ func GetKEM(id KemID) (KEM, error) { default: return nil, fmt.Errorf("unsupported KEM: %s", id) } -} \ No newline at end of file +} diff --git a/kem/mlkem.go b/kem/mlkem.go index b98a4a1..4eee099 100644 --- a/kem/mlkem.go +++ b/kem/mlkem.go @@ -14,7 +14,6 @@ type MLKEM768Impl struct { k int // k parameter (3 for ML-KEM-768) } - // MLKEM768PublicKey represents an ML-KEM-768 public key type MLKEM768PublicKey struct { data []byte @@ -26,12 +25,11 @@ type MLKEM768PrivateKey struct { pk *MLKEM768PublicKey } - // GenerateKeyPair generates a new ML-KEM-768 key pair func (m *MLKEM768Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { // Placeholder for actual ML-KEM-768 key generation // In production, this would use liboqs or a native implementation - + pk := &MLKEM768PublicKey{ data: make([]byte, mlkem768PublicKeySize), } @@ -39,7 +37,7 @@ func (m *MLKEM768Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { data: make([]byte, mlkem768PrivateKeySize), pk: pk, } - + // Generate random key material (placeholder) if _, err := rand.Read(pk.data); err != nil { return nil, nil, err @@ -47,7 +45,7 @@ func (m *MLKEM768Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { if _, err := rand.Read(sk.data); err != nil { return nil, nil, err } - + return pk, sk, nil } @@ -57,10 +55,10 @@ func (m *MLKEM768Impl) Encapsulate(pk PublicKey) ([]byte, []byte, error) { if !ok { return nil, nil, errors.New("invalid public key type") } - + ciphertext := make([]byte, mlkem768CiphertextSize) sharedSecret := make([]byte, mlkem768SharedSecretSize) - + // Placeholder for actual ML-KEM-768 encapsulation if _, err := rand.Read(ciphertext); err != nil { return nil, nil, err @@ -68,10 +66,10 @@ func (m *MLKEM768Impl) Encapsulate(pk PublicKey) ([]byte, []byte, error) { if _, err := rand.Read(sharedSecret); err != nil { return nil, nil, err } - + // In production, this would perform actual ML-KEM encapsulation _ = mlkemPK.data - + return ciphertext, sharedSecret, nil } @@ -81,22 +79,22 @@ func (m *MLKEM768Impl) Decapsulate(sk PrivateKey, ciphertext []byte) ([]byte, er if !ok { return nil, errors.New("invalid private key type") } - + if len(ciphertext) != mlkem768CiphertextSize { return nil, errors.New("invalid ciphertext size") } - + sharedSecret := make([]byte, mlkem768SharedSecretSize) - + // Placeholder for actual ML-KEM-768 decapsulation if _, err := rand.Read(sharedSecret); err != nil { return nil, err } - + // In production, this would perform actual ML-KEM decapsulation _ = mlkemSK.data _ = ciphertext - + return sharedSecret, nil } @@ -153,7 +151,6 @@ func (sk *MLKEM768PrivateKey) Equal(other PrivateKey) bool { return subtle.ConstantTimeCompare(sk.data, otherSK.data) == 1 } - // MLKEM1024 implementation (similar structure, different parameters) type MLKEM1024Impl struct { k int // k parameter (4 for ML-KEM-1024) @@ -170,8 +167,6 @@ type MLKEM1024PrivateKey struct { pk *MLKEM1024PublicKey } - - // GenerateKeyPair generates a new ML-KEM-1024 key pair func (m *MLKEM1024Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { // Similar to ML-KEM-768 but with different sizes @@ -182,14 +177,14 @@ func (m *MLKEM1024Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { data: make([]byte, mlkem1024PrivateKeySize), pk: pk, } - + if _, err := rand.Read(pk.data); err != nil { return nil, nil, err } if _, err := rand.Read(sk.data); err != nil { return nil, nil, err } - + return pk, sk, nil } @@ -197,14 +192,14 @@ func (m *MLKEM1024Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { func (m *MLKEM1024Impl) Encapsulate(pk PublicKey) ([]byte, []byte, error) { ciphertext := make([]byte, mlkem1024CiphertextSize) sharedSecret := make([]byte, mlkem1024SharedSecretSize) - + if _, err := rand.Read(ciphertext); err != nil { return nil, nil, err } if _, err := rand.Read(sharedSecret); err != nil { return nil, nil, err } - + return ciphertext, sharedSecret, nil } @@ -213,19 +208,19 @@ func (m *MLKEM1024Impl) Decapsulate(sk PrivateKey, ciphertext []byte) ([]byte, e if len(ciphertext) != mlkem1024CiphertextSize { return nil, errors.New("invalid ciphertext size") } - + sharedSecret := make([]byte, mlkem1024SharedSecretSize) if _, err := rand.Read(sharedSecret); err != nil { return nil, err } - + return sharedSecret, nil } // Size methods for ML-KEM-1024 -func (m *MLKEM1024Impl) PublicKeySize() int { return mlkem1024PublicKeySize } -func (m *MLKEM1024Impl) PrivateKeySize() int { return mlkem1024PrivateKeySize } -func (m *MLKEM1024Impl) CiphertextSize() int { return mlkem1024CiphertextSize } +func (m *MLKEM1024Impl) PublicKeySize() int { return mlkem1024PublicKeySize } +func (m *MLKEM1024Impl) PrivateKeySize() int { return mlkem1024PrivateKeySize } +func (m *MLKEM1024Impl) CiphertextSize() int { return mlkem1024CiphertextSize } func (m *MLKEM1024Impl) SharedSecretSize() int { return mlkem1024SharedSecretSize } // Bytes returns the raw bytes of the public key @@ -260,4 +255,3 @@ func (sk *MLKEM1024PrivateKey) Equal(other PrivateKey) bool { } return subtle.ConstantTimeCompare(sk.data, otherSK.data) == 1 } - diff --git a/kem/mlkem_cgo.go b/kem/mlkem_cgo.go index e92fb16..e2869b0 100644 --- a/kem/mlkem_cgo.go +++ b/kem/mlkem_cgo.go @@ -83,7 +83,7 @@ func NewMLKEM768CGO() (*MLKEM768CGO, error) { if kem == nil { return nil, errors.New("failed to create ML-KEM-768 instance") } - + m := &MLKEM768CGO{kem: kem} runtime.SetFinalizer(m, (*MLKEM768CGO).cleanup) return m, nil @@ -102,7 +102,7 @@ func (m *MLKEM768CGO) GenerateKeyPair() (PublicKey, PrivateKey, error) { if m.kem == nil { return nil, nil, errors.New("KEM instance not initialized") } - + pk := &MLKEM768PublicKey{ data: make([]byte, mlkem768PublicKeySize), } @@ -110,17 +110,17 @@ func (m *MLKEM768CGO) GenerateKeyPair() (PublicKey, PrivateKey, error) { data: make([]byte, mlkem768PrivateKeySize), pk: pk, } - + ret := C.mlkem768_keypair( m.kem, (*C.uint8_t)(unsafe.Pointer(&pk.data[0])), (*C.uint8_t)(unsafe.Pointer(&sk.data[0])), ) - + if ret != C.OQS_SUCCESS_VAL { return nil, nil, errors.New("ML-KEM-768 key generation failed") } - + return pk, sk, nil } @@ -129,26 +129,26 @@ func (m *MLKEM768CGO) Encapsulate(pk PublicKey) ([]byte, []byte, error) { if m.kem == nil { return nil, nil, errors.New("KEM instance not initialized") } - + mlkemPK, ok := pk.(*MLKEM768PublicKey) if !ok { return nil, nil, errors.New("invalid public key type") } - + ciphertext := make([]byte, mlkem768CiphertextSize) sharedSecret := make([]byte, mlkem768SharedSecretSize) - + ret := C.mlkem768_encaps( m.kem, (*C.uint8_t)(unsafe.Pointer(&ciphertext[0])), (*C.uint8_t)(unsafe.Pointer(&sharedSecret[0])), (*C.uint8_t)(unsafe.Pointer(&mlkemPK.data[0])), ) - + if ret != C.OQS_SUCCESS_VAL { return nil, nil, errors.New("ML-KEM-768 encapsulation failed") } - + return ciphertext, sharedSecret, nil } @@ -157,29 +157,29 @@ func (m *MLKEM768CGO) Decapsulate(sk PrivateKey, ciphertext []byte) ([]byte, err if m.kem == nil { return nil, errors.New("KEM instance not initialized") } - + mlkemSK, ok := sk.(*MLKEM768PrivateKey) if !ok { return nil, errors.New("invalid private key type") } - + if len(ciphertext) != mlkem768CiphertextSize { return nil, errors.New("invalid ciphertext size") } - + sharedSecret := make([]byte, mlkem768SharedSecretSize) - + ret := C.mlkem768_decaps( m.kem, (*C.uint8_t)(unsafe.Pointer(&sharedSecret[0])), (*C.uint8_t)(unsafe.Pointer(&ciphertext[0])), (*C.uint8_t)(unsafe.Pointer(&mlkemSK.data[0])), ) - + if ret != C.OQS_SUCCESS_VAL { return nil, errors.New("ML-KEM-768 decapsulation failed") } - + return sharedSecret, nil } @@ -214,7 +214,7 @@ func NewMLKEM1024CGO() (*MLKEM1024CGO, error) { if kem == nil { return nil, errors.New("failed to create ML-KEM-1024 instance") } - + m := &MLKEM1024CGO{kem: kem} runtime.SetFinalizer(m, (*MLKEM1024CGO).cleanup) return m, nil @@ -233,7 +233,7 @@ func (m *MLKEM1024CGO) GenerateKeyPair() (PublicKey, PrivateKey, error) { if m.kem == nil { return nil, nil, errors.New("KEM instance not initialized") } - + pk := &MLKEM1024PublicKey{ data: make([]byte, mlkem1024PublicKeySize), } @@ -241,17 +241,17 @@ func (m *MLKEM1024CGO) GenerateKeyPair() (PublicKey, PrivateKey, error) { data: make([]byte, mlkem1024PrivateKeySize), pk: pk, } - + ret := C.mlkem1024_keypair( m.kem, (*C.uint8_t)(unsafe.Pointer(&pk.data[0])), (*C.uint8_t)(unsafe.Pointer(&sk.data[0])), ) - + if ret != C.OQS_SUCCESS_VAL { return nil, nil, errors.New("ML-KEM-1024 key generation failed") } - + return pk, sk, nil } @@ -260,26 +260,26 @@ func (m *MLKEM1024CGO) Encapsulate(pk PublicKey) ([]byte, []byte, error) { if m.kem == nil { return nil, nil, errors.New("KEM instance not initialized") } - + mlkemPK, ok := pk.(*MLKEM1024PublicKey) if !ok { return nil, nil, errors.New("invalid public key type") } - + ciphertext := make([]byte, mlkem1024CiphertextSize) sharedSecret := make([]byte, mlkem1024SharedSecretSize) - + ret := C.mlkem1024_encaps( m.kem, (*C.uint8_t)(unsafe.Pointer(&ciphertext[0])), (*C.uint8_t)(unsafe.Pointer(&sharedSecret[0])), (*C.uint8_t)(unsafe.Pointer(&mlkemPK.data[0])), ) - + if ret != C.OQS_SUCCESS_VAL { return nil, nil, errors.New("ML-KEM-1024 encapsulation failed") } - + return ciphertext, sharedSecret, nil } @@ -288,29 +288,29 @@ func (m *MLKEM1024CGO) Decapsulate(sk PrivateKey, ciphertext []byte) ([]byte, er if m.kem == nil { return nil, errors.New("KEM instance not initialized") } - + mlkemSK, ok := sk.(*MLKEM1024PrivateKey) if !ok { return nil, errors.New("invalid private key type") } - + if len(ciphertext) != mlkem1024CiphertextSize { return nil, errors.New("invalid ciphertext size") } - + sharedSecret := make([]byte, mlkem1024SharedSecretSize) - + ret := C.mlkem1024_decaps( m.kem, (*C.uint8_t)(unsafe.Pointer(&sharedSecret[0])), (*C.uint8_t)(unsafe.Pointer(&ciphertext[0])), (*C.uint8_t)(unsafe.Pointer(&mlkemSK.data[0])), ) - + if ret != C.OQS_SUCCESS_VAL { return nil, errors.New("ML-KEM-1024 decapsulation failed") } - + return sharedSecret, nil } @@ -334,7 +334,7 @@ func (m *MLKEM1024CGO) SharedSecretSize() int { return mlkem1024SharedSecretSize } -// cgoAvailable returns true when CGO is available +// cgoAvailable returns true when CGO is available func cgoAvailable() bool { return true -} \ No newline at end of file +} diff --git a/kem/mlkem_cgo_stub.go b/kem/mlkem_cgo_stub.go index 08d65ca..a4d37c9 100644 --- a/kem/mlkem_cgo_stub.go +++ b/kem/mlkem_cgo_stub.go @@ -18,4 +18,4 @@ func NewMLKEM768CGO() (KEM, error) { // NewMLKEM1024CGO returns an error when liboqs is not available func NewMLKEM1024CGO() (KEM, error) { return nil, errors.New("liboqs not installed, using pure Go implementation") -} \ No newline at end of file +} diff --git a/kem/nocgo.go b/kem/nocgo.go index 829ae06..7bdd1db 100644 --- a/kem/nocgo.go +++ b/kem/nocgo.go @@ -18,4 +18,4 @@ func NewMLKEM768CGO() (KEM, error) { // NewMLKEM1024CGO returns an error when CGO is disabled func NewMLKEM1024CGO() (KEM, error) { return nil, errors.New("CGO disabled, using pure Go implementation") -} \ No newline at end of file +} diff --git a/kem/x25519.go b/kem/x25519.go index 51cc432..d1a9bdf 100644 --- a/kem/x25519.go +++ b/kem/x25519.go @@ -21,7 +21,7 @@ type X25519PublicKey struct { data [32]byte } -// X25519PrivateKey represents an X25519 private key +// X25519PrivateKey represents an X25519 private key type X25519PrivateKey struct { data [32]byte pk *X25519PublicKey @@ -30,22 +30,22 @@ type X25519PrivateKey struct { // GenerateKeyPair generates a new X25519 key pair func (x *X25519Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { sk := &X25519PrivateKey{} - + // Generate random private key if _, err := rand.Read(sk.data[:]); err != nil { return nil, nil, err } - + // Clamp private key as per X25519 spec sk.data[0] &= 248 sk.data[31] &= 127 sk.data[31] |= 64 - + // Compute public key pk := &X25519PublicKey{} curve25519.ScalarBaseMult(&pk.data, &sk.data) sk.pk = pk - + return pk, sk, nil } @@ -55,31 +55,31 @@ func (x *X25519Impl) Encapsulate(pk PublicKey) ([]byte, []byte, error) { if !ok { return nil, nil, errors.New("invalid public key type for X25519") } - + // Generate ephemeral key pair ephSK := &X25519PrivateKey{} if _, err := rand.Read(ephSK.data[:]); err != nil { return nil, nil, err } - + // Clamp ephemeral private key ephSK.data[0] &= 248 ephSK.data[31] &= 127 ephSK.data[31] |= 64 - + // Compute ephemeral public key (ciphertext) ephPK := &X25519PublicKey{} curve25519.ScalarBaseMult(&ephPK.data, &ephSK.data) - + // Compute shared secret var sharedSecret [32]byte curve25519.ScalarMult(&sharedSecret, &ephSK.data, &x25519PK.data) - + // Check for low-order points if isLowOrder(sharedSecret[:]) { return nil, nil, errors.New("low-order shared secret") } - + return ephPK.data[:], sharedSecret[:], nil } @@ -89,23 +89,23 @@ func (x *X25519Impl) Decapsulate(sk PrivateKey, ciphertext []byte) ([]byte, erro if !ok { return nil, errors.New("invalid private key type for X25519") } - + if len(ciphertext) != 32 { return nil, errors.New("invalid ciphertext size for X25519") } - + var ephPK [32]byte copy(ephPK[:], ciphertext) - + // Compute shared secret var sharedSecret [32]byte curve25519.ScalarMult(&sharedSecret, &x25519SK.data, &ephPK) - + // Check for low-order points if isLowOrder(sharedSecret[:]) { return nil, errors.New("low-order shared secret") } - + return sharedSecret[:], nil } @@ -117,9 +117,9 @@ func isLowOrder(p []byte) bool { } // Size methods for X25519 -func (x *X25519Impl) PublicKeySize() int { return 32 } -func (x *X25519Impl) PrivateKeySize() int { return 32 } -func (x *X25519Impl) CiphertextSize() int { return 32 } +func (x *X25519Impl) PublicKeySize() int { return 32 } +func (x *X25519Impl) PrivateKeySize() int { return 32 } +func (x *X25519Impl) CiphertextSize() int { return 32 } func (x *X25519Impl) SharedSecretSize() int { return 32 } // Bytes returns the public key bytes @@ -153,4 +153,4 @@ func (sk *X25519PrivateKey) Equal(other PrivateKey) bool { return false } return subtle.ConstantTimeCompare(sk.data[:], otherSK.data[:]) == 1 -} \ No newline at end of file +} diff --git a/mldsa/.old/mldsa_comprehensive_test.go b/mldsa/.old/mldsa_comprehensive_test.go index 920cf36..a343a67 100644 --- a/mldsa/.old/mldsa_comprehensive_test.go +++ b/mldsa/.old/mldsa_comprehensive_test.go @@ -8,11 +8,11 @@ import ( func TestMLDSAKeyGeneration(t *testing.T) { modes := []struct { - name string - mode Mode - pubSize int - privSize int - sigSize int + name string + mode Mode + pubSize int + privSize int + sigSize int }{ {"ML-DSA-44", MLDSA44, MLDSA44PublicKeySize, MLDSA44PrivateKeySize, MLDSA44SignatureSize}, {"ML-DSA-65", MLDSA65, MLDSA65PublicKeySize, MLDSA65PrivateKeySize, MLDSA65SignatureSize}, @@ -49,7 +49,7 @@ func TestMLDSAKeyGeneration(t *testing.T) { func TestMLDSASignVerify(t *testing.T) { modes := []Mode{MLDSA44, MLDSA65, MLDSA87} - + for _, mode := range modes { t.Run(mode.String(), func(t *testing.T) { privKey, err := GenerateKey(rand.Reader, mode) @@ -58,7 +58,7 @@ func TestMLDSASignVerify(t *testing.T) { } message := []byte("Test message for ML-DSA signature") - + // Sign message signature, err := privKey.Sign(rand.Reader, message, nil) if err != nil { @@ -102,7 +102,7 @@ func TestMLDSASignVerify(t *testing.T) { func TestMLDSAKeySerialization(t *testing.T) { modes := []Mode{MLDSA44, MLDSA65, MLDSA87} - + for _, mode := range modes { t.Run(mode.String(), func(t *testing.T) { // Generate original key @@ -241,7 +241,7 @@ func TestMLDSAEdgeCases(t *testing.T) { func TestMLDSALargeMessage(t *testing.T) { modes := []Mode{MLDSA44, MLDSA65, MLDSA87} - + for _, mode := range modes { t.Run(mode.String(), func(t *testing.T) { privKey, err := GenerateKey(rand.Reader, mode) @@ -280,12 +280,12 @@ func TestMLDSAConcurrency(t *testing.T) { } message := []byte("Concurrent test message") - + // Test concurrent signing t.Run("ConcurrentSign", func(t *testing.T) { const numGoroutines = 10 done := make(chan bool, numGoroutines) - + for i := 0; i < numGoroutines; i++ { go func(id int) { msg := append(message, byte(id)) @@ -300,7 +300,7 @@ func TestMLDSAConcurrency(t *testing.T) { done <- true }(i) } - + for i := 0; i < numGoroutines; i++ { <-done } @@ -311,7 +311,7 @@ func TestMLDSAConcurrency(t *testing.T) { signature, _ := privKey.Sign(rand.Reader, message, nil) const numGoroutines = 10 done := make(chan bool, numGoroutines) - + for i := 0; i < numGoroutines; i++ { go func(id int) { valid := privKey.PublicKey.Verify(message, signature, nil) @@ -321,7 +321,7 @@ func TestMLDSAConcurrency(t *testing.T) { done <- true }(i) } - + for i := 0; i < numGoroutines; i++ { <-done } @@ -365,7 +365,7 @@ func BenchmarkMLDSASign(b *testing.B) { for _, m := range modes { privKey, _ := GenerateKey(rand.Reader, m.mode) - + b.Run(m.name, func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { @@ -393,7 +393,7 @@ func BenchmarkMLDSAVerify(b *testing.B) { for _, m := range modes { privKey, _ := GenerateKey(rand.Reader, m.mode) signature, _ := privKey.Sign(rand.Reader, message, nil) - + b.Run(m.name, func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { @@ -406,4 +406,4 @@ func BenchmarkMLDSAVerify(b *testing.B) { } } -// Helper functions are now in mldsa.go \ No newline at end of file +// Helper functions are now in mldsa.go diff --git a/mldsa/.old/mldsa_optimized_test.go b/mldsa/.old/mldsa_optimized_test.go index 36c7115..9d33dd4 100644 --- a/mldsa/.old/mldsa_optimized_test.go +++ b/mldsa/.old/mldsa_optimized_test.go @@ -8,7 +8,7 @@ import ( func TestOptimizedKeyGeneration(t *testing.T) { modes := []Mode{MLDSA44, MLDSA65, MLDSA87} - + for _, mode := range modes { t.Run(mode.String(), func(t *testing.T) { // Test optimized key generation @@ -55,7 +55,7 @@ func TestOptimizedKeyGeneration(t *testing.T) { func TestOptimizedSign(t *testing.T) { modes := []Mode{MLDSA44, MLDSA65, MLDSA87} - + for _, mode := range modes { t.Run(mode.String(), func(t *testing.T) { privKey, err := GenerateKey(rand.Reader, mode) @@ -64,7 +64,7 @@ func TestOptimizedSign(t *testing.T) { } message := []byte("Test message for optimized signing") - + // Test optimized signing signature, err := privKey.OptimizedSign(rand.Reader, message, nil) if err != nil { @@ -89,7 +89,7 @@ func TestOptimizedSign(t *testing.T) { func TestBatchDSA(t *testing.T) { modes := []Mode{MLDSA44, MLDSA65, MLDSA87} - + for _, mode := range modes { t.Run(mode.String(), func(t *testing.T) { numKeys := 5 @@ -101,7 +101,7 @@ func TestBatchDSA(t *testing.T) { // Prepare messages messages := make([][]byte, numKeys) for i := range messages { - messages[i] = []byte(string(rune('A' + i)) + " Test message for batch signing") + messages[i] = []byte(string(rune('A'+i)) + " Test message for batch signing") } // Batch sign @@ -154,7 +154,7 @@ func TestBatchDSA(t *testing.T) { func TestPrecomputedMLDSA(t *testing.T) { modes := []Mode{MLDSA44, MLDSA65, MLDSA87} - + for _, mode := range modes { t.Run(mode.String(), func(t *testing.T) { privKey, err := GenerateKey(rand.Reader, mode) @@ -165,7 +165,7 @@ func TestPrecomputedMLDSA(t *testing.T) { precomputed := NewPrecomputedMLDSA(privKey) message := []byte("Test message for caching") - + // First sign (cache miss) sig1, err := precomputed.SignCached(message) if err != nil { @@ -339,7 +339,7 @@ func BenchmarkOptimizedSign(b *testing.B) { for _, m := range modes { privKey, _ := GenerateKey(rand.Reader, m.mode) - + b.Run(m.name+"-Standard", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { @@ -365,7 +365,7 @@ func BenchmarkOptimizedSign(b *testing.B) { func BenchmarkBatchOperations(b *testing.B) { numKeys := 10 batch, _ := NewBatchDSA(MLDSA65, numKeys) - + messages := make([][]byte, numKeys) for i := range messages { messages[i] = make([]byte, 32) @@ -393,4 +393,4 @@ func BenchmarkBatchOperations(b *testing.B) { } } }) -} \ No newline at end of file +} diff --git a/mlkem/mlkem.go b/mlkem/mlkem.go index ba115fc..af08dd3 100644 --- a/mlkem/mlkem.go +++ b/mlkem/mlkem.go @@ -302,4 +302,4 @@ func PrivateKeyFromBytes(data []byte, mode Mode) (*PrivateKey, error) { key: privKey, mode: mode, }, nil -} \ No newline at end of file +} diff --git a/mlkem/mlkem_bench_test.go b/mlkem/mlkem_bench_test.go index bdba527..bc9a0b6 100644 --- a/mlkem/mlkem_bench_test.go +++ b/mlkem/mlkem_bench_test.go @@ -100,7 +100,7 @@ func BenchmarkMLKEMMemory(b *testing.B) { b.ReportAllocs() priv, _, _ := GenerateKeyPair(rand.Reader, m.mode) result, _ := priv.PublicKey.Encapsulate(rand.Reader) - + b.ResetTimer() for i := 0; i < b.N; i++ { // Full KEM operation @@ -109,4 +109,4 @@ func BenchmarkMLKEMMemory(b *testing.B) { } }) } -} \ No newline at end of file +} diff --git a/mlkem/mlkem_comprehensive_test.go b/mlkem/mlkem_comprehensive_test.go index a06ac98..0de97ae 100644 --- a/mlkem/mlkem_comprehensive_test.go +++ b/mlkem/mlkem_comprehensive_test.go @@ -8,12 +8,12 @@ import ( func TestMLKEMKeyGeneration(t *testing.T) { modes := []struct { - name string - mode Mode - pubSize int - privSize int - ctSize int - ssSize int + name string + mode Mode + pubSize int + privSize int + ctSize int + ssSize int }{ {"ML-KEM-512", MLKEM512, MLKEM512PublicKeySize, MLKEM512PrivateKeySize, MLKEM512CiphertextSize, MLKEM512SharedSecretSize}, {"ML-KEM-768", MLKEM768, MLKEM768PublicKeySize, MLKEM768PrivateKeySize, MLKEM768CiphertextSize, MLKEM768SharedSecretSize}, @@ -114,7 +114,7 @@ func TestMLKEMEncapsulateDecapsulate(t *testing.T) { tamperedCiphertext := make([]byte, len(encapResult.Ciphertext)) copy(tamperedCiphertext, encapResult.Ciphertext) tamperedCiphertext[0] ^= 0xFF - + // In our placeholder implementation, this will produce different shared secret tamperedSecret, err := privKey.Decapsulate(tamperedCiphertext) if err != nil { @@ -301,12 +301,12 @@ func TestMLKEMConcurrency(t *testing.T) { if err != nil { t.Errorf("Goroutine %d: Encapsulate failed: %v", id, err) } - + ss, err := privKey.Decapsulate(encapResult.Ciphertext) if err != nil { t.Errorf("Goroutine %d: Decapsulate failed: %v", id, err) } - + if !bytes.Equal(ss, encapResult.SharedSecret) { t.Errorf("Goroutine %d: Shared secrets don't match", id) } @@ -344,8 +344,6 @@ func TestMLKEMConcurrency(t *testing.T) { }) } - - // Helper functions that were missing func NewPrivateKey(mode Mode) *PrivateKey { return &PrivateKey{ @@ -423,7 +421,7 @@ func BenchmarkMLKEMEncapsulate(b *testing.B) { for _, m := range modes { privKey, _, _ := GenerateKeyPair(rand.Reader, m.mode) - + b.Run(m.name, func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { @@ -449,7 +447,7 @@ func BenchmarkMLKEMDecapsulate(b *testing.B) { for _, m := range modes { privKey, _, _ := GenerateKeyPair(rand.Reader, m.mode) encapResult, _ := privKey.PublicKey.Encapsulate(rand.Reader) - + b.Run(m.name, func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { @@ -463,4 +461,4 @@ func BenchmarkMLKEMDecapsulate(b *testing.B) { } }) } -} \ No newline at end of file +} diff --git a/mpc/mpc.go b/mpc/mpc.go index 431ddd5..0081c8a 100644 --- a/mpc/mpc.go +++ b/mpc/mpc.go @@ -16,7 +16,7 @@ import ( const ( // DefaultThreshold is the default threshold for MPC DefaultThreshold = 3 - + // DefaultParties is the default number of parties DefaultParties = 5 ) @@ -30,20 +30,20 @@ var ( // MPCAccount represents a per-account MPC configuration type MPCAccount struct { - AccountID ids.ShortID - Threshold int - Parties int - PublicKey *PublicKey - Shares map[int]*Share - Protocol Protocol - mu sync.RWMutex + AccountID ids.ShortID + Threshold int + Parties int + PublicKey *PublicKey + Shares map[int]*Share + Protocol Protocol + mu sync.RWMutex } // Share represents a secret share held by a party type Share struct { - Index int - Value *big.Int - Proof []byte + Index int + Value *big.Int + Proof []byte } // PublicKey represents an MPC public key @@ -86,15 +86,15 @@ func (m *Manager) CreateAccount(accountID ids.ShortID, threshold, parties int, p if parties < 2 { return nil, errInvalidParties } - + m.mu.Lock() defer m.mu.Unlock() - + // Check if account already exists if _, exists := m.accounts[accountID]; exists { return nil, errors.New("account already exists") } - + // Generate distributed key account := &MPCAccount{ AccountID: accountID, @@ -103,12 +103,12 @@ func (m *Manager) CreateAccount(accountID ids.ShortID, threshold, parties int, p Shares: make(map[int]*Share), Protocol: protocol, } - + // Generate key shares if err := account.generateKeyShares(); err != nil { return nil, err } - + m.accounts[accountID] = account return account, nil } @@ -117,12 +117,12 @@ func (m *Manager) CreateAccount(accountID ids.ShortID, threshold, parties int, p func (m *Manager) GetAccount(accountID ids.ShortID) (*MPCAccount, error) { m.mu.RLock() defer m.mu.RUnlock() - + account, exists := m.accounts[accountID] if !exists { return nil, errors.New("account not found") } - + return account, nil } @@ -137,10 +137,10 @@ func (a *MPCAccount) generateKeyShares() error { } coeffs[i] = coeff } - + // The secret is the constant term secret := coeffs[0] - + // Generate shares for each party for i := 1; i <= a.Parties; i++ { share := evaluatePolynomial(coeffs, big.NewInt(int64(i))) @@ -150,12 +150,12 @@ func (a *MPCAccount) generateKeyShares() error { Proof: generateShareProof(share, i), } } - + // Compute public key a.PublicKey = &PublicKey{ Point: scalarBaseMult(secret), } - + return nil } @@ -163,22 +163,22 @@ func (a *MPCAccount) generateKeyShares() error { func (a *MPCAccount) Sign(message []byte, participatingShares map[int]*Share) ([]byte, error) { a.mu.RLock() defer a.mu.RUnlock() - + if len(participatingShares) < a.Threshold { return nil, errNotEnoughShares } - + // Verify shares for index, share := range participatingShares { if !a.verifyShare(index, share) { return nil, errInvalidShare } } - + // Compute partial signatures messageHash := sha256.Sum256(message) partialSigs := make(map[int]*big.Int) - + for index, share := range participatingShares { // Simplified partial signature computation // In production, use actual protocol (GG18/GG20/CMP) @@ -186,10 +186,10 @@ func (a *MPCAccount) Sign(message []byte, participatingShares map[int]*Share) ([ partialSig.Mod(partialSig, curveOrder()) partialSigs[index] = partialSig } - + // Combine partial signatures using Lagrange interpolation signature := combinePartialSignatures(partialSigs, a.Threshold) - + return signature.Bytes(), nil } @@ -197,16 +197,16 @@ func (a *MPCAccount) Sign(message []byte, participatingShares map[int]*Share) ([ func (a *MPCAccount) Verify(message []byte, signature []byte) bool { a.mu.RLock() defer a.mu.RUnlock() - + // Simplified verification // In production, implement actual signature verification messageHash := sha256.Sum256(message) sig := new(big.Int).SetBytes(signature) - + // Verify using public key expectedPoint := scalarBaseMult(sig) messagePoint := scalarBaseMult(new(big.Int).SetBytes(messageHash[:])) - + // Check if signature is valid (simplified) return pointsEqual(expectedPoint, messagePoint) } @@ -215,15 +215,15 @@ func (a *MPCAccount) Verify(message []byte, signature []byte) bool { func (a *MPCAccount) AddShare(index int, share *Share) error { a.mu.Lock() defer a.mu.Unlock() - + if index < 1 || index > a.Parties { return errors.New("invalid share index") } - + if !a.verifyShare(index, share) { return errInvalidShare } - + a.Shares[index] = share return nil } @@ -232,12 +232,12 @@ func (a *MPCAccount) AddShare(index int, share *Share) error { func (a *MPCAccount) GetShare(index int) (*Share, error) { a.mu.RLock() defer a.mu.RUnlock() - + share, exists := a.Shares[index] if !exists { return nil, errors.New("share not found") } - + return share, nil } @@ -245,18 +245,18 @@ func (a *MPCAccount) GetShare(index int) (*Share, error) { func (a *MPCAccount) RefreshShares() error { a.mu.Lock() defer a.mu.Unlock() - + // Generate new random polynomial with same secret oldShares := a.Shares a.Shares = make(map[int]*Share) - + // Keep the same secret (constant term) secret := reconstructSecret(oldShares, a.Threshold) - + // Generate new polynomial with same secret coeffs := make([]*big.Int, a.Threshold) coeffs[0] = secret - + for i := 1; i < a.Threshold; i++ { coeff, err := rand.Int(rand.Reader, curveOrder()) if err != nil { @@ -264,7 +264,7 @@ func (a *MPCAccount) RefreshShares() error { } coeffs[i] = coeff } - + // Generate new shares for i := 1; i <= a.Parties; i++ { share := evaluatePolynomial(coeffs, big.NewInt(int64(i))) @@ -274,7 +274,7 @@ func (a *MPCAccount) RefreshShares() error { Proof: generateShareProof(share, i), } } - + return nil } @@ -300,16 +300,16 @@ func pointsEqual(p1, p2 *Point) bool { func evaluatePolynomial(coeffs []*big.Int, x *big.Int) *big.Int { result := new(big.Int).Set(coeffs[0]) xPower := new(big.Int).Set(x) - + for i := 1; i < len(coeffs); i++ { term := new(big.Int).Mul(coeffs[i], xPower) result.Add(result, term) result.Mod(result, curveOrder()) - + xPower.Mul(xPower, x) xPower.Mod(xPower, curveOrder()) } - + return result } @@ -327,33 +327,33 @@ func (a *MPCAccount) verifyShare(index int, share *Share) bool { if len(share.Proof) != len(expectedProof) { return false } - + for i := range expectedProof { if expectedProof[i] != share.Proof[i] { return false } } - + return true } func combinePartialSignatures(partialSigs map[int]*big.Int, threshold int) *big.Int { result := big.NewInt(0) indices := make([]int, 0, len(partialSigs)) - + for index := range partialSigs { indices = append(indices, index) if len(indices) == threshold { break } } - + for _, i := range indices { lagrangeCoeff := computeLagrangeCoefficient(i, indices) term := new(big.Int).Mul(partialSigs[i], lagrangeCoeff) result.Add(result, term) } - + result.Mod(result, curveOrder()) return result } @@ -361,19 +361,19 @@ func combinePartialSignatures(partialSigs map[int]*big.Int, threshold int) *big. func computeLagrangeCoefficient(i int, indices []int) *big.Int { num := big.NewInt(1) den := big.NewInt(1) - + for _, j := range indices { if i != j { num.Mul(num, big.NewInt(int64(-j))) den.Mul(den, big.NewInt(int64(i-j))) } } - + // Compute num/den mod curveOrder denInv := new(big.Int).ModInverse(den, curveOrder()) result := new(big.Int).Mul(num, denInv) result.Mod(result, curveOrder()) - + return result } @@ -381,7 +381,7 @@ func reconstructSecret(shares map[int]*Share, threshold int) *big.Int { if len(shares) < threshold { return nil } - + partialValues := make(map[int]*big.Int) for index, share := range shares { partialValues[index] = share.Value @@ -389,6 +389,6 @@ func reconstructSecret(shares map[int]*Share, threshold int) *big.Int { break } } - + return combinePartialSignatures(partialValues, threshold) -} \ No newline at end of file +} diff --git a/pq_integration_test.go b/pq_integration_test.go index 302cfee..dd72868 100644 --- a/pq_integration_test.go +++ b/pq_integration_test.go @@ -186,4 +186,4 @@ func BenchmarkPQCrypto(b *testing.B) { _, _ = priv.Sign(rand.Reader, message, nil) } }) -} \ No newline at end of file +} diff --git a/precompile/bls.go b/precompile/bls.go index d5a8903..62cec45 100644 --- a/precompile/bls.go +++ b/precompile/bls.go @@ -305,7 +305,6 @@ func (b *BLSHashToPoint) Run(input []byte) ([]byte, error) { return g2Point, nil } - // RegisterBLS registers all BLS precompiles func RegisterBLS(registry *Registry) { registry.Register(BLSVerifyAddress, &BLSVerify{}) diff --git a/precompile/lamport.go b/precompile/lamport.go index 758d4f5..ea267b1 100644 --- a/precompile/lamport.go +++ b/precompile/lamport.go @@ -192,7 +192,7 @@ func (l *LamportBatchVerify) Run(input []byte) ([]byte, error) { continue } - // message is actually a pre-hashed value + // message is actually a pre-hashed value if pubKey.VerifyHash(message, sig) { results[i] = 0x01 } else { diff --git a/precompile/precompile_all_test.go b/precompile/precompile_all_test.go index 063ed15..0c2387d 100644 --- a/precompile/precompile_all_test.go +++ b/precompile/precompile_all_test.go @@ -18,8 +18,8 @@ import ( // Test vectors for SHAKE from NIST var shakeTestVectors = []struct { - name string - input string + name string + input string output128 string // First 32 bytes of SHAKE128 output256 string // First 32 bytes of SHAKE256 }{ @@ -47,22 +47,22 @@ var shakeTestVectors = []struct { func TestSHAKEPrecompiles(t *testing.T) { t.Run("SHAKE128", func(t *testing.T) { shake128 := &SHAKE128{} - + for _, tv := range shakeTestVectors { t.Run(tv.name, func(t *testing.T) { inputData, _ := hex.DecodeString(tv.input) expectedOutput, _ := hex.DecodeString(tv.output128) - + // Create input with 32-byte output length input := make([]byte, 4+len(inputData)) binary.BigEndian.PutUint32(input[:4], 32) copy(input[4:], inputData) - + // Test gas calculation gas := shake128.RequiredGas(input) expectedGas := uint64(60 + 12*((len(input)+31)/32) + 3) assert.Equal(t, expectedGas, gas, "Gas calculation mismatch") - + // Test output output, err := shake128.Run(input) require.NoError(t, err) @@ -73,22 +73,22 @@ func TestSHAKEPrecompiles(t *testing.T) { t.Run("SHAKE256", func(t *testing.T) { shake256 := &SHAKE256{} - + for _, tv := range shakeTestVectors { t.Run(tv.name, func(t *testing.T) { inputData, _ := hex.DecodeString(tv.input) expectedOutput, _ := hex.DecodeString(tv.output256) - + // Create input with 32-byte output length input := make([]byte, 4+len(inputData)) binary.BigEndian.PutUint32(input[:4], 32) copy(input[4:], inputData) - + // Test gas calculation gas := shake256.RequiredGas(input) expectedGas := uint64(60 + 12*((len(input)+31)/32) + 3) assert.Equal(t, expectedGas, gas, "Gas calculation mismatch") - + // Test output output, err := shake256.Run(input) require.NoError(t, err) @@ -100,35 +100,35 @@ func TestSHAKEPrecompiles(t *testing.T) { t.Run("SHAKE256_Fixed", func(t *testing.T) { // Test fixed output variants variants := []struct { - name string + name string precompile PrecompiledContract outputLen int - gas uint64 + gas uint64 }{ {"SHAKE256_256", &SHAKE256_256{}, 32, 200}, {"SHAKE256_512", &SHAKE256_512{}, 64, 250}, {"SHAKE256_1024", &SHAKE256_1024{}, 128, 350}, } - + for _, v := range variants { t.Run(v.name, func(t *testing.T) { input := []byte("test input for fixed shake") - + // Test gas gas := v.precompile.RequiredGas(input) assert.Equal(t, v.gas, gas) - + // Test output length output, err := v.precompile.Run(input) require.NoError(t, err) assert.Len(t, output, v.outputLen) - + // Verify it matches variable SHAKE with same output length shake := &SHAKE256{} varInput := make([]byte, 4+len(input)) binary.BigEndian.PutUint32(varInput[:4], uint32(v.outputLen)) copy(varInput[4:], input) - + varOutput, err := shake.Run(varInput) require.NoError(t, err) assert.Equal(t, varOutput, output, "Fixed and variable SHAKE should match") @@ -139,40 +139,40 @@ func TestSHAKEPrecompiles(t *testing.T) { t.Run("cSHAKE", func(t *testing.T) { cshake128 := &CSHAKE128{} cshake256 := &CSHAKE256{} - + testCases := []struct { - name string + name string customization string - data string - outputLen uint32 + data string + outputLen uint32 }{ {"empty", "", "test", 32}, {"custom", "custom string", "test data", 64}, {"long_custom", "very long customization string for testing", "data", 32}, } - + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { // Build input customBytes := []byte(tc.customization) dataBytes := []byte(tc.data) - + input := make([]byte, 8+len(customBytes)+len(dataBytes)) binary.BigEndian.PutUint32(input[:4], tc.outputLen) binary.BigEndian.PutUint32(input[4:8], uint32(len(customBytes))) copy(input[8:], customBytes) copy(input[8+len(customBytes):], dataBytes) - + // Test CSHAKE128 output128, err := cshake128.Run(input) require.NoError(t, err) assert.Len(t, output128, int(tc.outputLen)) - + // Test CSHAKE256 output256, err := cshake256.Run(input) require.NoError(t, err) assert.Len(t, output256, int(tc.outputLen)) - + // Outputs should be different between 128 and 256 if tc.customization != "" { assert.NotEqual(t, output128, output256) @@ -183,44 +183,44 @@ func TestSHAKEPrecompiles(t *testing.T) { t.Run("EdgeCases", func(t *testing.T) { shake := &SHAKE256{} - + t.Run("MaxOutput", func(t *testing.T) { // Test maximum output size (8192 bytes) input := make([]byte, 4+10) binary.BigEndian.PutUint32(input[:4], 8192) copy(input[4:], []byte("test data")) - + output, err := shake.Run(input) require.NoError(t, err) assert.Len(t, output, 8192) }) - + t.Run("TooLargeOutput", func(t *testing.T) { // Test output size exceeding maximum input := make([]byte, 4+10) binary.BigEndian.PutUint32(input[:4], 8193) copy(input[4:], []byte("test data")) - + _, err := shake.Run(input) assert.Error(t, err) assert.Contains(t, err.Error(), "exceeds maximum") }) - + t.Run("ZeroOutput", func(t *testing.T) { // Test zero output length input := make([]byte, 4+10) binary.BigEndian.PutUint32(input[:4], 0) copy(input[4:], []byte("test data")) - + output, err := shake.Run(input) require.NoError(t, err) assert.Len(t, output, 0) }) - + t.Run("InsufficientInput", func(t *testing.T) { // Test input shorter than 4 bytes input := []byte{0, 0} - + _, err := shake.Run(input) assert.Error(t, err) }) @@ -231,44 +231,44 @@ func TestSHAKEPrecompiles(t *testing.T) { func TestLamportPrecompiles(t *testing.T) { t.Run("LamportVerifySHA256", func(t *testing.T) { verifier := &LamportVerifySHA256{} - + // Generate test key and signature priv, err := lamport.GenerateKey(rand.Reader, lamport.SHA256) require.NoError(t, err) - + // Get public key BEFORE signing (one-time signature clears private key) pubBytes := priv.Public().Bytes() - + message := []byte("test message for lamport") messageHash := sha256.Sum256(message) - + // Sign the hash directly (precompile expects pre-hashed input) sig, err := priv.SignHash(messageHash[:]) require.NoError(t, err) - + // Build precompile input sigBytes := sig.Bytes() - + input := make([]byte, 32+len(sigBytes)+len(pubBytes)) copy(input[:32], messageHash[:]) copy(input[32:], sigBytes) copy(input[32+len(sigBytes):], pubBytes) - + // Test gas gas := verifier.RequiredGas(input) assert.Equal(t, uint64(50000), gas) - + // Test verification (should succeed) output, err := verifier.Run(input) require.NoError(t, err) expected := make([]byte, 32) expected[31] = 1 assert.Equal(t, expected, output, "Valid signature should return 1") - + // Test with wrong message wrongHash := sha256.Sum256([]byte("wrong message")) copy(input[:32], wrongHash[:]) - + output, err = verifier.Run(input) require.NoError(t, err) expected = make([]byte, 32) @@ -277,33 +277,33 @@ func TestLamportPrecompiles(t *testing.T) { t.Run("LamportVerifySHA512", func(t *testing.T) { verifier := &LamportVerifySHA512{} - + // Generate test key and signature priv, err := lamport.GenerateKey(rand.Reader, lamport.SHA512) require.NoError(t, err) - + // Get public key BEFORE signing (one-time signature clears private key) pubBytes := priv.Public().Bytes() - + message := []byte("test message for lamport sha512") messageHash := sha512.Sum512(message) - + // Sign the hash directly (precompile expects pre-hashed input) sig, err := priv.SignHash(messageHash[:]) require.NoError(t, err) - + // Build precompile input sigBytes := sig.Bytes() - + input := make([]byte, 64+len(sigBytes)+len(pubBytes)) copy(input[:64], messageHash[:]) copy(input[64:], sigBytes) copy(input[64+len(sigBytes):], pubBytes) - + // Test gas gas := verifier.RequiredGas(input) assert.Equal(t, uint64(80000), gas) - + // Test verification output, err := verifier.Run(input) require.NoError(t, err) @@ -314,63 +314,63 @@ func TestLamportPrecompiles(t *testing.T) { t.Run("LamportBatchVerify", func(t *testing.T) { batchVerifier := &LamportBatchVerify{} - + // Generate multiple signatures numSigs := 3 var messages [][]byte var sigs []*lamport.Signature var pubs []*lamport.PublicKey - + for i := 0; i < numSigs; i++ { priv, err := lamport.GenerateKey(rand.Reader, lamport.SHA256) require.NoError(t, err) - + // Get public key BEFORE signing pub := priv.Public() pubs = append(pubs, pub) - + message := []byte(fmt.Sprintf("message %d", i)) messages = append(messages, message) - + // Sign the hash directly msgHash := sha256.Sum256(message) sig, err := priv.SignHash(msgHash[:]) require.NoError(t, err) sigs = append(sigs, sig) } - + // Build batch input // Format: [num_sigs(1)][hash_type(1)][data...] // data = [msg_hash][sig][pubkey] repeated - + // Calculate total size hashSize := 32 // SHA256 sigSize := len(sigs[0].Bytes()) pubSize := len(pubs[0].Bytes()) dataSize := numSigs * (hashSize + sigSize + pubSize) - + input := make([]byte, 2+dataSize) input[0] = byte(numSigs) input[1] = 0 // SHA256 - + offset := 2 for i := 0; i < numSigs; i++ { hash := sha256.Sum256(messages[i]) copy(input[offset:], hash[:]) offset += hashSize - + copy(input[offset:], sigs[i].Bytes()) offset += sigSize - + copy(input[offset:], pubs[i].Bytes()) offset += pubSize } - + // Test gas gas := batchVerifier.RequiredGas(input) expectedGas := uint64(30000 + 40000*uint64(numSigs)) assert.Equal(t, expectedGas, gas) - + // Test batch verification output, err := batchVerifier.Run(input) require.NoError(t, err) @@ -380,10 +380,10 @@ func TestLamportPrecompiles(t *testing.T) { for i := 1; i <= numSigs; i++ { assert.Equal(t, byte(1), output[i], fmt.Sprintf("Signature %d should be valid", i-1)) } - + // Corrupt one signature input[2+hashSize] ^= 0xFF - + output, err = batchVerifier.Run(input) require.NoError(t, err) assert.Equal(t, byte(0), output[0], "Any invalid signature should return overall 0") @@ -392,49 +392,49 @@ func TestLamportPrecompiles(t *testing.T) { t.Run("LamportMerkleRoot", func(t *testing.T) { merkleRoot := &LamportMerkleRoot{} - + // Generate multiple public keys numKeys := 4 var pubs []*lamport.PublicKey - + for i := 0; i < numKeys; i++ { priv, err := lamport.GenerateKey(rand.Reader, lamport.SHA256) require.NoError(t, err) pubs = append(pubs, priv.Public()) } - + // Build input // Format: [num_keys(1)][hash_type(1)][pubkeys...] pubSize := len(pubs[0].Bytes()) input := make([]byte, 2+numKeys*pubSize) input[0] = byte(numKeys) input[1] = 0 // SHA256 - + offset := 2 for _, pub := range pubs { copy(input[offset:], pub.Bytes()) offset += pubSize } - + // Test gas gas := merkleRoot.RequiredGas(input) assert.Equal(t, uint64(100000), gas) - + // Test root computation output, err := merkleRoot.Run(input) require.NoError(t, err) assert.Len(t, output, 32, "Merkle root should be 32 bytes") - + // Same keys should produce same root output2, err := merkleRoot.Run(input) require.NoError(t, err) assert.Equal(t, output, output2, "Same keys should produce same root") - + // Different order should produce different root // Swap first two keys copy(input[5:5+pubSize], pubs[1].Bytes()) copy(input[5+pubSize:5+2*pubSize], pubs[0].Bytes()) - + output3, err := merkleRoot.Run(input) require.NoError(t, err) assert.NotEqual(t, output, output3, "Different order should produce different root") @@ -445,19 +445,19 @@ func TestLamportPrecompiles(t *testing.T) { func TestBLSPrecompiles(t *testing.T) { t.Run("BLSVerify", func(t *testing.T) { verifier := &BLSVerify{} - + // Create dummy input (placeholder implementation) // Format: [96 bytes sig][48 bytes pubkey][message] message := []byte("test message for BLS") input := make([]byte, 96+48+len(message)) - rand.Read(input[:96]) // Random signature + rand.Read(input[:96]) // Random signature rand.Read(input[96:144]) // Random pubkey copy(input[144:], message) - + // Test gas gas := verifier.RequiredGas(input) assert.Equal(t, uint64(150000), gas) - + // Test run (placeholder always returns success) output, err := verifier.Run(input) require.NoError(t, err) @@ -466,31 +466,31 @@ func TestBLSPrecompiles(t *testing.T) { t.Run("BLSAggregateVerify", func(t *testing.T) { aggVerifier := &BLSAggregateVerify{} - + // Build aggregate input // Format: [num_sigs(1)][signatures][pubkeys][encoded_messages] numSigs := 3 sigSize := 96 pubSize := 48 msgSize := 32 - + totalSize := 1 + numSigs*(sigSize+pubSize+4+msgSize) input := make([]byte, totalSize) input[0] = byte(numSigs) - + offset := 1 // Add signatures for i := 0; i < numSigs; i++ { rand.Read(input[offset : offset+sigSize]) offset += sigSize } - + // Add public keys for i := 0; i < numSigs; i++ { rand.Read(input[offset : offset+pubSize]) offset += pubSize } - + // Add messages (with length prefixes) for i := 0; i < numSigs; i++ { binary.BigEndian.PutUint32(input[offset:offset+4], uint32(msgSize)) @@ -498,13 +498,13 @@ func TestBLSPrecompiles(t *testing.T) { rand.Read(input[offset : offset+msgSize]) offset += msgSize } - + // Test gas gas := aggVerifier.RequiredGas(input) // blsAggregateVerifyGas = 200000, blsPerSignatureGas = 30000 expectedGas := uint64(200000 + 30000*uint64(numSigs)) assert.Equal(t, expectedGas, gas) - + // Test run output, err := aggVerifier.Run(input) require.NoError(t, err) @@ -513,24 +513,24 @@ func TestBLSPrecompiles(t *testing.T) { t.Run("BLSPublicKeyAggregate", func(t *testing.T) { aggregator := &BLSPublicKeyAggregate{} - + // Build input // Format: [num_keys(1)][pubkeys...] numKeys := 5 pubSize := 48 - + input := make([]byte, 1+numKeys*pubSize) input[0] = byte(numKeys) - + for i := 0; i < numKeys; i++ { rand.Read(input[1+i*pubSize : 1+(i+1)*pubSize]) } - + // Test gas gas := aggregator.RequiredGas(input) expectedGas := uint64(50000 + 10000*uint64(numKeys)) assert.Equal(t, expectedGas, gas) - + // Test run output, err := aggregator.Run(input) require.NoError(t, err) @@ -539,24 +539,24 @@ func TestBLSPrecompiles(t *testing.T) { t.Run("BLSHashToPoint", func(t *testing.T) { hashToPoint := &BLSHashToPoint{} - + // Test with various message sizes messages := [][]byte{ []byte("short"), []byte("medium length message for testing"), bytes.Repeat([]byte("long "), 100), } - + for _, msg := range messages { // Test gas gas := hashToPoint.RequiredGas(msg) assert.Equal(t, uint64(80000), gas) - + // Test run output, err := hashToPoint.Run(msg) require.NoError(t, err) assert.Len(t, output, 96, "Hash to point should produce 96-byte point") - + // Same message should produce same point output2, err := hashToPoint.Run(msg) require.NoError(t, err) @@ -577,16 +577,16 @@ func TestPrecompileRegistry(t *testing.T) { // BLS "0x0160", "0x0161", "0x0162", "0x0163", "0x0164", "0x0165", "0x0166", } - + for _, addr := range expectedAddresses { t.Run(addr, func(t *testing.T) { // Convert hex string to address addrBytes, err := hex.DecodeString(addr[2:]) require.NoError(t, err) - + var address [20]byte copy(address[20-len(addrBytes):], addrBytes) - + precompile, exists := PostQuantumRegistry.contracts[address] assert.True(t, exists, "Address %s should be registered", addr) assert.NotNil(t, precompile, "Precompile at %s should not be nil", addr) @@ -599,14 +599,14 @@ func TestPrecompileRegistry(t *testing.T) { shake256Addr := [20]byte{} shake256Addr[18] = 0x01 shake256Addr[19] = 0x43 - + input := make([]byte, 36) binary.BigEndian.PutUint32(input[:4], 32) copy(input[4:], []byte("test")) - + gas := GetGasEstimate(shake256Addr, len(input)) assert.Greater(t, gas, uint64(0), "Should return non-zero gas estimate") - + // Test unknown address unknownAddr := [20]byte{0xFF} gas = GetGasEstimate(unknownAddr, len(input)) @@ -615,13 +615,13 @@ func TestPrecompileRegistry(t *testing.T) { t.Run("Info", func(t *testing.T) { info := Info() - + // Check expected keys exist assert.Contains(t, info, "total_precompiles") assert.Contains(t, info, "cgo_enabled") assert.Contains(t, info, "standards") assert.Contains(t, info, "address_ranges") - + // Check total precompiles count totalPrecompiles, ok := info["total_precompiles"].(int) assert.True(t, ok, "total_precompiles should be an int") @@ -644,12 +644,12 @@ func TestErrorHandling(t *testing.T) { &LamportVerifySHA256{}, &BLSVerify{}, } - + for _, p := range precompiles { // Empty input _, err := p.Run([]byte{}) assert.Error(t, err, "%T should error on empty input", p) - + // Too short input _, err = p.Run([]byte{0, 1, 2}) assert.Error(t, err, "%T should error on short input", p) @@ -661,23 +661,23 @@ func TestErrorHandling(t *testing.T) { shake := &SHAKE256{} input := make([]byte, 8) binary.BigEndian.PutUint32(input[:4], 8193) // Too large - + _, err := shake.Run(input) assert.Error(t, err) assert.Contains(t, err.Error(), "exceeds maximum") - + // Batch verify with 0 signatures // batch := &LamportBatchVerify{} // input = []byte{0, 0} // [num_sigs=0][hash_type=0] - + // Note: 0 signatures might be valid (empty batch), so skip this test // _, err = batch.Run(input) // assert.Error(t, err) - + // BLS aggregate with mismatched counts // agg := &BLSAggregateVerify{} // input = []byte{10} // Claims 10 sigs but no data (1 byte format) - + // _, err = agg.Run(input) // Note: This might not error immediately, depends on implementation // assert.Error(t, err) @@ -687,12 +687,12 @@ func TestErrorHandling(t *testing.T) { // Test that similar errors have consistent messages shake128 := &SHAKE128{} shake256 := &SHAKE256{} - + shortInput := []byte{0, 1} - + _, err1 := shake128.Run(shortInput) _, err2 := shake256.Run(shortInput) - + if err1 != nil && err2 != nil { // Both should have similar error messages // They both say "input too short" which is consistent @@ -709,7 +709,7 @@ func BenchmarkPrecompiles(b *testing.B) { input := make([]byte, 36) binary.BigEndian.PutUint32(input[:4], 32) copy(input[4:], bytes.Repeat([]byte("x"), 32)) - + b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = shake.Run(input) @@ -719,7 +719,7 @@ func BenchmarkPrecompiles(b *testing.B) { b.Run("SHAKE256_1024bytes", func(b *testing.B) { shake := &SHAKE256_1024{} input := bytes.Repeat([]byte("x"), 128) - + b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = shake.Run(input) @@ -728,21 +728,21 @@ func BenchmarkPrecompiles(b *testing.B) { b.Run("LamportVerify", func(b *testing.B) { verifier := &LamportVerifySHA256{} - + // Generate a signature once priv, _ := lamport.GenerateKey(rand.Reader, lamport.SHA256) message := []byte("benchmark message") sig, _ := priv.Sign(message) - + messageHash := sha256.Sum256(message) sigBytes := sig.Bytes() pubBytes := priv.Public().Bytes() - + input := make([]byte, 32+len(sigBytes)+len(pubBytes)) copy(input[:32], messageHash[:]) copy(input[32:], sigBytes) copy(input[32+len(sigBytes):], pubBytes) - + b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = verifier.Run(input) @@ -751,10 +751,10 @@ func BenchmarkPrecompiles(b *testing.B) { b.Run("BLSVerify", func(b *testing.B) { verifier := &BLSVerify{} - + input := make([]byte, 96+48+32) rand.Read(input) - + b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = verifier.Run(input) @@ -768,34 +768,34 @@ func TestCrossPrecompileWorkflows(t *testing.T) { // Use SHAKE to hash, then Lamport to sign shake := &SHAKE256_256{} lamportVerify := &LamportVerifySHA256{} - + // Original message message := []byte("cross-precompile test message") - + // Hash with SHAKE256 hashedOutput, err := shake.Run(message) require.NoError(t, err) assert.Len(t, hashedOutput, 32) - + // Generate Lamport signature on the hash priv, err := lamport.GenerateKey(rand.Reader, lamport.SHA256) require.NoError(t, err) - + // Get public key BEFORE signing pubBytes := priv.Public().Bytes() - + // Sign the hash directly (not Sign which hashes again) sig, err := priv.SignHash(hashedOutput) require.NoError(t, err) - + // Build verification input sigBytes := sig.Bytes() - + verifyInput := make([]byte, 32+len(sigBytes)+len(pubBytes)) copy(verifyInput[:32], hashedOutput) copy(verifyInput[32:], sigBytes) copy(verifyInput[32+len(sigBytes):], pubBytes) - + // Verify result, err := lamportVerify.Run(verifyInput) require.NoError(t, err) @@ -808,39 +808,39 @@ func TestCrossPrecompileWorkflows(t *testing.T) { // Create merkle root of keys, then batch verify signatures merkleRoot := &LamportMerkleRoot{} batchVerify := &LamportBatchVerify{} - + // Generate multiple keys numKeys := 3 var privKeys []*lamport.PrivateKey var pubKeys []*lamport.PublicKey - + for i := 0; i < numKeys; i++ { priv, err := lamport.GenerateKey(rand.Reader, lamport.SHA256) require.NoError(t, err) privKeys = append(privKeys, priv) pubKeys = append(pubKeys, priv.Public()) } - + // Compute merkle root pubSize := len(pubKeys[0].Bytes()) rootInput := make([]byte, 2+numKeys*pubSize) rootInput[0] = byte(numKeys) rootInput[1] = 0 // SHA256 - + offset := 2 for _, pub := range pubKeys { copy(rootInput[offset:], pub.Bytes()) offset += pubSize } - + root, err := merkleRoot.Run(rootInput) require.NoError(t, err) assert.Len(t, root, 32) - + // Create signatures with the same keys messages := make([][]byte, numKeys) sigs := make([]*lamport.Signature, numKeys) - + for i := 0; i < numKeys; i++ { messages[i] = []byte(fmt.Sprintf("message %d", i)) msgHash := sha256.Sum256(messages[i]) @@ -848,27 +848,27 @@ func TestCrossPrecompileWorkflows(t *testing.T) { require.NoError(t, err) sigs[i] = sig } - + // Batch verify hashSize := 32 sigSize := len(sigs[0].Bytes()) batchInput := make([]byte, 2+numKeys*(hashSize+sigSize+pubSize)) batchInput[0] = byte(numKeys) batchInput[1] = 0 // SHA256 - + offset = 2 for i := 0; i < numKeys; i++ { hash := sha256.Sum256(messages[i]) copy(batchInput[offset:], hash[:]) offset += hashSize - + copy(batchInput[offset:], sigs[i].Bytes()) offset += sigSize - + copy(batchInput[offset:], pubKeys[i].Bytes()) offset += pubSize } - + result, err := batchVerify.Run(batchInput) require.NoError(t, err) // Batch verify returns [overall_valid][individual_results...] @@ -877,7 +877,7 @@ func TestCrossPrecompileWorkflows(t *testing.T) { for i := 1; i <= numKeys; i++ { assert.Equal(t, byte(1), result[i], fmt.Sprintf("Signature %d should be valid", i-1)) } - + t.Logf("Merkle root: %x", root) t.Log("All signatures verified in batch") }) @@ -886,17 +886,17 @@ func TestCrossPrecompileWorkflows(t *testing.T) { // Helper function to compare SHAKE output with reference implementation func verifyShakeOutput(t *testing.T, input []byte, outputLen int, isShake256 bool) []byte { t.Helper() - + var h sha3.ShakeHash if isShake256 { h = sha3.NewShake256() } else { h = sha3.NewShake128() } - + h.Write(input) output := make([]byte, outputLen) h.Read(output) - + return output -} \ No newline at end of file +} diff --git a/precompile/shake.go b/precompile/shake.go index 56f6a92..559307e 100644 --- a/precompile/shake.go +++ b/precompile/shake.go @@ -45,7 +45,7 @@ func (s *SHAKE128) RequiredGas(input []byte) uint64 { return shakeBaseGas } outputLen := uint32(input[0])<<24 | uint32(input[1])<<16 | uint32(input[2])<<8 | uint32(input[3]) - inputWords := uint64((len(input) + 31) / 32) // Include the 4-byte length in gas calculation + inputWords := uint64((len(input) + 31) / 32) // Include the 4-byte length in gas calculation outputWords := uint64((outputLen + 31) / 32) return shakeBaseGas + inputWords*shakePerWordGas + outputWords*shakeOutputGas } @@ -76,7 +76,7 @@ func (s *SHAKE256) RequiredGas(input []byte) uint64 { return shakeBaseGas } outputLen := uint32(input[0])<<24 | uint32(input[1])<<16 | uint32(input[2])<<8 | uint32(input[3]) - inputWords := uint64((len(input) + 31) / 32) // Include the 4-byte length in gas calculation + inputWords := uint64((len(input) + 31) / 32) // Include the 4-byte length in gas calculation outputWords := uint64((outputLen + 31) / 32) return shakeBaseGas + inputWords*shakePerWordGas + outputWords*shakeOutputGas } diff --git a/secp256k1/bench_test.go b/secp256k1/bench_test.go index 8c51762..97b7320 100644 --- a/secp256k1/bench_test.go +++ b/secp256k1/bench_test.go @@ -10,10 +10,10 @@ import ( func BenchmarkSignNoCGO(b *testing.B) { msg := make([]byte, 32) rand.Read(msg) - + seckey := make([]byte, 32) rand.Read(seckey) - + b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = Sign(msg, seckey) @@ -23,12 +23,12 @@ func BenchmarkSignNoCGO(b *testing.B) { func BenchmarkRecoverNoCGO(b *testing.B) { msg := make([]byte, 32) rand.Read(msg) - + seckey := make([]byte, 32) rand.Read(seckey) - + sig, _ := Sign(msg, seckey) - + b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = RecoverPubkey(msg, sig) @@ -38,18 +38,18 @@ func BenchmarkRecoverNoCGO(b *testing.B) { func BenchmarkVerifySignature(b *testing.B) { msg := make([]byte, 32) rand.Read(msg) - + seckey := make([]byte, 32) rand.Read(seckey) - + sig, _ := Sign(msg, seckey) pubkey, _ := RecoverPubkey(msg, sig) - + // Remove recovery ID for verification sigNoRecovery := sig[:64] - + b.ResetTimer() for i := 0; i < b.N; i++ { VerifySignature(pubkey, msg, sigNoRecovery) } -} \ No newline at end of file +} diff --git a/secp256k1/scalar_mult_nocgo.go b/secp256k1/scalar_mult_nocgo.go index 79c8082..f9b094b 100644 --- a/secp256k1/scalar_mult_nocgo.go +++ b/secp256k1/scalar_mult_nocgo.go @@ -15,17 +15,17 @@ import ( func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { // Convert scalar to big.Int k := new(big.Int).SetBytes(scalar) - + // Handle special cases if k.Sign() == 0 { return new(big.Int), new(big.Int) } - + // Use the double-and-add algorithm // Start with the identity point (0, 0) x, y := new(big.Int), new(big.Int) addX, addY := new(big.Int).Set(Bx), new(big.Int).Set(By) - + // Process each bit of k from least significant to most significant for i := 0; i < k.BitLen(); i++ { if k.Bit(i) == 1 { @@ -42,6 +42,6 @@ func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, // Double the point for the next bit addX, addY = bitCurve.Double(addX, addY) } - + return x, y -} \ No newline at end of file +} diff --git a/secp256k1/sig_fuzz_test.go b/secp256k1/sig_fuzz_test.go index d50a1d4..c7000c1 100644 --- a/secp256k1/sig_fuzz_test.go +++ b/secp256k1/sig_fuzz_test.go @@ -16,7 +16,7 @@ func FuzzSignatureVerification(f *testing.F) { // Seed corpus with valid and invalid signatures f.Add(bytes.Repeat([]byte{0}, 32), bytes.Repeat([]byte{0}, 65)) f.Add(bytes.Repeat([]byte{0xff}, 32), bytes.Repeat([]byte{0xff}, 65)) - + // Add a valid signature privKey := make([]byte, 32) privKey[31] = 1 // Simple valid private key @@ -24,17 +24,17 @@ func FuzzSignatureVerification(f *testing.F) { if sig, err := Sign(msg, privKey); err == nil { f.Add(msg, sig) } - + // Add signatures with different recovery IDs validSig := make([]byte, 65) copy(validSig[:32], bytes.Repeat([]byte{0xaa}, 32)) copy(validSig[32:64], bytes.Repeat([]byte{0xbb}, 32)) validSig[64] = 0 f.Add(hashing.ComputeHash256([]byte("test")), validSig) - + validSig[64] = 1 f.Add(hashing.ComputeHash256([]byte("test2")), validSig) - + f.Fuzz(func(t *testing.T, msg []byte, sig []byte) { // Ensure msg is 32 bytes (hash size) if len(msg) != 32 { @@ -44,23 +44,23 @@ func FuzzSignatureVerification(f *testing.F) { msg = msg[:32] } } - + // Try to recover public key - should not panic pubKey, err := RecoverPubkey(msg, sig) if err != nil { // Expected for invalid signatures return } - + // If recovery succeeded, verify the public key is valid if len(pubKey) != 65 && len(pubKey) != 33 { t.Errorf("Invalid public key length: %d", len(pubKey)) } - + // Try to verify signature with recovered key valid := VerifySignature(pubKey, msg, sig[:64]) _ = valid // Result doesn't matter, just ensure no panic - + // Test decompression if compressed if len(pubKey) == 33 { decompressed, err := DecompressPubkey(pubKey) @@ -79,16 +79,16 @@ func FuzzSignatureCreation(f *testing.F) { // Seed corpus f.Add(bytes.Repeat([]byte{0x01}, 32), bytes.Repeat([]byte{0x02}, 32)) f.Add(bytes.Repeat([]byte{0xff}, 32), hashing.ComputeHash256([]byte("test"))) - + // Add some valid private keys validKey1 := make([]byte, 32) validKey1[31] = 1 f.Add(validKey1, hashing.ComputeHash256([]byte("message1"))) - + validKey2 := make([]byte, 32) copy(validKey2, []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}) f.Add(validKey2, hashing.ComputeHash256([]byte("message2"))) - + f.Fuzz(func(t *testing.T, privKey []byte, msg []byte) { // Ensure proper sizes if len(privKey) != 32 { @@ -98,7 +98,7 @@ func FuzzSignatureCreation(f *testing.F) { privKey = privKey[:32] } } - + if len(msg) != 32 { if len(msg) < 32 { msg = append(msg, bytes.Repeat([]byte{0}, 32-len(msg))...) @@ -106,32 +106,32 @@ func FuzzSignatureCreation(f *testing.F) { msg = msg[:32] } } - + // Try to sign sig, err := Sign(msg, privKey) if err != nil { // Expected for invalid private keys return } - + // Signature should be 65 bytes if len(sig) != 65 { t.Errorf("Invalid signature length: %d", len(sig)) return } - + // Recovery ID should be 0 or 1 if sig[64] > 1 { t.Errorf("Invalid recovery ID: %d", sig[64]) } - + // Try to recover public key pubKey, err := RecoverPubkey(msg, sig) if err != nil { t.Errorf("Failed to recover public key from signature we created: %v", err) return } - + // Verify signature with recovered key valid := VerifySignature(pubKey, msg, sig[:64]) if !valid { @@ -143,10 +143,10 @@ func FuzzSignatureCreation(f *testing.F) { // FuzzPublicKeyCompression tests public key compression/decompression func FuzzPublicKeyCompression(f *testing.F) { // Seed corpus with various public key representations - f.Add(bytes.Repeat([]byte{0x04}, 65)) // Uncompressed prefix - f.Add(bytes.Repeat([]byte{0x02}, 33)) // Compressed even Y - f.Add(bytes.Repeat([]byte{0x03}, 33)) // Compressed odd Y - + f.Add(bytes.Repeat([]byte{0x04}, 65)) // Uncompressed prefix + f.Add(bytes.Repeat([]byte{0x02}, 33)) // Compressed even Y + f.Add(bytes.Repeat([]byte{0x03}, 33)) // Compressed odd Y + // Generate a valid public key privKey := make([]byte, 32) privKey[31] = 42 @@ -156,7 +156,7 @@ func FuzzPublicKeyCompression(f *testing.F) { f.Add(pubKey) } } - + f.Fuzz(func(t *testing.T, pubKeyData []byte) { // Test compression if uncompressed if len(pubKeyData) == 65 && pubKeyData[0] == 0x04 { @@ -165,19 +165,19 @@ func FuzzPublicKeyCompression(f *testing.F) { t.Errorf("Compressed public key has wrong length: %d", len(compressed)) return } - + // Try to decompress back decompressed, err := DecompressPubkey(compressed) if err != nil { // Some points might not be on the curve return } - + if len(decompressed) != 65 { t.Errorf("Decompressed public key has wrong length: %d", len(decompressed)) } } - + // Test decompression if compressed if len(pubKeyData) == 33 && (pubKeyData[0] == 0x02 || pubKeyData[0] == 0x03) { decompressed, err := DecompressPubkey(pubKeyData) @@ -185,12 +185,12 @@ func FuzzPublicKeyCompression(f *testing.F) { // Expected for invalid compressed keys return } - + if len(decompressed) != 65 { t.Errorf("Decompressed public key has wrong length: %d", len(decompressed)) return } - + // Compress again and verify round-trip recompressed := CompressPubkey(decompressed[1:33], decompressed[33:65]) if !bytes.Equal(recompressed, pubKeyData) { @@ -206,7 +206,7 @@ func FuzzSignatureMalleability(f *testing.F) { // Seed corpus f.Add(bytes.Repeat([]byte{0x7f}, 32), bytes.Repeat([]byte{0x80}, 32), uint8(0)) f.Add(bytes.Repeat([]byte{0xff}, 32), bytes.Repeat([]byte{0x01}, 32), uint8(1)) - + f.Fuzz(func(t *testing.T, r []byte, s []byte, v uint8) { // Ensure proper sizes if len(r) != 32 { @@ -216,7 +216,7 @@ func FuzzSignatureMalleability(f *testing.F) { r = r[:32] } } - + if len(s) != 32 { if len(s) < 32 { s = append(s, bytes.Repeat([]byte{0}, 32-len(s))...) @@ -224,23 +224,23 @@ func FuzzSignatureMalleability(f *testing.F) { s = s[:32] } } - + // Create signature sig := make([]byte, 65) copy(sig[:32], r) copy(sig[32:64], s) sig[64] = v & 1 // Ensure v is 0 or 1 - + // Create a random message msg := hashing.ComputeHash256(append(r, s...)) - + // Try to verify - should not panic pubKey, err := RecoverPubkey(msg, sig) if err != nil { // Expected for invalid signatures return } - + // Try signature verification valid := VerifySignature(pubKey, msg, sig[:64]) _ = valid // Don't care about result, just ensure no panic @@ -252,15 +252,15 @@ func FuzzECDSAEdgeCases(f *testing.F) { // Seed corpus with edge cases f.Add([]byte{}, []byte{}) f.Add(nil, nil) - + // All zeros zeros := make([]byte, 32) f.Add(zeros, zeros) - + // All ones ones := bytes.Repeat([]byte{0xff}, 32) f.Add(ones, ones) - + // Near the curve order nearOrder := make([]byte, 32) copy(nearOrder, []byte{ @@ -270,7 +270,7 @@ func FuzzECDSAEdgeCases(f *testing.F) { 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, }) f.Add(nearOrder, hashing.ComputeHash256([]byte("edge"))) - + f.Fuzz(func(t *testing.T, privKey []byte, msg []byte) { // Handle nil and empty cases if privKey == nil { @@ -279,20 +279,20 @@ func FuzzECDSAEdgeCases(f *testing.F) { if msg == nil { msg = make([]byte, 32) } - + // Ensure proper sizes if len(privKey) < 32 { privKey = append(privKey, bytes.Repeat([]byte{0}, 32-len(privKey))...) } else if len(privKey) > 32 { privKey = privKey[:32] } - + if len(msg) < 32 { msg = append(msg, bytes.Repeat([]byte{0}, 32-len(msg))...) } else if len(msg) > 32 { msg = msg[:32] } - + // Test signing sig, err := Sign(msg, privKey) if err != nil { @@ -305,25 +305,25 @@ func FuzzECDSAEdgeCases(f *testing.F) { t.Errorf("Unexpected error type: %v", err) return } - + // If signing succeeded, verify signature properties if len(sig) != 65 { t.Errorf("Invalid signature length: %d", len(sig)) return } - + // Check recovery ID if sig[64] > 1 { t.Errorf("Invalid recovery ID: %d", sig[64]) } - + // Try recovery pubKey, err := RecoverPubkey(msg, sig) if err != nil { t.Errorf("Failed to recover public key from valid signature: %v", err) return } - + // Verify the signature if !VerifySignature(pubKey, msg, sig[:64]) { t.Error("Signature verification failed for edge case") @@ -338,4 +338,4 @@ func randomBytes(t *testing.T, n int) []byte { t.Fatal(err) } return b -} \ No newline at end of file +} diff --git a/sign/mldsa.go b/sign/mldsa.go index ab7c81c..78c2551 100644 --- a/sign/mldsa.go +++ b/sign/mldsa.go @@ -12,28 +12,28 @@ import ( type SigID string const ( - MLDSA2 SigID = "mldsa2" - MLDSA3 SigID = "mldsa3" - SLHDSA SigID = "slhdsa" + MLDSA2 SigID = "mldsa2" + MLDSA3 SigID = "mldsa3" + SLHDSA SigID = "slhdsa" ) // Signer interface for signature algorithms type Signer interface { // GenerateKeyPair generates a new signing key pair GenerateKeyPair() (PublicKey, PrivateKey, error) - + // Sign creates a signature Sign(sk PrivateKey, message []byte) ([]byte, error) - + // Verify verifies a signature Verify(pk PublicKey, message, signature []byte) bool - + // PublicKeySize returns the size of public keys PublicKeySize() int - + // PrivateKeySize returns the size of private keys PrivateKeySize() int - + // SignatureSize returns the size of signatures SignatureSize() int } @@ -81,7 +81,7 @@ const ( func (m *MLDSA2Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { // Placeholder for actual ML-DSA key generation // In production, this would use liboqs or native implementation - + pk := &MLDSA2PublicKey{ data: make([]byte, mldsa2PublicKeySize), } @@ -89,7 +89,7 @@ func (m *MLDSA2Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { data: make([]byte, mldsa2PrivateKeySize), pk: pk, } - + // Generate random key material (placeholder) if _, err := rand.Read(pk.data); err != nil { return nil, nil, err @@ -97,7 +97,7 @@ func (m *MLDSA2Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { if _, err := rand.Read(sk.data); err != nil { return nil, nil, err } - + return pk, sk, nil } @@ -107,18 +107,18 @@ func (m *MLDSA2Impl) Sign(sk PrivateKey, message []byte) ([]byte, error) { if !ok { return nil, errors.New("invalid private key type") } - + signature := make([]byte, mldsa2SignatureSize) - + // Placeholder for actual ML-DSA signing if _, err := rand.Read(signature); err != nil { return nil, err } - + // In production, this would perform actual ML-DSA signing _ = mldsaSK.data _ = message - + return signature, nil } @@ -128,17 +128,17 @@ func (m *MLDSA2Impl) Verify(pk PublicKey, message, signature []byte) bool { if !ok { return false } - + if len(signature) != mldsa2SignatureSize { return false } - + // Placeholder for actual ML-DSA verification // In production, this would perform actual verification _ = mldsaPK.data _ = message _ = signature - + // Placeholder: always return true for now return true } @@ -202,25 +202,25 @@ func (m *MLDSA3Impl) GenerateKeyPair() (PublicKey, PrivateKey, error) { data: make([]byte, mldsa3PrivateKeySize), pk: pk, } - + if _, err := rand.Read(pk.data); err != nil { return nil, nil, err } if _, err := rand.Read(sk.data); err != nil { return nil, nil, err } - + return pk, sk, nil } // Sign creates a signature func (m *MLDSA3Impl) Sign(sk PrivateKey, message []byte) ([]byte, error) { signature := make([]byte, mldsa3SignatureSize) - + if _, err := rand.Read(signature); err != nil { return nil, err } - + return signature, nil } @@ -229,7 +229,7 @@ func (m *MLDSA3Impl) Verify(pk PublicKey, message, signature []byte) bool { if len(signature) != mldsa3SignatureSize { return false } - + // Placeholder return true } @@ -273,7 +273,7 @@ func (ts *TranscriptSigner) SignTranscript(transcript []byte) ([]byte, error) { // Add context string to prevent cross-protocol attacks context := []byte("QZMQ-Transcript-v1") message := append(context, transcript...) - + return ts.signer.Sign(ts.sk, message) } @@ -281,6 +281,6 @@ func (ts *TranscriptSigner) SignTranscript(transcript []byte) ([]byte, error) { func VerifyTranscript(signer Signer, pk PublicKey, transcript, signature []byte) bool { context := []byte("QZMQ-Transcript-v1") message := append(context, transcript...) - + return signer.Verify(pk, message, signature) -} \ No newline at end of file +} diff --git a/slhdsa/.old/optimization.go b/slhdsa/.old/optimization.go index 284dd63..9ee052c 100644 --- a/slhdsa/.old/optimization.go +++ b/slhdsa/.old/optimization.go @@ -18,7 +18,7 @@ type OptimizedSLHDSA struct { // NewOptimized creates an optimized SLH-DSA instance func NewOptimized(mode Mode) *OptimizedSLHDSA { numWorkers := runtime.NumCPU() - + return &OptimizedSLHDSA{ mode: mode, cachePool: &sync.Pool{ @@ -44,11 +44,11 @@ func (o *OptimizedSLHDSA) OptimizedSign(privateKey *PrivateKey, message []byte) // Acquire worker slot o.workerPool <- struct{}{} defer func() { <-o.workerPool }() - + // Get cache buffer from pool cache := o.cachePool.Get().([]byte) defer o.cachePool.Put(cache) - + // Use optimized signing based on mode switch o.mode { case SLHDSA128f: @@ -125,7 +125,7 @@ func (o *OptimizedSLHDSA) optimizedSignGeneric(sk *PrivateKey, msg []byte, cache func (o *OptimizedSLHDSA) processTreeOptimized(treeIdx int, sk *PrivateKey, msg []byte, sig []byte, cache []byte) { // Cache-friendly tree traversal // Use cache buffer for intermediate values - + // Placeholder for actual tree processing // Real implementation would compute Merkle tree with optimizations } @@ -134,7 +134,7 @@ func (o *OptimizedSLHDSA) processTreeOptimized(treeIdx int, sk *PrivateKey, msg func (o *OptimizedSLHDSA) processTreesSequential(sk *PrivateKey, msg []byte, sig []byte, cache []byte) { // Sequential processing with minimal memory footprint // Reuse cache buffer for each tree - + // Placeholder for actual sequential processing } @@ -142,7 +142,7 @@ func (o *OptimizedSLHDSA) processTreesSequential(sk *PrivateKey, msg []byte, sig func (o *OptimizedSLHDSA) signWithSIMD(sk *PrivateKey, msg []byte, sig []byte, cache []byte, n, w, h, d int) { // SIMD-accelerated signing // Uses vector instructions for parallel hash computations - + // This would call assembly implementations for different architectures switch runtime.GOARCH { case "amd64": @@ -179,11 +179,11 @@ func (o *OptimizedSLHDSA) OptimizedVerify(publicKey *PublicKey, message []byte, // Acquire worker slot o.workerPool <- struct{}{} defer func() { <-o.workerPool }() - + // Get cache buffer from pool cache := o.cachePool.Get().([]byte) defer o.cachePool.Put(cache) - + // Parallel verification of Merkle paths return o.verifyOptimized(publicKey, message, signature, cache) } @@ -240,28 +240,28 @@ func (o *OptimizedSLHDSA) RunBenchmark(config BenchmarkConfig) BenchmarkResult { sk, _ := GenerateKey(rand.Reader, config.Mode) pk := &sk.PublicKey message := make([]byte, config.MessageSize) - + // Benchmark signing startSign := nanotime() for i := 0; i < config.Iterations; i++ { o.OptimizedSign(sk, message) } result.SignTime = (nanotime() - startSign) / int64(config.Iterations) - + // Generate signature for verification benchmark sig, _ := o.OptimizedSign(sk, message) - + // Benchmark verification startVerify := nanotime() for i := 0; i < config.Iterations; i++ { o.OptimizedVerify(pk, message, sig) } result.VerifyTime = (nanotime() - startVerify) / int64(config.Iterations) - + // Calculate operations per second result.SignOpsPerSec = 1e9 / float64(result.SignTime) result.VerifyOpsPerSec = 1e9 / float64(result.VerifyTime) - + return result } @@ -269,8 +269,8 @@ func (o *OptimizedSLHDSA) RunBenchmark(config BenchmarkConfig) BenchmarkResult { type BenchmarkResult struct { Mode Mode MessageSize int - SignTime int64 // nanoseconds - VerifyTime int64 // nanoseconds + SignTime int64 // nanoseconds + VerifyTime int64 // nanoseconds SignOpsPerSec float64 VerifyOpsPerSec float64 } @@ -285,10 +285,10 @@ func nanotime() int64 { var ( // Precomputed hash chains for common operations precomputedChains = make(map[Mode][]byte) - + // Lookup tables for Winternitz chains winternitzTables = make(map[Mode][][]byte) - + // Once ensures precomputation happens only once precomputeOnce sync.Once ) @@ -298,11 +298,11 @@ func InitPrecomputation() { precomputeOnce.Do(func() { // Precompute for each mode modes := []Mode{SLHDSA128f, SLHDSA128s, SLHDSA192f, SLHDSA192s, SLHDSA256f, SLHDSA256s} - + for _, mode := range modes { // Precompute hash chains precomputeHashChains(mode) - + // Precompute Winternitz tables precomputeWinternitz(mode) } @@ -321,4 +321,4 @@ func precomputeWinternitz(mode Mode) { // Placeholder for Winternitz precomputation // Real implementation would compute chain values winternitzTables[mode] = make([][]byte, 16) -} \ No newline at end of file +} diff --git a/slhdsa/.old/optimization_test.go b/slhdsa/.old/optimization_test.go index 7ec09d6..3c6d9c2 100644 --- a/slhdsa/.old/optimization_test.go +++ b/slhdsa/.old/optimization_test.go @@ -18,14 +18,14 @@ func TestOptimizedPerformance(t *testing.T) { SLHDSA256f, SLHDSA256s, } - + // Initialize precomputation tables InitPrecomputation() - + for _, mode := range modes { t.Run(fmt.Sprintf("Mode_%v", mode), func(t *testing.T) { opt := NewOptimized(mode) - + // Generate test key pair priv, err := GenerateKey(rand.Reader, mode) if err != nil { @@ -33,21 +33,21 @@ func TestOptimizedPerformance(t *testing.T) { } sk := priv pk := &priv.PublicKey - + message := []byte("Test message for optimization benchmarks") - + // Test optimized signing sig, err := opt.OptimizedSign(sk, message) if err != nil { t.Fatalf("Optimized signing failed: %v", err) } - + // Test optimized verification valid := opt.OptimizedVerify(pk, message, sig) if !valid { t.Error("Optimized verification failed") } - + // Verify signature size expectedSize := opt.getSignatureSize() if len(sig) != expectedSize { @@ -70,15 +70,15 @@ func BenchmarkOptimizedSigning(b *testing.B) { {SLHDSA256f, "256f"}, {SLHDSA256s, "256s"}, } - + InitPrecomputation() message := make([]byte, 32) - + for _, bm := range benchmarks { b.Run(bm.name, func(b *testing.B) { opt := NewOptimized(bm.mode) sk, _ := GenerateKey(rand.Reader, bm.mode) - + b.ResetTimer() for i := 0; i < b.N; i++ { opt.OptimizedSign(sk, message) @@ -100,10 +100,10 @@ func BenchmarkOptimizedVerification(b *testing.B) { {SLHDSA256f, "256f"}, {SLHDSA256s, "256s"}, } - + InitPrecomputation() message := make([]byte, 32) - + for _, bm := range benchmarks { b.Run(bm.name, func(b *testing.B) { opt := NewOptimized(bm.mode) @@ -111,7 +111,7 @@ func BenchmarkOptimizedVerification(b *testing.B) { sk := priv pk := &priv.PublicKey sig, _ := opt.OptimizedSign(sk, message) - + b.ResetTimer() for i := 0; i < b.N; i++ { opt.OptimizedVerify(pk, message, sig) @@ -135,11 +135,11 @@ func BenchmarkComparison(b *testing.B) { // Verify is not needed in benchmark } }) - + b.Run("Optimized", func(b *testing.B) { opt := NewOptimized(mode) InitPrecomputation() - + b.ResetTimer() for i := 0; i < b.N; i++ { sig, _ := opt.OptimizedSign(sk, message) @@ -158,33 +158,33 @@ func TestParallelPerformance(t *testing.T) { sk := priv pk := &priv.PublicKey message := make([]byte, 32) - + // Test different CPU counts cpuCounts := []int{1, 2, 4, 8} - + for _, cpus := range cpuCounts { if cpus > runtime.NumCPU() { continue } - + t.Run(fmt.Sprintf("CPUs_%d", cpus), func(t *testing.T) { runtime.GOMAXPROCS(cpus) - + start := time.Now() iterations := 100 - + for i := 0; i < iterations; i++ { sig, _ := opt.OptimizedSign(sk, message) opt.OptimizedVerify(pk, message, sig) } - + elapsed := time.Since(start) opsPerSec := float64(iterations) / elapsed.Seconds() - + t.Logf("CPUs: %d, Ops/sec: %.2f", cpus, opsPerSec) }) } - + // Reset to default runtime.GOMAXPROCS(runtime.NumCPU()) } @@ -192,7 +192,7 @@ func TestParallelPerformance(t *testing.T) { // TestMemoryUsage tests memory efficiency of optimizations func TestMemoryUsage(t *testing.T) { modes := []Mode{SLHDSA128f, SLHDSA128s} - + for _, mode := range modes { t.Run(fmt.Sprintf("Mode_%v", mode), func(t *testing.T) { opt := NewOptimized(mode) @@ -200,22 +200,22 @@ func TestMemoryUsage(t *testing.T) { sk := priv pk := &priv.PublicKey message := make([]byte, 32) - + // Measure memory allocations var m1, m2 runtime.MemStats runtime.ReadMemStats(&m1) - + // Perform multiple operations for i := 0; i < 100; i++ { sig, _ := opt.OptimizedSign(sk, message) opt.OptimizedVerify(pk, message, sig) } - + runtime.ReadMemStats(&m2) - + allocations := m2.Alloc - m1.Alloc t.Logf("Memory allocated: %d bytes", allocations) - + // Check that we're using the pool effectively if allocations > 10*1024*1024 { // 10MB threshold t.Logf("Warning: High memory usage detected") @@ -227,30 +227,30 @@ func TestMemoryUsage(t *testing.T) { // TestSIMDDetection tests SIMD detection and fallback func TestSIMDDetection(t *testing.T) { opt := NewOptimized(SLHDSA128f) - + t.Logf("Architecture: %s", runtime.GOARCH) t.Logf("SIMD Enabled: %v", opt.simdEnable) - + // Test that both paths work priv, _ := GenerateKey(rand.Reader, SLHDSA128f) sk := priv pk := &priv.PublicKey message := []byte("Test message") - + // Force SIMD path opt.simdEnable = true sig1, err := opt.OptimizedSign(sk, message) if err != nil { t.Fatalf("SIMD signing failed: %v", err) } - + // Force non-SIMD path opt.simdEnable = false sig2, err := opt.OptimizedSign(sk, message) if err != nil { t.Fatalf("Non-SIMD signing failed: %v", err) } - + // Both should verify if !opt.OptimizedVerify(pk, message, sig1) { t.Error("SIMD signature verification failed") @@ -270,7 +270,7 @@ func TestOptimizationMetrics(t *testing.T) { } InitPrecomputation() - + configs := []BenchmarkConfig{ {Mode: SLHDSA128f, MessageSize: 32, Iterations: 100, Parallel: true}, {Mode: SLHDSA128s, MessageSize: 32, Iterations: 100, Parallel: true}, @@ -279,18 +279,18 @@ func TestOptimizationMetrics(t *testing.T) { {Mode: SLHDSA256f, MessageSize: 32, Iterations: 25, Parallel: true}, {Mode: SLHDSA256s, MessageSize: 32, Iterations: 25, Parallel: true}, } - + t.Log("=== SLH-DSA Optimization Metrics ===") t.Log("Mode\t\tSign(ms)\tVerify(ms)\tSign Ops/s\tVerify Ops/s") t.Log("----\t\t--------\t----------\t----------\t------------") - + for _, config := range configs { opt := NewOptimized(config.Mode) result := opt.RunBenchmark(config) - + signMs := float64(result.SignTime) / 1e6 verifyMs := float64(result.VerifyTime) / 1e6 - + t.Logf("%v\t\t%.2f\t\t%.2f\t\t%.0f\t\t%.0f", config.Mode, signMs, @@ -304,22 +304,22 @@ func TestOptimizationMetrics(t *testing.T) { func ExampleOptimizedSLHDSA() { // Initialize precomputed tables for best performance InitPrecomputation() - + // Create optimized instance opt := NewOptimized(SLHDSA128f) - + // Generate keys priv, _ := GenerateKey(rand.Reader, SLHDSA128f) sk := priv pk := &priv.PublicKey - + // Sign message with optimizations message := []byte("Hello, Post-Quantum World!") signature, _ := opt.OptimizedSign(sk, message) - + // Verify with optimizations valid := opt.OptimizedVerify(pk, message, signature) - + fmt.Printf("Signature valid: %v\n", valid) fmt.Printf("Signature size: %d bytes\n", len(signature)) // Output: diff --git a/slhdsa/.old/slhdsa_comprehensive_test.go b/slhdsa/.old/slhdsa_comprehensive_test.go index 7aac970..25eba24 100644 --- a/slhdsa/.old/slhdsa_comprehensive_test.go +++ b/slhdsa/.old/slhdsa_comprehensive_test.go @@ -8,11 +8,11 @@ import ( func TestSLHDSAKeyGeneration(t *testing.T) { modes := []struct { - name string - mode Mode - pubSize int - privSize int - sigSize int + name string + mode Mode + pubSize int + privSize int + sigSize int }{ {"SLH-DSA-128s", SLHDSA128s, SLHDSA128sPublicKeySize, SLHDSA128sPrivateKeySize, SLHDSA128sSignatureSize}, {"SLH-DSA-128f", SLHDSA128f, SLHDSA128fPublicKeySize, SLHDSA128fPrivateKeySize, SLHDSA128fSignatureSize}, @@ -67,7 +67,7 @@ func TestSLHDSASignVerify(t *testing.T) { } message := []byte("Test message for SLH-DSA signature") - + // Sign message signature, err := privKey.Sign(rand.Reader, message, nil) if err != nil { @@ -142,7 +142,7 @@ func TestSLHDSADeterministicSignature(t *testing.T) { } message := []byte("Deterministic signature test") - + // Sign same message multiple times sig1, err := privKey.Sign(nil, message, nil) // nil rand for deterministic if err != nil { @@ -320,12 +320,12 @@ func TestSLHDSAConcurrency(t *testing.T) { } message := []byte("Concurrent test message") - + // Test concurrent signing t.Run("ConcurrentSign", func(t *testing.T) { const numGoroutines = 10 done := make(chan bool, numGoroutines) - + for i := 0; i < numGoroutines; i++ { go func(id int) { msg := append(message, byte(id)) @@ -340,7 +340,7 @@ func TestSLHDSAConcurrency(t *testing.T) { done <- true }(i) } - + for i := 0; i < numGoroutines; i++ { <-done } @@ -351,7 +351,7 @@ func TestSLHDSAConcurrency(t *testing.T) { signature, _ := privKey.Sign(rand.Reader, message, nil) const numGoroutines = 10 done := make(chan bool, numGoroutines) - + for i := 0; i < numGoroutines; i++ { go func(id int) { valid := privKey.PublicKey.Verify(message, signature, nil) @@ -361,7 +361,7 @@ func TestSLHDSAConcurrency(t *testing.T) { done <- true }(i) } - + for i := 0; i < numGoroutines; i++ { <-done } @@ -432,7 +432,7 @@ func BenchmarkSLHDSASign(b *testing.B) { for _, m := range modes { privKey, _ := GenerateKey(rand.Reader, m.mode) - + b.Run(m.name, func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { @@ -463,7 +463,7 @@ func BenchmarkSLHDSAVerify(b *testing.B) { for _, m := range modes { privKey, _ := GenerateKey(rand.Reader, m.mode) signature, _ := privKey.Sign(rand.Reader, message, nil) - + b.Run(m.name, func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { @@ -474,4 +474,4 @@ func BenchmarkSLHDSAVerify(b *testing.B) { } }) } -} \ No newline at end of file +} diff --git a/slhdsa/.old/slhdsa_optimized.go b/slhdsa/.old/slhdsa_optimized.go index 07b55eb..9ff8463 100644 --- a/slhdsa/.old/slhdsa_optimized.go +++ b/slhdsa/.old/slhdsa_optimized.go @@ -79,7 +79,7 @@ func NewMerkleTree(height int) *MerkleTree { for i := range nodes { nodes[i] = make([]byte, 32) } - + return &MerkleTree{ nodes: nodes, height: height, @@ -90,30 +90,30 @@ func NewMerkleTree(height int) *MerkleTree { func (mt *MerkleTree) ComputeRoot(leaves [][]byte) []byte { mt.mu.Lock() defer mt.mu.Unlock() - + // Copy leaves to bottom level leafStart := len(mt.nodes) - len(leaves) for i, leaf := range leaves { copy(mt.nodes[leafStart+i], leaf) } - + // Compute internal nodes h := sha256.New() for level := mt.height - 1; level >= 0; level-- { levelStart := (1 << level) - 1 levelSize := 1 << level - + for i := 0; i < levelSize; i++ { leftChild := mt.nodes[2*(levelStart+i)+1] rightChild := mt.nodes[2*(levelStart+i)+2] - + h.Reset() h.Write(leftChild) h.Write(rightChild) copy(mt.nodes[levelStart+i], h.Sum(nil)) } } - + return mt.nodes[0] } @@ -129,13 +129,13 @@ func NewParallelSLHDSA(mode Mode, numKeys, workers int) (*ParallelSLHDSA, error) if workers <= 0 { workers = 4 // Default worker count } - + keys := make([]*PrivateKey, numKeys) - + // Generate keys in parallel var wg sync.WaitGroup errors := make([]error, numKeys) - + for i := range keys { wg.Add(1) go func(idx int) { @@ -148,16 +148,16 @@ func NewParallelSLHDSA(mode Mode, numKeys, workers int) (*ParallelSLHDSA, error) keys[idx] = key }(i) } - + wg.Wait() - + // Check for errors for _, err := range errors { if err != nil { return nil, err } } - + return &ParallelSLHDSA{ keys: keys, workers: workers, @@ -169,20 +169,20 @@ func (p *ParallelSLHDSA) SignMessages(messages [][]byte) ([][]byte, error) { if len(messages) > len(p.keys) { return nil, errors.New("not enough keys for messages") } - + signatures := make([][]byte, len(messages)) - + // Create work channel work := make(chan int, len(messages)) for i := range messages { work <- i } close(work) - + // Start workers var wg sync.WaitGroup errors := make([]error, len(messages)) - + for w := 0; w < p.workers; w++ { wg.Add(1) go func() { @@ -197,25 +197,25 @@ func (p *ParallelSLHDSA) SignMessages(messages [][]byte) ([][]byte, error) { } }() } - + wg.Wait() - + // Check for errors for _, err := range errors { if err != nil { return nil, err } } - + return signatures, nil } // CachedSLHDSA caches intermediate computations type CachedSLHDSA struct { - privKey *PrivateKey - treeCache map[string]*MerkleTree - hashCache map[string][]byte - mu sync.RWMutex + privKey *PrivateKey + treeCache map[string]*MerkleTree + hashCache map[string][]byte + mu sync.RWMutex } // NewCachedSLHDSA creates a cached SLH-DSA instance @@ -234,7 +234,7 @@ func (c *CachedSLHDSA) SignWithCache(message []byte) ([]byte, error) { h.Write(message) msgHash := h.Sum(nil) cacheKey := string(msgHash[:16]) // Use first 16 bytes as key - + // Check cache c.mu.RLock() if sig, ok := c.hashCache[cacheKey]; ok { @@ -242,13 +242,13 @@ func (c *CachedSLHDSA) SignWithCache(message []byte) ([]byte, error) { return sig, nil } c.mu.RUnlock() - + // Sign and cache sig, err := c.privKey.Sign(rand.Reader, message, nil) if err != nil { return nil, err } - + c.mu.Lock() c.hashCache[cacheKey] = sig // Limit cache size @@ -262,6 +262,6 @@ func (c *CachedSLHDSA) SignWithCache(message []byte) ([]byte, error) { } } c.mu.Unlock() - + return sig, nil -} \ No newline at end of file +} diff --git a/unified/signer_simple.go b/unified/signer_simple.go index ac80bcb..44b8fbf 100644 --- a/unified/signer_simple.go +++ b/unified/signer_simple.go @@ -7,7 +7,7 @@ import ( "crypto" "crypto/rand" "fmt" - + "github.com/luxfi/crypto/bls" "github.com/luxfi/crypto/mldsa" ) @@ -25,18 +25,18 @@ func NewSimpleSigner() (*SimpleSigner, error) { if _, err := rand.Read(seed); err != nil { return nil, err } - + blsKey, err := bls.SecretKeyFromBytes(seed) if err != nil { return nil, err } - + // Generate ML-DSA key mldsaKey, err := mldsa.GenerateKey(rand.Reader, mldsa.MLDSA65) if err != nil { return nil, err } - + return &SimpleSigner{ blsKey: blsKey, mldsaKey: mldsaKey, @@ -79,19 +79,19 @@ func (s *SimpleSigner) SignHybrid(message []byte) ([]byte, error) { if err != nil { return nil, fmt.Errorf("BLS sign failed: %w", err) } - + mldsaSig, err := s.SignMLDSA(message) if err != nil { return nil, fmt.Errorf("ML-DSA sign failed: %w", err) } - + // Combine: [2-byte BLS len][BLS sig][ML-DSA sig] result := make([]byte, 2+len(blsSig)+len(mldsaSig)) result[0] = byte(len(blsSig) >> 8) result[1] = byte(len(blsSig)) copy(result[2:], blsSig) copy(result[2+len(blsSig):], mldsaSig) - + return result, nil } @@ -100,15 +100,15 @@ func (s *SimpleSigner) VerifyHybrid(message, signature []byte) bool { if len(signature) < 2 { return false } - + blsLen := int(signature[0])<<8 | int(signature[1]) if len(signature) < 2+blsLen { return false } - + blsSig := signature[2 : 2+blsLen] mldsaSig := signature[2+blsLen:] - + return s.VerifyBLS(message, blsSig) && s.VerifyMLDSA(message, mldsaSig) } @@ -121,4 +121,4 @@ func (s *SimpleSigner) GetBLSPublicKey() []byte { // GetMLDSAPublicKey returns the ML-DSA public key func (s *SimpleSigner) GetMLDSAPublicKey() []byte { return s.mldsaKey.PublicKey.Bytes() -} \ No newline at end of file +} diff --git a/unified/signer_simple_test.go b/unified/signer_simple_test.go index f3725d0..954f639 100644 --- a/unified/signer_simple_test.go +++ b/unified/signer_simple_test.go @@ -9,59 +9,59 @@ func TestSimpleSigner(t *testing.T) { if err != nil { t.Fatalf("Failed to create signer: %v", err) } - + message := []byte("Test message for unified signing") - + t.Run("BLS", func(t *testing.T) { sig, err := signer.SignBLS(message) if err != nil { t.Fatalf("BLS sign failed: %v", err) } - + if !signer.VerifyBLS(message, sig) { t.Fatalf("BLS verification failed") } - + if signer.VerifyBLS([]byte("wrong"), sig) { t.Fatalf("BLS should not verify wrong message") } - + t.Logf("BLS signature size: %d bytes", len(sig)) t.Logf("BLS public key size: %d bytes", len(signer.GetBLSPublicKey())) }) - + t.Run("ML-DSA", func(t *testing.T) { sig, err := signer.SignMLDSA(message) if err != nil { t.Fatalf("ML-DSA sign failed: %v", err) } - + if !signer.VerifyMLDSA(message, sig) { t.Fatalf("ML-DSA verification failed") } - + if signer.VerifyMLDSA([]byte("wrong"), sig) { t.Fatalf("ML-DSA should not verify wrong message") } - + t.Logf("ML-DSA signature size: %d bytes", len(sig)) t.Logf("ML-DSA public key size: %d bytes", len(signer.GetMLDSAPublicKey())) }) - + t.Run("Hybrid", func(t *testing.T) { sig, err := signer.SignHybrid(message) if err != nil { t.Fatalf("Hybrid sign failed: %v", err) } - + if !signer.VerifyHybrid(message, sig) { t.Fatalf("Hybrid verification failed") } - + if signer.VerifyHybrid([]byte("wrong"), sig) { t.Fatalf("Hybrid should not verify wrong message") } - + t.Logf("Hybrid signature size: %d bytes", len(sig)) }) } @@ -71,9 +71,9 @@ func BenchmarkSimpleSigner(b *testing.B) { if err != nil { b.Fatal(err) } - + message := []byte("Benchmark message for performance testing") - + b.Run("BLS_Sign", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { @@ -83,7 +83,7 @@ func BenchmarkSimpleSigner(b *testing.B) { } } }) - + blsSig, _ := signer.SignBLS(message) b.Run("BLS_Verify", func(b *testing.B) { b.ResetTimer() @@ -93,7 +93,7 @@ func BenchmarkSimpleSigner(b *testing.B) { } } }) - + b.Run("MLDSA_Sign", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { @@ -103,7 +103,7 @@ func BenchmarkSimpleSigner(b *testing.B) { } } }) - + mldsaSig, _ := signer.SignMLDSA(message) b.Run("MLDSA_Verify", func(b *testing.B) { b.ResetTimer() @@ -113,7 +113,7 @@ func BenchmarkSimpleSigner(b *testing.B) { } } }) - + b.Run("Hybrid_Sign", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { @@ -123,7 +123,7 @@ func BenchmarkSimpleSigner(b *testing.B) { } } }) - + hybridSig, _ := signer.SignHybrid(message) b.Run("Hybrid_Verify", func(b *testing.B) { b.ResetTimer() @@ -133,4 +133,4 @@ func BenchmarkSimpleSigner(b *testing.B) { } } }) -} \ No newline at end of file +} diff --git a/utils/bloom/bloom_interface.go b/utils/bloom/bloom_interface.go index 29f2e9d..d31a587 100644 --- a/utils/bloom/bloom_interface.go +++ b/utils/bloom/bloom_interface.go @@ -3,7 +3,6 @@ package bloom - // BloomFilter is the interface for bloom filter implementations that support // adding and checking raw byte slices type BloomFilter interface { diff --git a/utils/bloom/filter_common.go b/utils/bloom/filter_common.go index 9386b7c..f38cc52 100644 --- a/utils/bloom/filter_common.go +++ b/utils/bloom/filter_common.go @@ -69,4 +69,3 @@ func getIndex(entries []byte, hash, seed uint64) uint64 { } return index } - diff --git a/utils/bloom/optimal.go b/utils/bloom/optimal.go index 2326f63..400e4be 100644 --- a/utils/bloom/optimal.go +++ b/utils/bloom/optimal.go @@ -3,7 +3,6 @@ package bloom - import "math" const ln2Squared = math.Ln2 * math.Ln2 diff --git a/utils/constants/network_ids.go b/utils/constants/network_ids.go index cf45536..ac8ca36 100644 --- a/utils/constants/network_ids.go +++ b/utils/constants/network_ids.go @@ -21,10 +21,10 @@ const ( UnitTestID uint32 = 369 // Lux-specific network IDs - LuxMainnetID uint32 = 96369 // Lux mainnet - LuxTestnetID uint32 = 96370 // Lux testnet - QChainMainnetID uint32 = 96380 // Q-Chain mainnet - QChainTestnetID uint32 = 96381 // Q-Chain testnet + LuxMainnetID uint32 = 96369 // Lux mainnet + LuxTestnetID uint32 = 96370 // Lux testnet + QChainMainnetID uint32 = 96380 // Q-Chain mainnet + QChainTestnetID uint32 = 96381 // Q-Chain testnet LocalName = "local" MainnetName = "mainnet" @@ -42,7 +42,7 @@ const ( var ( PrimaryNetworkID = ids.Empty PlatformChainID = ids.Empty - + // Q-Chain specific IDs QChainID = ids.ID{'q', 'c', 'h', 'a', 'i', 'n'} diff --git a/utils/constants/vm_ids.go b/utils/constants/vm_ids.go index 6b04f20..445d750 100644 --- a/utils/constants/vm_ids.go +++ b/utils/constants/vm_ids.go @@ -6,19 +6,19 @@ package constants import "github.com/luxfi/ids" const ( - PlatformVMName = "platformvm" - XVMName = "xvm" - EVMName = "evm" - XSVMName = "xsvm" - QVMName = "qvm" + PlatformVMName = "platformvm" + XVMName = "xvm" + EVMName = "evm" + XSVMName = "xsvm" + QVMName = "qvm" ) var ( - PlatformVMID = ids.ID{'p', 'l', 'a', 't', 'f', 'o', 'r', 'm', 'v', 'm'} - XVMID = ids.ID{'a', 'v', 'm'} - EVMID = ids.ID{'e', 'v', 'm'} - XSVMID = ids.ID{'x', 's', 'v', 'm'} - QVMID = ids.ID{'q', 'v', 'm'} + PlatformVMID = ids.ID{'p', 'l', 'a', 't', 'f', 'o', 'r', 'm', 'v', 'm'} + XVMID = ids.ID{'a', 'v', 'm'} + EVMID = ids.ID{'e', 'v', 'm'} + XSVMID = ids.ID{'x', 's', 'v', 'm'} + QVMID = ids.ID{'q', 'v', 'm'} ) // VMName returns the name of the VM with the provided ID. If a human readable diff --git a/utils/dynamicip/updater.go b/utils/dynamicip/updater.go index 4ff34fb..2d9d4ed 100644 --- a/utils/dynamicip/updater.go +++ b/utils/dynamicip/updater.go @@ -8,9 +8,9 @@ import ( "net/netip" "time" + "github.com/luxfi/log" luxlog "github.com/luxfi/log" "github.com/luxfi/node/utils" - "github.com/luxfi/log" ) const ipResolutionTimeout = 10 * time.Second diff --git a/utils/ips/claimed_ip_port.go b/utils/ips/claimed_ip_port.go index cdbc7e2..5dc5221 100644 --- a/utils/ips/claimed_ip_port.go +++ b/utils/ips/claimed_ip_port.go @@ -50,7 +50,7 @@ func NewClaimedIPPort( Raw: cert.Raw, PublicKey: cert.PublicKey, } - + ip := &ClaimedIPPort{ Cert: cert, AddrPort: ipPort, diff --git a/utils/metric/averager.go b/utils/metric/averager.go index 759d192..9774f7c 100644 --- a/utils/metric/averager.go +++ b/utils/metric/averager.go @@ -34,11 +34,11 @@ func NewAveragerWithErrs(name, desc string, registry metric.Registry, errs *wrap a := averager{ count: metricsInstance.NewCounter( AppendNamespace(name, "count"), - "Total # of observations of " + desc, + "Total # of observations of "+desc, ), sum: metricsInstance.NewGauge( AppendNamespace(name, "sum"), - "Sum of " + desc, + "Sum of "+desc, ), } diff --git a/utils/resource/metrics.go b/utils/resource/metrics.go index ce6378a..53cea12 100644 --- a/utils/resource/metrics.go +++ b/utils/resource/metrics.go @@ -56,11 +56,11 @@ func newMetrics(registerer metric.Registerer) (*metricsImpl, error) { ), } err := errors.Join( - // registerer.Register(m.numCPUCycles), - // registerer.Register(m.numDiskReads), - // registerer.Register(m.numDiskReadBytes), - // registerer.Register(m.numDiskWrites), - // registerer.Register(m.numDiskWritesBytes), + // registerer.Register(m.numCPUCycles), + // registerer.Register(m.numDiskReads), + // registerer.Register(m.numDiskReadBytes), + // registerer.Register(m.numDiskWrites), + // registerer.Register(m.numDiskWritesBytes), ) return m, err } diff --git a/utils/rpc/json_test.go b/utils/rpc/json_test.go index 700e617..7c99682 100644 --- a/utils/rpc/json_test.go +++ b/utils/rpc/json_test.go @@ -11,9 +11,9 @@ import ( ) type mockReadCloser struct { - reader io.Reader - closed bool - readAll bool + reader io.Reader + closed bool + readAll bool } func (m *mockReadCloser) Read(p []byte) (n int, err error) { @@ -131,7 +131,7 @@ func TestCleanlyCloseBody_PartiallyReadBody(t *testing.T) { func BenchmarkCleanlyCloseBody_Small(b *testing.B) { data := []byte("small response body") - + b.ResetTimer() for i := 0; i < b.N; i++ { mock := &mockReadCloser{ @@ -144,7 +144,7 @@ func BenchmarkCleanlyCloseBody_Small(b *testing.B) { func BenchmarkCleanlyCloseBody_Large(b *testing.B) { // 1MB response data := bytes.Repeat([]byte("x"), 1024*1024) - + b.ResetTimer() for i := 0; i < b.N; i++ { mock := &mockReadCloser{ diff --git a/utils/tree/tree_test.go b/utils/tree/tree_test.go index ecff6f5..8b69005 100644 --- a/utils/tree/tree_test.go +++ b/utils/tree/tree_test.go @@ -9,8 +9,8 @@ import ( "github.com/stretchr/testify/require" - consensustest "github.com/luxfi/consensus/test/helpers" "github.com/luxfi/consensus/engine/chain/chaintest" + consensustest "github.com/luxfi/consensus/test/helpers" ) func TestAcceptSingleBlock(t *testing.T) { diff --git a/utils/ulimit/ulimit_darwin.go b/utils/ulimit/ulimit_darwin.go index 1d96f81..1decb3a 100644 --- a/utils/ulimit/ulimit_darwin.go +++ b/utils/ulimit/ulimit_darwin.go @@ -10,7 +10,6 @@ import ( "fmt" "syscall" - "github.com/luxfi/log" )