mirror of
https://github.com/luxfi/chains.git
synced 2026-09-24 00:26:00 +00:00
VMs now live in ONE place: chains/<name>/ owns the full implementation. Previously split across node/vms/<name>/ (impl) + chains/<name>/main.go (plugin wrapper). Now consolidated. New layout: chains/<name>vm/*.go — package <name>vm (VM code) chains/<name>vm/cmd/plugin/main.go — package main (plugin binary) chains/<name>vm/go.mod — module github.com/luxfi/chains/<name>vm Moved 11 VMs: aivm, bridgevm, dexvm, graphvm, identityvm, keyvm, oraclevm, quantumvm, relayvm, thresholdvm, zkvm. External callers now import github.com/luxfi/chains/<name> directly.
199 lines
4.8 KiB
Go
199 lines
4.8 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package zkvm
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"sync"
|
|
|
|
"github.com/luxfi/log"
|
|
)
|
|
|
|
// FHEProcessor handles fully homomorphic encryption operations
|
|
type FHEProcessor struct {
|
|
config ZConfig
|
|
log log.Logger
|
|
|
|
// FHE parameters
|
|
publicKey []byte
|
|
evalKey []byte
|
|
|
|
// Processing statistics
|
|
processCount uint64
|
|
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
// NewFHEProcessor creates a new FHE processor
|
|
func NewFHEProcessor(config ZConfig, log log.Logger) (*FHEProcessor, error) {
|
|
if !config.EnableFHE {
|
|
return nil, errors.New("FHE not enabled in config")
|
|
}
|
|
|
|
fp := &FHEProcessor{
|
|
config: config,
|
|
log: log,
|
|
}
|
|
|
|
// Initialize FHE parameters
|
|
if err := fp.initializeFHEParams(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return fp, nil
|
|
}
|
|
|
|
// VerifyFHEOperations verifies FHE operations in a transaction
|
|
func (fp *FHEProcessor) VerifyFHEOperations(tx *Transaction) error {
|
|
if tx.FHEData == nil {
|
|
return errors.New("no FHE data in transaction")
|
|
}
|
|
|
|
fp.mu.Lock()
|
|
fp.processCount++
|
|
fp.mu.Unlock()
|
|
|
|
// Verify circuit ID is supported
|
|
if !fp.isCircuitSupported(tx.FHEData.CircuitID) {
|
|
return errors.New("unsupported FHE circuit")
|
|
}
|
|
|
|
// Verify encrypted inputs
|
|
if len(tx.FHEData.EncryptedInputs) == 0 {
|
|
return errors.New("no encrypted inputs provided")
|
|
}
|
|
|
|
// Verify computation proof
|
|
if len(tx.FHEData.ComputationProof) < 128 {
|
|
return errors.New("invalid computation proof")
|
|
}
|
|
|
|
fp.log.Debug("FHE operations verified",
|
|
log.String("txID", tx.ID.String()),
|
|
log.String("circuitID", tx.FHEData.CircuitID),
|
|
log.Int("inputCount", len(tx.FHEData.EncryptedInputs)),
|
|
)
|
|
|
|
return nil
|
|
}
|
|
|
|
// ProcessFHEComputation performs an FHE computation
|
|
func (fp *FHEProcessor) ProcessFHEComputation(
|
|
circuitID string,
|
|
encryptedInputs [][]byte,
|
|
) ([]byte, []byte, error) {
|
|
// Stub: returns zero-filled result and proof
|
|
encryptedResult := make([]byte, 256)
|
|
computationProof := make([]byte, 256)
|
|
|
|
fp.log.Debug("FHE computation processed",
|
|
log.String("circuitID", circuitID),
|
|
log.Int("inputCount", len(encryptedInputs)),
|
|
)
|
|
|
|
return encryptedResult, computationProof, nil
|
|
}
|
|
|
|
// EncryptValue encrypts a value using FHE
|
|
func (fp *FHEProcessor) EncryptValue(value uint64) ([]byte, error) {
|
|
// Stub: encodes value in first 8 bytes (not encrypted)
|
|
ciphertext := make([]byte, 256)
|
|
// Encode value in first 8 bytes (insecure, just for testing)
|
|
binary.BigEndian.PutUint64(ciphertext[:8], value)
|
|
|
|
return ciphertext, nil
|
|
}
|
|
|
|
// DecryptValue decrypts an FHE ciphertext
|
|
func (fp *FHEProcessor) DecryptValue(ciphertext []byte, privateKey []byte) (uint64, error) {
|
|
if len(ciphertext) < 256 {
|
|
return 0, errors.New("invalid ciphertext length")
|
|
}
|
|
|
|
// Stub: reads value from first 8 bytes (not decrypting)
|
|
value := binary.BigEndian.Uint64(ciphertext[:8])
|
|
|
|
return value, nil
|
|
}
|
|
|
|
// AddCiphertexts performs homomorphic addition
|
|
func (fp *FHEProcessor) AddCiphertexts(ct1, ct2 []byte) ([]byte, error) {
|
|
if len(ct1) != 256 || len(ct2) != 256 {
|
|
return nil, errors.New("invalid ciphertext length")
|
|
}
|
|
|
|
// Stub: adds raw encoded values (not homomorphic)
|
|
val1 := binary.BigEndian.Uint64(ct1[:8])
|
|
val2 := binary.BigEndian.Uint64(ct2[:8])
|
|
|
|
result := make([]byte, 256)
|
|
binary.BigEndian.PutUint64(result[:8], val1+val2)
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// MultiplyCiphertext performs homomorphic multiplication by a plaintext
|
|
func (fp *FHEProcessor) MultiplyCiphertext(ct []byte, scalar uint64) ([]byte, error) {
|
|
if len(ct) != 256 {
|
|
return nil, errors.New("invalid ciphertext length")
|
|
}
|
|
|
|
// Stub: multiplies raw encoded value (not homomorphic)
|
|
val := binary.BigEndian.Uint64(ct[:8])
|
|
|
|
result := make([]byte, 256)
|
|
binary.BigEndian.PutUint64(result[:8], val*scalar)
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// initializeFHEParams initializes FHE parameters
|
|
func (fp *FHEProcessor) initializeFHEParams() error {
|
|
// Stub: generates zero-filled keys matching expected sizes
|
|
switch fp.config.FHEScheme {
|
|
case "BFV":
|
|
fp.publicKey = make([]byte, 2048)
|
|
fp.evalKey = make([]byte, 4096)
|
|
case "CKKS":
|
|
fp.publicKey = make([]byte, 2048)
|
|
fp.evalKey = make([]byte, 4096)
|
|
default:
|
|
return errors.New("unsupported FHE scheme")
|
|
}
|
|
|
|
fp.log.Info("FHE parameters initialized",
|
|
log.String("scheme", fp.config.FHEScheme),
|
|
log.Int("securityLevel", int(fp.config.SecurityLevel)),
|
|
)
|
|
|
|
return nil
|
|
}
|
|
|
|
// isCircuitSupported checks if a circuit ID is supported
|
|
func (fp *FHEProcessor) isCircuitSupported(circuitID string) bool {
|
|
supportedCircuits := []string{
|
|
"add",
|
|
"multiply",
|
|
"compare",
|
|
"range_proof",
|
|
"balance_check",
|
|
}
|
|
|
|
for _, supported := range supportedCircuits {
|
|
if circuitID == supported {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// GetStats returns FHE processing statistics
|
|
func (fp *FHEProcessor) GetStats() uint64 {
|
|
fp.mu.RLock()
|
|
defer fp.mu.RUnlock()
|
|
return fp.processCount
|
|
}
|