-
Notifications
You must be signed in to change notification settings - Fork 2
chore: add re-encrypt #28
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -238,6 +238,12 @@ func newTestEVMEnvironment() *MockEVMEnvironment { | |
return &MockEVMEnvironment{fhevmData: &fhevmData, stateDb: state, commit: true, fhevmParams: DefaultFhevmParams()} | ||
} | ||
|
||
func newTestEVMEnvironmentWithEthCall() *MockEVMEnvironment { | ||
mockEVM := newTestEVMEnvironment() | ||
mockEVM.ethCall = true | ||
return mockEVM | ||
} | ||
|
||
Comment on lines
+241
to
+246
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure it's super worth it to create a separate function in a separate file just for one instance. I would rather add the line |
||
func TestProtectedStorageSstoreSload(t *testing.T) { | ||
environment := newTestEVMEnvironment() | ||
pc := uint64(0) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,6 +78,7 @@ type GasCosts struct { | |
TeeNeg map[tfhe.FheUintType]uint64 | ||
TeeBitwiseOp map[tfhe.FheUintType]uint64 | ||
TeeCast uint64 | ||
TeeReencrypt map[tfhe.FheUintType]uint64 | ||
} | ||
|
||
func DefaultGasCosts() GasCosts { | ||
|
@@ -308,6 +309,14 @@ func DefaultGasCosts() GasCosts { | |
tfhe.FheUint32: 150, | ||
tfhe.FheUint64: 189, | ||
}, | ||
// TODO: Costs will depend on the complexity of doing reencryption/decryption by the oracle. | ||
TeeReencrypt: map[tfhe.FheUintType]uint64{ | ||
tfhe.FheBool: 1000, | ||
tfhe.FheUint4: 1000, | ||
tfhe.FheUint8: 1000, | ||
tfhe.FheUint16: 1100, | ||
tfhe.FheUint32: 1200, | ||
Comment on lines
+313
to
+318
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These values are much larger than the ones for other TEE operations. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically copy & pasted code from tfhe reencrypt. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @amaury1093 Do you have any chance to look into this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. Maybe we can do 100, so 10x cheaper than FHE. In the same order of magniture as a mul |
||
}, | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -88,3 +88,49 @@ func teeDecryptRun(environment EVMEnvironment, caller common.Address, addr commo | |
copy(ret[32-len(plaintext):], plaintext) | ||
return ret, nil | ||
} | ||
|
||
func teeReencryptRun(environment EVMEnvironment, caller common.Address, addr common.Address, input []byte, readOnly bool, runSpan trace.Span) ([]byte, error) { | ||
input = input[:minInt(64, len(input))] | ||
logger := environment.GetLogger() | ||
if !environment.IsEthCall() { | ||
msg := "reencrypt only supported on EthCall" | ||
logger.Error(msg) | ||
return nil, errors.New(msg) | ||
} | ||
if len(input) != 64 { | ||
msg := "reencrypt input len must be 64 bytes" | ||
logger.Error(msg, "input", hex.EncodeToString(input), "len", len(input)) | ||
return nil, errors.New(msg) | ||
} | ||
ct := getVerifiedCiphertext(environment, common.BytesToHash(input[0:32])) | ||
if ct != nil { | ||
otelDescribeOperandsFheTypes(runSpan, ct.fheUintType()) | ||
|
||
plainText, err := tee.Decrypt(ct.ciphertext) | ||
if err != nil { | ||
logger.Error("reencrypt decryption failed", "err", err) | ||
return nil, err | ||
} | ||
decryptedValue := new(big.Int).SetBytes(plainText.Value) | ||
|
||
pubKey := input[32:64] | ||
reencryptedValue, err := encryptToUserKey(decryptedValue, pubKey) | ||
if err != nil { | ||
logger.Error("reencrypt failed to encrypt to user key", "err", err) | ||
return nil, err | ||
} | ||
|
||
// TODO: decide if `res.Signature` should be verified here | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this comment about? |
||
|
||
logger.Info("reencrypt success", "input", hex.EncodeToString(input), "callerAddr", caller, "reencryptedValue", reencryptedValue, "len", len(reencryptedValue)) | ||
reencryptedValue = toEVMBytes(reencryptedValue) | ||
// pad according to abi specification, first add offset to the dynamic bytes argument | ||
outputBytes := make([]byte, 32, len(reencryptedValue)+32) | ||
outputBytes[31] = 0x20 | ||
outputBytes = append(outputBytes, reencryptedValue...) | ||
return padArrayTo32Multiple(outputBytes), nil | ||
} | ||
msg := "reencrypt unverified ciphertext handle" | ||
logger.Error(msg, "input", hex.EncodeToString(input)) | ||
return nil, errors.New(msg) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,3 +46,36 @@ func TestTeeDecryptRun(t *testing.T) { | |
} | ||
}) | ||
} | ||
|
||
func TestTeeReEncryptRun(t *testing.T) { | ||
signature := "teeReencrypt(uint256,uint256)" | ||
rapid.Check(t, func(t *rapid.T) { | ||
testcases := []struct { | ||
typ tfhe.FheUintType | ||
expected uint64 | ||
}{ | ||
{tfhe.FheUint4, uint64(rapid.Uint8().Draw(t, "expected"))}, | ||
{tfhe.FheUint8, uint64(rapid.Uint8().Draw(t, "expected"))}, | ||
{tfhe.FheUint16, uint64(rapid.Uint16().Draw(t, "expected"))}, | ||
{tfhe.FheUint32, uint64(rapid.Uint32().Draw(t, "expected"))}, | ||
{tfhe.FheUint64, uint64(rapid.Uint64().Draw(t, "expected"))}, | ||
} | ||
for _, tc := range testcases { | ||
depth := 1 | ||
environment := newTestEVMEnvironmentWithEthCall() | ||
environment.depth = depth | ||
addr := common.Address{} | ||
readOnly := false | ||
ct, err := importTeePlaintextToEVM(environment, depth, tc.expected, tc.typ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test doesn't use any pubkey. What is it testing exactly here? |
||
if err != nil { | ||
t.Fatalf(err.Error()) | ||
} | ||
|
||
input := toLibPrecompileInput(signature, false, ct.GetHash()) | ||
_, err = FheLibRun(environment, addr, addr, input, readOnly) | ||
if err != nil { | ||
t.Fatalf("Reencrypt error: %s", err.Error()) | ||
} | ||
} | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import ( | |
"encoding/binary" | ||
"encoding/json" | ||
"fmt" | ||
"math/big" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
|
@@ -118,3 +119,17 @@ func Decrypt(ct *tfhe.TfheCiphertext) (TeePlaintext, error) { | |
|
||
return plaintext, nil | ||
} | ||
|
||
func DecryptToBigInt(ct *tfhe.TfheCiphertext) (*big.Int, error) { | ||
decryptedValue, err := Decrypt(ct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
plaintext := decryptedValue.Value | ||
// Always return a 32-byte big-endian integer. | ||
ret := make([]byte, 32) | ||
copy(ret[32-len(plaintext):], plaintext) | ||
|
||
return new(big.Int).SetBytes(ret), nil | ||
} | ||
Comment on lines
+130
to
+135
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can just use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In #31, there has been a refactor to move tee operations into teelib.go. Your new function should go there.