From 25d89b5c1a763fc027eb1a3a1e704855a22d850b Mon Sep 17 00:00:00 2001 From: Levent Demir Date: Thu, 22 Dec 2022 17:43:27 +0100 Subject: [PATCH 1/3] feature: add lte works only when keys have the same msg bit and carry bits, e.g. msg2_carry2 --- core/vm/contracts.go | 82 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 413f7b150a9c..e75642d00e21 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -78,6 +78,36 @@ void sub_encrypted_integers(BufferView sks_view, BufferView ct1_view, BufferView destroy_shortint_ciphertext(result_ct); } +void less_or_equal(BufferView sks_view, BufferView ct1_view, BufferView ct2_view, Buffer* result) +{ + ShortintServerKey *sks = NULL; + ShortintCiphertext *ct1 = NULL; + ShortintCiphertext *ct2 = NULL; + ShortintCiphertext *result_ct = NULL; + + int deser_sks_ok = shortint_deserialize_server_key(sks_view, &sks); + assert(deser_sks_ok == 0); + + int deser_ct1_ok = shortint_deserialize_ciphertext(ct1_view, &ct1); + assert(deser_ct1_ok == 0); + + int deser_ct2_ok = shortint_deserialize_ciphertext(ct2_view, &ct2); + assert(deser_ct2_ok == 0); + + // int comp_ok = shortint_server_key_smart_less_or_equal(sks, ct1, ct2, &result_ct); + int comp_ok = shortint_server_key_unchecked_less_or_equal(sks, ct1, ct2, &result_ct); + assert(comp_ok == 0); + + int ser_ok = shortint_serialize_ciphertext(result_ct, result); + assert(ser_ok == 0); + + destroy_shortint_server_key(sks); + destroy_shortint_ciphertext(ct1); + destroy_shortint_ciphertext(ct2); + destroy_shortint_ciphertext(result_ct); +} + + void encrypt_integer(BufferView cks_buff_view, uint64_t val, Buffer* ct_buf) { ShortintCiphertext *ct = NULL; @@ -1722,36 +1752,50 @@ func (e *fheLte) Run(accessibleState PrecompileAccessibleState, caller common.Ad return nil, errors.New("unverified ciphertext handle") } - // If we are not committing state, skip execution and insert a random ciphertext as a result. - if !accessibleState.Interpreter().evm.Commit { - return importRandomCiphertext(accessibleState, len(lhsCt)), nil - } - - // TODO: decrypt inputs till we support the FHE LTE operator - lhs, err := fheDecrypt(lhsCt) + sks, err := os.ReadFile(networkKeysDir + "sks") if err != nil { return nil, err } - rhs, err := fheDecrypt(rhsCt) - if err != nil { - return nil, err + + cCiphertext1 := C.CBytes(lhsCt) + viewCiphertext1 := C.BufferView{ + pointer: (*C.uchar)(cCiphertext1), + length: (C.ulong)(len(lhsCt)), } - var result uint64 - if lhs <= rhs { - result = 1 - } else { - result = 0 + + cCiphertext2 := C.CBytes(rhsCt) + viewCiphertext2 := C.BufferView{ + pointer: (*C.uchar)(cCiphertext2), + length: (C.ulong)(len(rhsCt)), } - ct, err := fheEncryptToNetworkKey(result) - if err != nil { - return nil, err + + cServerKey := C.CBytes(sks) + viewServerKey := C.BufferView{ + pointer: (*C.uchar)(cServerKey), + length: (C.ulong)(len(sks)), } + + result := &C.Buffer{} + C.less_or_equal(viewServerKey, viewCiphertext1, viewCiphertext2, result) + + ctBytes := C.GoBytes(unsafe.Pointer(result.pointer), C.int(result.length)) verifiedCiphertext := &verifiedCiphertext{ depth: accessibleState.Interpreter().evm.depth, - ciphertext: ct, + ciphertext: ctBytes, } + + err = os.WriteFile("/tmp/lte_result", ctBytes, 0644) + if err != nil { + return nil, err + } + ctHash := crypto.Keccak256Hash(verifiedCiphertext.ciphertext) accessibleState.Interpreter().verifiedCiphertexts[ctHash] = verifiedCiphertext + + C.free(cServerKey) + C.free(cCiphertext1) + C.free(cCiphertext2) + return ctHash[:], nil } From 06c599b7c98f6c0c80c814ca9b2d44eb9750b07b Mon Sep 17 00:00:00 2001 From: Levent Demir Date: Thu, 22 Dec 2022 17:49:12 +0100 Subject: [PATCH 2/3] fixture: reintegrate if not committing code (rebase erases it) --- core/vm/contracts.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index e75642d00e21..94139ccaca7f 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -1752,6 +1752,11 @@ func (e *fheLte) Run(accessibleState PrecompileAccessibleState, caller common.Ad return nil, errors.New("unverified ciphertext handle") } + // If we are not committing state, skip execution and insert a random ciphertext as a result. + if !accessibleState.Interpreter().evm.Commit { + return importRandomCiphertext(accessibleState, len(lhsCt)), nil + } + sks, err := os.ReadFile(networkKeysDir + "sks") if err != nil { return nil, err From 785bc6e9f06543a608e575771fb48dccb90aaa29 Mon Sep 17 00:00:00 2001 From: Levent Demir Date: Fri, 23 Dec 2022 12:21:11 +0100 Subject: [PATCH 3/3] fixture: replace unchecked lte with smart one --- core/vm/contracts.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 94139ccaca7f..e785dc606a10 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -94,8 +94,7 @@ void less_or_equal(BufferView sks_view, BufferView ct1_view, BufferView ct2_view int deser_ct2_ok = shortint_deserialize_ciphertext(ct2_view, &ct2); assert(deser_ct2_ok == 0); - // int comp_ok = shortint_server_key_smart_less_or_equal(sks, ct1, ct2, &result_ct); - int comp_ok = shortint_server_key_unchecked_less_or_equal(sks, ct1, ct2, &result_ct); + int comp_ok = shortint_server_key_smart_less_or_equal(sks, ct1, ct2, &result_ct); assert(comp_ok == 0); int ser_ok = shortint_serialize_ciphertext(result_ct, result);