Skip to content

Commit

Permalink
Merge branch '1.10.19-zama' into louis/scalar_ops
Browse files Browse the repository at this point in the history
  • Loading branch information
tremblaythibaultl committed Jun 26, 2023
2 parents 1de28d6 + 88f7c50 commit 50f969b
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish_geth_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
uses: actions/checkout@v3
with:
repository: zama-ai/tfhe-rs
ref: 1d817c45d5234bcf33638406191b656998b30c2a
ref: 0.3.0-beta.0
path: tfhe-rs

- name: Checkout zbc-fhe-tool
Expand Down
29 changes: 25 additions & 4 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -1306,11 +1306,16 @@ func importCiphertext(accessibleState PrecompileAccessibleState, ct *tfheCiphert

// Used when we want to skip FHE computation, e.g. gas estimation.
func importRandomCiphertext(accessibleState PrecompileAccessibleState, t fheUintType) []byte {
nextCtHash := &accessibleState.Interpreter().evm.nextCiphertextHashOnGasEst
ctHashBytes := crypto.Keccak256(nextCtHash.Bytes())
handle := common.BytesToHash(ctHashBytes)
ct := new(tfheCiphertext)
ct.encrypt(*big.NewInt(0), t)
ct.fheUintType = t
ct.hash = &handle
importCiphertext(accessibleState, ct)
ctHash := ct.getHash()
return ctHash[:]
temp := nextCtHash.Clone()
nextCtHash.Add(temp, uint256.NewInt(1))
return ct.getHash().Bytes()
}

func get2VerifiedOperands(accessibleState PrecompileAccessibleState, input []byte) (lhs *verifiedCiphertext, rhs *verifiedCiphertext, err error) {
Expand Down Expand Up @@ -1482,6 +1487,11 @@ func (e *verifyCiphertext) Run(accessibleState PrecompileAccessibleState, caller
ctBytes := input[:len(input)-1]
ctType := fheUintType(input[len(input)-1])

// If we are doing gas estimation, skip execution and insert a random ciphertext as a result.
if !accessibleState.Interpreter().evm.Commit && !accessibleState.Interpreter().evm.EthCall {
return importRandomCiphertext(accessibleState, ctType), nil
}

ct := new(tfheCiphertext)
err := ct.deserializeCompact(ctBytes, ctType)
if err != nil {
Expand Down Expand Up @@ -2369,9 +2379,15 @@ func (e *cast) Run(accessibleState PrecompileAccessibleState, caller common.Addr

ct := getVerifiedCiphertext(accessibleState, common.BytesToHash(input[0:32]))
if ct == nil {
logger.Error("cast input not verified")
return nil, errors.New("unverified ciphertext handle")
}

castToType := fheUintType(input[32])
if !castToType.isValid() {
logger.Error("invalid type to cast to")
return nil, errors.New("invalid type provided")
}

res, err := ct.ciphertext.castTo(castToType)
if err != nil {
Expand Down Expand Up @@ -2417,7 +2433,12 @@ func (e *fhePubKey) Run(accessibleState PrecompileAccessibleState, caller common
accessibleState.Interpreter().evm.Logger.Error(msg, "existing", existing.Hex(), "pksHash", pksHash.Hex())
return nil, errors.New(msg)
}
return toEVMBytes(pksBytes), nil
// If we have a single byte with the value of 1, return as an EVM array. Otherwise, returh the raw bytes.
if len(input) == 1 && input[0] == 1 {
return toEVMBytes(pksBytes), nil
} else {
return pksBytes, nil
}
}

type trivialEncrypt struct{}
Expand Down
18 changes: 11 additions & 7 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,19 +159,23 @@ type EVM struct {

// The logger allows the EVM to report information during execution.
Logger Logger

// An integer used as a counter for unique ciphertext hashes during gas estimation.
nextCiphertextHashOnGasEst uint256.Int
}

// NewEVM returns a new EVM. The returned EVM is not thread safe and should
// only ever be used *once*.
func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM {
evm := &EVM{
Context: blockCtx,
TxContext: txCtx,
StateDB: statedb,
Config: config,
chainConfig: chainConfig,
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil),
Logger: &defaultLogger{},
Context: blockCtx,
TxContext: txCtx,
StateDB: statedb,
Config: config,
chainConfig: chainConfig,
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil),
Logger: &defaultLogger{},
nextCiphertextHashOnGasEst: *uint256.NewInt(0),
}
evm.interpreter = NewEVMInterpreter(evm, config)
return evm
Expand Down
7 changes: 6 additions & 1 deletion core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,10 @@ func verifyIfCiphertextHandle(val common.Hash, interpreter *EVMInterpreter, cont
ct, ok := interpreter.verifiedCiphertexts[val]
if ok {
// If already existing in memory, skip storage and import the same ciphertext at the current depth.
//
// Also works for gas estimation - we don't persist anything to protected storage during gas estimation.
// However, ciphertexts remain in memory for the duration of the call, allowing for this lookup to find it.
// Note that even if a ciphertext has an empty verification depth set, it still remains in memory.
importCiphertextToEVM(interpreter, ct.ciphertext)
return
}
Expand Down Expand Up @@ -721,7 +725,8 @@ func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
newValHash := common.BytesToHash(newValBytes)
oldValHash := interpreter.evm.StateDB.GetState(scope.Contract.Address(), common.Hash(loc.Bytes32()))
protectedStorage := crypto.CreateProtectedStorageContractAddress(scope.Contract.Address())
if newValHash != oldValHash {
// If the value is the same or if we are not going to commit, don't do anything to protected storage.
if newValHash != oldValHash && interpreter.evm.Commit {
// Since the old value is no longer stored in actual contract storage, run garbage collection on protected storage.
garbageCollectProtectedStorage(oldValHash, protectedStorage, interpreter)
// If a verified ciphertext, persist to protected storage.
Expand Down
12 changes: 7 additions & 5 deletions core/vm/tfhe.go
Original file line number Diff line number Diff line change
Expand Up @@ -1502,7 +1502,7 @@ const (
type tfheCiphertext struct {
ptr unsafe.Pointer
serialization []byte
hash []byte
hash *common.Hash
value *big.Int
fheUintType fheUintType
}
Expand Down Expand Up @@ -2354,13 +2354,15 @@ func (ct *tfheCiphertext) setPtr(ptr unsafe.Pointer) {
}

func (ct *tfheCiphertext) getHash() common.Hash {
if ct.hash != nil {
return *ct.hash
}
if !ct.initialized() {
panic("cannot get hash of non-initialized ciphertext")
}
if ct.hash == nil {
ct.hash = crypto.Keccak256(ct.serialize())
}
return common.BytesToHash(ct.hash)
hash := common.BytesToHash(crypto.Keccak256(ct.serialize()))
ct.hash = &hash
return *ct.hash
}

func (ct *tfheCiphertext) availableForOps() bool {
Expand Down
4 changes: 2 additions & 2 deletions install_thfe_rs_api.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/bin/bash

git clone https://github.com/zama-ai/tfhe-rs.git
git checkout 1d817c45d5234bcf33638406191b656998b30c2a
git checkout 0.3.0-beta.0
mkdir -p core/vm/lib
cd tfhe-rs
make build_c_api
make build_c_api_experimental_deterministic_fft
cp target/release/libtfhe.* ../core/vm/lib
cp target/release/tfhe.h ../core/vm

0 comments on commit 50f969b

Please sign in to comment.