From d0947c98034a2d000dbf9b01d262a5ba6b010dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20=27birdy=27=20Danjou?= Date: Mon, 5 Feb 2024 17:23:57 +0100 Subject: [PATCH] feat: add 64bits support --- Makefile | 4 - fhevm/contracts_test.go | 352 +++++++++++++- fhevm/instructions_test.go | 2 +- fhevm/params.go | 109 +++-- fhevm/precompiles.go | 21 +- fhevm/tfhe.go | 911 ++++++++++++++++++++++++++++++++++++- fhevm/tfhe_test.go | 319 ++++++++++++- 7 files changed, 1644 insertions(+), 74 deletions(-) diff --git a/Makefile b/Makefile index d26b514..d83dff6 100644 --- a/Makefile +++ b/Makefile @@ -6,10 +6,6 @@ build: build-tfhe-rs-capi test: build-tfhe-rs-capi cd fhevm && go test -v . -.PHONY: gasEstimation -gasEstimation: build-tfhe-rs-capi - cd fhevm && go test -count=1 -v . -run GasEstimation - .PHONY: build-tfhe-rs-capi build-tfhe-rs-capi: cd tfhe-rs && RUSTFLAGS="" make build_c_api_experimental_deterministic_fft \ diff --git a/fhevm/contracts_test.go b/fhevm/contracts_test.go index 3f46850..fa0e20f 100644 --- a/fhevm/contracts_test.go +++ b/fhevm/contracts_test.go @@ -176,7 +176,7 @@ func toLibPrecompileInputNoScalar(method string, hashes ...common.Hash) []byte { } func VerifyCiphertext(t *testing.T, fheUintType FheUintType) { - var value uint32 + var value uint64 switch fheUintType { case FheUint8: value = 2 @@ -184,6 +184,8 @@ func VerifyCiphertext(t *testing.T, fheUintType FheUintType) { value = 4283 case FheUint32: value = 1333337 + case FheUint64: + value = 13333377777777777 } depth := 1 environment := newTestEVMEnvironment() @@ -210,7 +212,7 @@ func VerifyCiphertext(t *testing.T, fheUintType FheUintType) { } func VerifyCiphertextBadType(t *testing.T, actualType FheUintType, metadataType FheUintType) { - var value uint32 + var value uint64 switch actualType { case FheUint8: value = 2 @@ -218,6 +220,8 @@ func VerifyCiphertextBadType(t *testing.T, actualType FheUintType, metadataType value = 4283 case FheUint32: value = 1333337 + case FheUint64: + value = 13333377777777777 } depth := 1 environment := newTestEVMEnvironment() @@ -244,6 +248,8 @@ func TrivialEncrypt(t *testing.T, fheUintType FheUintType) { value = *big.NewInt(4283) case FheUint32: value = *big.NewInt(1333337) + case FheUint64: + value = *big.NewInt(13333377777777777) } depth := 1 environment := newTestEVMEnvironment() @@ -278,6 +284,10 @@ func FheLibAdd(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 133377777777 + } expected := lhs + rhs signature := "fheAdd(uint256,uint256,bytes1)" @@ -320,6 +330,9 @@ func FheLibSub(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 133377777777 } expected := lhs - rhs signature := "fheSub(uint256,uint256,bytes1)" @@ -362,6 +375,9 @@ func FheLibMul(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777 + lhs = 1337 } expected := lhs * rhs signature := "fheMul(uint256,uint256,bytes1)" @@ -404,6 +420,9 @@ func FheLibLe(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 1333777777777 + lhs = 133377777777 } signature := "fheLe(uint256,uint256,bytes1)" depth := 1 @@ -466,6 +485,9 @@ func FheLibLt(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 133377777777 } signature := "fheLt(uint256,uint256,bytes1)" @@ -529,6 +551,9 @@ func FheLibEq(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 133377777777 } signature := "fheLt(uint256,uint256,bytes1)" depth := 1 @@ -571,6 +596,9 @@ func FheLibGe(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 133377777777 } signature := "fheGe(uint256,uint256,bytes1)" depth := 1 @@ -631,6 +659,9 @@ func FheLibGt(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 133377777777 } signature := "fheGt(uint256,uint256,bytes1)" @@ -693,6 +724,9 @@ func FheLibShl(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 3 + case FheUint64: + lhs = 13333377777777777 + lhs = 34 } expected := lhs << rhs signature := "fheShl(uint256,uint256,bytes1)" @@ -735,6 +769,9 @@ func FheLibShr(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 3 + case FheUint64: + lhs = 13333377777777777 + lhs = 34 } expected := lhs >> rhs signature := "fheShr(uint256,uint256,bytes1)" @@ -777,6 +814,9 @@ func FheLibNe(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 133377777777 } signature := "fheNe(uint256,uint256,bytes1)" depth := 1 @@ -819,6 +859,9 @@ func FheLibMin(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 133377777777 } signature := "fheMin(uint256,uint256,bytes1)" @@ -880,6 +923,9 @@ func FheLibMax(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 133377777777 } signature := "fheMax(uint256,uint256,bytes1)" @@ -941,6 +987,9 @@ func FheLibNeg(t *testing.T, fheUintType FheUintType) { case FheUint32: pt = 1333337 expected = uint64(-uint32(pt)) + case FheUint64: + pt = 13333377777777777 + expected = uint64(-uint64(pt)) } signature := "fheNeg(uint256)" @@ -978,6 +1027,9 @@ func FheLibNot(t *testing.T, fheUintType FheUintType) { case FheUint32: pt = 1333337 expected = uint64(^uint32(pt)) + case FheUint64: + pt = 13333377777777777 + expected = uint64(^uint64(pt)) } signature := "fheNot(uint256)" @@ -1015,6 +1067,9 @@ func FheLibDiv(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 137 rhs = 17 + case FheUint64: + lhs = 13333377777777777 + lhs = 1337 } expected := lhs / rhs @@ -1064,6 +1119,9 @@ func FheLibRem(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1337 rhs = 73 + case FheUint64: + lhs = 13333377777777777 + lhs = 1337 } expected := lhs % rhs signature := "fheRem(uint256,uint256,bytes1)" @@ -1112,6 +1170,9 @@ func FheLibBitAnd(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 1337 } expected := lhs & rhs signature := "fheBitAnd(uint256,uint256,bytes1)" @@ -1160,6 +1221,9 @@ func FheLibBitOr(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 1337 } expected := lhs | rhs signature := "fheBitOr(uint256,uint256,bytes1)" @@ -1208,6 +1272,9 @@ func FheLibBitXor(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777777777 + lhs = 1337 } expected := lhs ^ rhs signature := "fheBitXor(uint256,uint256,bytes1)" @@ -1287,6 +1354,10 @@ func FheLibRand(t *testing.T, fheUintType FheUintType) { if decrypted.Uint64() > 0xFFFFFFFF { t.Fatalf("random value is bigger than 0xFFFFFFFF (32 bits)") } + case FheUint64: + if decrypted.Uint64() > 0xFFFFFFFFFFFFFFFF { + t.Fatalf("random value is bigger than 0xFFFFFFFFFFFFFFFF (64 bits)") + } } } @@ -1339,6 +1410,9 @@ func FheLibIfThenElse(t *testing.T, fheUintType FheUintType, condition uint64) { case FheUint32: second = 1333337 third = 133337 + case FheUint64: + second = 1333337777777 + third = 133337 } signature := "fheIfThenElse(uint256,uint256,uint256)" depth := 1 @@ -1374,6 +1448,8 @@ func LibTrivialEncrypt(t *testing.T, fheUintType FheUintType) { value = *big.NewInt(4283) case FheUint32: value = *big.NewInt(1333337) + case FheUint64: + value = *big.NewInt(133333777777) } signature := "trivialEncrypt(uint256,bytes1)" hashRes := crypto.Keccak256([]byte(signature)) @@ -1411,6 +1487,8 @@ func LibDecrypt(t *testing.T, fheUintType FheUintType) { value = 4283 case FheUint32: value = 1333337 + case FheUint64: + value = 133333777777 } signature := "decrypt(uint256)" hashRes := crypto.Keccak256([]byte(signature)) @@ -1522,6 +1600,9 @@ func FheAdd(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 133333777777 + rhs = 133337 } expected := lhs + rhs depth := 1 @@ -1563,6 +1644,9 @@ func FheSub(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 133333777777 + rhs = 133337 } expected := lhs - rhs depth := 1 @@ -1604,6 +1688,9 @@ func FheMul(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 137 rhs = 17 + case FheUint64: + lhs = 137777 + rhs = 17 } expected := lhs * rhs depth := 1 @@ -1645,6 +1732,9 @@ func FheDiv(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 137 rhs = 65521 + case FheUint64: + lhs = 137777777 + rhs = 65521 } expected := lhs / rhs depth := 1 @@ -1692,6 +1782,9 @@ func FheRem(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 123765 rhs = 2179 + case FheUint64: + lhs = 1237651337 + rhs = 2179 } expected := lhs % rhs depth := 1 @@ -1739,6 +1832,9 @@ func FheBitAnd(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777 + rhs = 133337 } expected := lhs & rhs depth := 1 @@ -1786,6 +1882,9 @@ func FheBitOr(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777 + rhs = 133337 } expected := lhs | rhs depth := 1 @@ -1833,6 +1932,9 @@ func FheBitXor(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777 + rhs = 133337 } expected := lhs ^ rhs depth := 1 @@ -1880,6 +1982,9 @@ func FheShl(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 3 + case FheUint64: + lhs = 1333337777 + rhs = 10 } expected := lhs << rhs depth := 1 @@ -1921,6 +2026,9 @@ func FheShr(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 3 + case FheUint64: + lhs = 133333777777 + rhs = 10 } expected := lhs >> rhs depth := 1 @@ -1962,6 +2070,9 @@ func FheEq(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777 + rhs = 133337 } depth := 1 environment := newTestEVMEnvironment() @@ -2003,6 +2114,9 @@ func FheNe(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777 + rhs = 133337 } depth := 1 environment := newTestEVMEnvironment() @@ -2044,6 +2158,9 @@ func FheGe(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777 + rhs = 133337 } depth := 1 environment := newTestEVMEnvironment() @@ -2103,6 +2220,9 @@ func FheGt(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777 + rhs = 133337 } depth := 1 @@ -2164,6 +2284,9 @@ func FheLe(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 1333337777 + rhs = 133337 } depth := 1 environment := newTestEVMEnvironment() @@ -2225,6 +2348,9 @@ func FheLt(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777 + rhs = 133337 } depth := 1 @@ -2287,6 +2413,9 @@ func FheMin(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 133333777777 + rhs = 133337 } depth := 1 @@ -2347,6 +2476,9 @@ func FheMax(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777 + rhs = 133337 } depth := 1 @@ -2407,6 +2539,9 @@ func FheNeg(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: pt = 1333337 expected = uint64(-uint32(pt)) + case FheUint64: + pt = 133333777777 + expected = uint64(-uint64(pt)) } depth := 1 @@ -2444,6 +2579,9 @@ func FheNot(t *testing.T, fheUintType FheUintType, scalar bool) { case FheUint32: pt = 1333337 expected = uint64(^uint32(pt)) + case FheUint64: + pt = 1333337777777 + expected = uint64(^uint64(pt)) } depth := 1 @@ -2481,6 +2619,9 @@ func FheIfThenElse(t *testing.T, fheUintType FheUintType, condition uint64) { case FheUint32: lhs = 1333337 rhs = 133337 + case FheUint64: + lhs = 13333377777 + rhs = 133337 } depth := 1 environment := newTestEVMEnvironment() @@ -2515,6 +2656,8 @@ func Decrypt(t *testing.T, fheUintType FheUintType) { value = 4283 case FheUint32: value = 1333337 + case FheUint64: + value = 133333777777777 } depth := 1 environment := newTestEVMEnvironment() @@ -2565,7 +2708,7 @@ func TestVerifyCiphertextInvalidType(t *testing.T) { addr := common.Address{} readOnly := false invalidType := FheUintType(255) - compact := encryptAndSerializeCompact(0, FheUint32) + compact := encryptAndSerializeCompact(0, FheUint64) input := append(compact, byte(invalidType)) _, err := verifyCiphertextRun(environment, addr, addr, input, readOnly) if err == nil { @@ -2635,6 +2778,10 @@ func TestVerifyCiphertext32(t *testing.T) { VerifyCiphertext(t, FheUint32) } +func TestVerifyCiphertext64(t *testing.T) { + VerifyCiphertext(t, FheUint64) +} + func TestTrivialEncrypt8(t *testing.T) { TrivialEncrypt(t, FheUint8) } @@ -2647,6 +2794,10 @@ func TestTrivialEncrypt32(t *testing.T) { TrivialEncrypt(t, FheUint32) } +func TestTrivialEncrypt64(t *testing.T) { + TrivialEncrypt(t, FheUint64) +} + func TestVerifyCiphertext8BadType(t *testing.T) { VerifyCiphertextBadType(t, FheUint8, FheUint16) VerifyCiphertextBadType(t, FheUint8, FheUint32) @@ -2662,6 +2813,11 @@ func TestVerifyCiphertext32BadType(t *testing.T) { VerifyCiphertextBadType(t, FheUint32, FheUint16) } +func TestVerifyCiphertext64BadType(t *testing.T) { + VerifyCiphertextBadType(t, FheUint64, FheUint8) + VerifyCiphertextBadType(t, FheUint64, FheUint16) +} + func TestVerifyCiphertextBadCiphertext(t *testing.T) { depth := 1 environment := newTestEVMEnvironment() @@ -2769,6 +2925,10 @@ func TestFheLibRand32(t *testing.T) { FheLibRand(t, FheUint32) } +func TestFheLibRand64(t *testing.T) { + FheLibRand(t, FheUint64) +} + func TestFheLibRandBounded8(t *testing.T) { FheLibRandBounded(t, FheUint8, 8) } @@ -2781,6 +2941,10 @@ func TestFheLibRandBounded32(t *testing.T) { FheLibRandBounded(t, FheUint32, 32) } +func TestFheLibRandBounded64(t *testing.T) { + FheLibRandBounded(t, FheUint64, 64) +} + func TestFheLibIfThenElse8(t *testing.T) { FheLibIfThenElse(t, FheUint8, 1) FheLibIfThenElse(t, FheUint8, 0) @@ -2796,6 +2960,11 @@ func TestFheLibIfThenElse32(t *testing.T) { FheLibIfThenElse(t, FheUint32, 0) } +func TestFheLibIfThenElse64(t *testing.T) { + FheLibIfThenElse(t, FheUint64, 1) + FheLibIfThenElse(t, FheUint64, 0) +} + func TestFheLibTrivialEncrypt8(t *testing.T) { LibTrivialEncrypt(t, FheUint8) } @@ -2817,6 +2986,10 @@ func TestFheAdd32(t *testing.T) { FheAdd(t, FheUint32, false) } +func TestFheAdd64(t *testing.T) { + FheAdd(t, FheUint64, false) +} + func TestFheScalarAdd8(t *testing.T) { FheAdd(t, FheUint8, true) } @@ -2829,6 +3002,10 @@ func TestFheScalarAdd32(t *testing.T) { FheAdd(t, FheUint32, true) } +func TestFheScalarAdd64(t *testing.T) { + FheAdd(t, FheUint64, true) +} + func TestFheSub8(t *testing.T) { FheSub(t, FheUint8, false) } @@ -2841,6 +3018,10 @@ func TestFheSub32(t *testing.T) { FheSub(t, FheUint32, false) } +func TestFheSub64(t *testing.T) { + FheSub(t, FheUint64, false) +} + func TestFheScalarSub8(t *testing.T) { FheSub(t, FheUint8, true) } @@ -2853,6 +3034,10 @@ func TestFheScalarSub32(t *testing.T) { FheSub(t, FheUint32, true) } +func TestFheScalarSub64(t *testing.T) { + FheSub(t, FheUint64, true) +} + func TestFheMul8(t *testing.T) { FheMul(t, FheUint8, false) } @@ -2865,6 +3050,10 @@ func TestFheMul32(t *testing.T) { FheMul(t, FheUint32, false) } +func TestFheMul64(t *testing.T) { + FheMul(t, FheUint64, false) +} + func TestFheScalarMul8(t *testing.T) { FheMul(t, FheUint8, true) } @@ -2877,6 +3066,10 @@ func TestFheScalarMul32(t *testing.T) { FheMul(t, FheUint32, true) } +func TestFheScalarMul64(t *testing.T) { + FheMul(t, FheUint64, true) +} + func TestFheDiv8(t *testing.T) { FheDiv(t, FheUint8, false) } @@ -2889,6 +3082,10 @@ func TestFheDiv32(t *testing.T) { FheDiv(t, FheUint32, false) } +func TestFheDiv64(t *testing.T) { + FheDiv(t, FheUint64, false) +} + func TestFheScalarDiv8(t *testing.T) { FheDiv(t, FheUint8, true) } @@ -2901,6 +3098,10 @@ func TestFheScalarDiv32(t *testing.T) { FheDiv(t, FheUint32, true) } +func TestFheScalarDiv64(t *testing.T) { + FheDiv(t, FheUint64, true) +} + func TestFheRem8(t *testing.T) { FheRem(t, FheUint8, false) } @@ -2913,6 +3114,10 @@ func TestFheRem32(t *testing.T) { FheRem(t, FheUint32, false) } +func TestFheRem64(t *testing.T) { + FheRem(t, FheUint64, false) +} + func TestFheScalarRem8(t *testing.T) { FheRem(t, FheUint8, true) } @@ -2925,6 +3130,10 @@ func TestFheScalarRem32(t *testing.T) { FheRem(t, FheUint32, true) } +func TestFheScalarRem64(t *testing.T) { + FheRem(t, FheUint64, true) +} + func TestFheBitAnd8(t *testing.T) { FheBitAnd(t, FheUint8, false) } @@ -2937,6 +3146,10 @@ func TestFheBitAnd32(t *testing.T) { FheBitAnd(t, FheUint32, false) } +func TestFheBitAnd64(t *testing.T) { + FheBitAnd(t, FheUint64, false) +} + func TestFheScalarBitAnd8(t *testing.T) { FheBitAnd(t, FheUint8, true) } @@ -2949,6 +3162,10 @@ func TestFheScalarBitAnd32(t *testing.T) { FheBitAnd(t, FheUint32, true) } +func TestFheScalarBitAnd64(t *testing.T) { + FheBitAnd(t, FheUint64, true) +} + func TestFheBitOr8(t *testing.T) { FheBitOr(t, FheUint8, false) } @@ -2961,6 +3178,10 @@ func TestFheBitOr32(t *testing.T) { FheBitOr(t, FheUint32, false) } +func TestFheBitOr64(t *testing.T) { + FheBitOr(t, FheUint64, false) +} + func TestFheScalarBitOr8(t *testing.T) { FheBitOr(t, FheUint8, true) } @@ -2973,6 +3194,10 @@ func TestFheScalarBitOr32(t *testing.T) { FheBitOr(t, FheUint32, true) } +func TestFheScalarBitOr64(t *testing.T) { + FheBitOr(t, FheUint64, true) +} + func TestFheBitXor8(t *testing.T) { FheBitXor(t, FheUint8, false) } @@ -2985,6 +3210,10 @@ func TestFheBitXor32(t *testing.T) { FheBitXor(t, FheUint32, false) } +func TestFheBitXor64(t *testing.T) { + FheBitXor(t, FheUint64, false) +} + func TestFheScalarBitXor8(t *testing.T) { FheBitXor(t, FheUint8, true) } @@ -2997,6 +3226,10 @@ func TestFheScalarBitXor32(t *testing.T) { FheBitXor(t, FheUint32, true) } +func TestFheScalarBitXor64(t *testing.T) { + FheBitXor(t, FheUint64, true) +} + func TestFheShl8(t *testing.T) { FheShl(t, FheUint8, false) } @@ -3009,6 +3242,10 @@ func TestFheShl32(t *testing.T) { FheShl(t, FheUint32, false) } +func TestFheShl64(t *testing.T) { + FheShl(t, FheUint64, false) +} + func TestFheScalarShl8(t *testing.T) { FheShl(t, FheUint8, true) } @@ -3021,6 +3258,10 @@ func TestFheScalarShl32(t *testing.T) { FheShl(t, FheUint32, true) } +func TestFheScalarShl64(t *testing.T) { + FheShl(t, FheUint64, true) +} + func TestFheShr8(t *testing.T) { FheShr(t, FheUint8, false) } @@ -3033,6 +3274,10 @@ func TestFheShr32(t *testing.T) { FheShr(t, FheUint32, false) } +func TestFheShr64(t *testing.T) { + FheShr(t, FheUint64, false) +} + func TestFheScalarShr8(t *testing.T) { FheShr(t, FheUint8, true) } @@ -3045,6 +3290,10 @@ func TestFheScalarShr32(t *testing.T) { FheShr(t, FheUint32, true) } +func TestFheScalarShr64(t *testing.T) { + FheShr(t, FheUint64, true) +} + func TestFheEq8(t *testing.T) { FheEq(t, FheUint8, false) } @@ -3057,6 +3306,10 @@ func TestFheEq32(t *testing.T) { FheEq(t, FheUint32, false) } +func TestFheEq64(t *testing.T) { + FheEq(t, FheUint64, false) +} + func TestFheScalarEq8(t *testing.T) { FheEq(t, FheUint8, true) } @@ -3069,6 +3322,10 @@ func TestFheScalarEq32(t *testing.T) { FheEq(t, FheUint32, true) } +func TestFheScalarEq64(t *testing.T) { + FheEq(t, FheUint64, true) +} + func TestFheNe8(t *testing.T) { FheNe(t, FheUint8, false) } @@ -3081,6 +3338,10 @@ func TestFheNe32(t *testing.T) { FheNe(t, FheUint32, false) } +func TestFheNe64(t *testing.T) { + FheNe(t, FheUint64, false) +} + func TestFheScalarNe8(t *testing.T) { FheNe(t, FheUint8, true) } @@ -3093,6 +3354,10 @@ func TestFheScalarNe32(t *testing.T) { FheNe(t, FheUint32, true) } +func TestFheScalarNe64(t *testing.T) { + FheNe(t, FheUint64, true) +} + func TestFheGe8(t *testing.T) { FheGe(t, FheUint8, false) } @@ -3105,6 +3370,10 @@ func TestFheGe32(t *testing.T) { FheGe(t, FheUint32, false) } +func TestFheGe64(t *testing.T) { + FheGe(t, FheUint64, false) +} + func TestFheScalarGe8(t *testing.T) { FheGe(t, FheUint8, true) } @@ -3117,6 +3386,10 @@ func TestFheScalarGe32(t *testing.T) { FheGe(t, FheUint32, true) } +func TestFheScalarGe64(t *testing.T) { + FheGe(t, FheUint64, true) +} + func TestFheGt8(t *testing.T) { FheGt(t, FheUint8, false) } @@ -3129,6 +3402,10 @@ func TestFheGt32(t *testing.T) { FheGt(t, FheUint32, false) } +func TestFheGt64(t *testing.T) { + FheGt(t, FheUint64, false) +} + func TestFheScalarGt8(t *testing.T) { FheGt(t, FheUint8, true) } @@ -3141,6 +3418,10 @@ func TestFheScalarGt32(t *testing.T) { FheGt(t, FheUint32, true) } +func TestFheScalarGt64(t *testing.T) { + FheGt(t, FheUint64, true) +} + func TestFheLe8(t *testing.T) { FheLe(t, FheUint8, false) } @@ -3153,6 +3434,10 @@ func TestFheLe32(t *testing.T) { FheLe(t, FheUint32, false) } +func TestFheLe64(t *testing.T) { + FheLe(t, FheUint64, false) +} + func TestFheScalarLe8(t *testing.T) { FheLe(t, FheUint8, true) } @@ -3165,6 +3450,10 @@ func TestFheScalarLe32(t *testing.T) { FheLe(t, FheUint32, true) } +func TestFheScalarLe64(t *testing.T) { + FheLe(t, FheUint64, true) +} + func TestFheLt8(t *testing.T) { FheLt(t, FheUint8, false) } @@ -3177,6 +3466,10 @@ func TestFheLt32(t *testing.T) { FheLt(t, FheUint32, false) } +func TestFheLt64(t *testing.T) { + FheLt(t, FheUint64, false) +} + func TestFheScalarLt8(t *testing.T) { FheLt(t, FheUint8, true) } @@ -3189,6 +3482,10 @@ func TestFheScalarLt32(t *testing.T) { FheLt(t, FheUint32, true) } +func TestFheScalarLt64(t *testing.T) { + FheLt(t, FheUint64, true) +} + func TestFheMin8(t *testing.T) { FheMin(t, FheUint8, false) } @@ -3201,6 +3498,10 @@ func TestFheMin32(t *testing.T) { FheMin(t, FheUint32, false) } +func TestFheMin64(t *testing.T) { + FheMin(t, FheUint64, false) +} + func TestFheScalarMin8(t *testing.T) { FheMin(t, FheUint8, true) } @@ -3213,6 +3514,10 @@ func TestFheScalarMin32(t *testing.T) { FheMin(t, FheUint32, true) } +func TestFheScalarMin64(t *testing.T) { + FheMin(t, FheUint64, true) +} + func TestFheMax8(t *testing.T) { FheMax(t, FheUint8, false) } @@ -3225,6 +3530,10 @@ func TestFheMax32(t *testing.T) { FheMax(t, FheUint32, false) } +func TestFheMax64(t *testing.T) { + FheMax(t, FheUint64, false) +} + func TestFheNeg8(t *testing.T) { FheNeg(t, FheUint8, false) } @@ -3237,6 +3546,10 @@ func TestFheNeg32(t *testing.T) { FheNeg(t, FheUint32, false) } +func TestFheNeg64(t *testing.T) { + FheNeg(t, FheUint64, false) +} + func TestFheNot8(t *testing.T) { FheNot(t, FheUint8, false) } @@ -3249,6 +3562,10 @@ func TestFheNot32(t *testing.T) { FheNot(t, FheUint32, false) } +func TestFheNot64(t *testing.T) { + FheNot(t, FheUint64, false) +} + func TestFheIfThenElse8(t *testing.T) { FheIfThenElse(t, FheUint8, 1) FheIfThenElse(t, FheUint8, 0) @@ -3264,6 +3581,11 @@ func TestFheIfThenElse32(t *testing.T) { FheIfThenElse(t, FheUint32, 0) } +func TestFheIfThenElse64(t *testing.T) { + FheIfThenElse(t, FheUint64, 1) + FheIfThenElse(t, FheUint64, 0) +} + func TestFheScalarMax8(t *testing.T) { FheMax(t, FheUint8, true) } @@ -3276,6 +3598,10 @@ func TestFheScalarMax32(t *testing.T) { FheMax(t, FheUint32, true) } +func TestFheScalarMax64(t *testing.T) { + FheMax(t, FheUint64, true) +} + func TestDecrypt8(t *testing.T) { Decrypt(t, FheUint8) } @@ -3288,6 +3614,10 @@ func TestDecrypt32(t *testing.T) { Decrypt(t, FheUint32) } +func TestDecrypt64(t *testing.T) { + Decrypt(t, FheUint64) +} + func TestFheRand8(t *testing.T) { FheRand(t, FheUint8) } @@ -3300,6 +3630,10 @@ func TestFheRand32(t *testing.T) { FheRand(t, FheUint32) } +func TestFheRand64(t *testing.T) { + FheRand(t, FheUint64) +} + func TestUnknownCiphertextHandle(t *testing.T) { depth := 1 environment := newTestEVMEnvironment() @@ -3404,7 +3738,7 @@ func TestFheRandBoundedInvalidType(t *testing.T) { addr := common.Address{} readOnly := false input := make([]byte, 0) - upperBound := uint256.NewInt(4).Bytes32() + upperBound := uint256.NewInt(8).Bytes32() input = append(input, upperBound[:]...) input = append(input, byte(254)) _, err := fheRandBoundedRun(environment, addr, addr, input, readOnly) @@ -3465,6 +3799,16 @@ func TestFheRandBoundedInvalidBound32(t *testing.T) { FheRandBoundedInvalidBound(t, FheUint32, moreThan64Bits) } +func TestFheRandBoundedInvalidBound64(t *testing.T) { + FheRandBoundedInvalidBound(t, FheUint64, uint256.NewInt(0)) + FheRandBoundedInvalidBound(t, FheUint64, uint256.NewInt(111999)) + FheRandBoundedInvalidBound(t, FheUint64, uint256.NewInt(448884)) + FheRandBoundedInvalidBound(t, FheUint64, uint256.NewInt(0xFFFFFFFFFFFFFFFF)) + moreThan64Bits := uint256.NewInt(0xFFFFFFFFFFFFFFFF) + moreThan64Bits.Add(moreThan64Bits, uint256.NewInt(1)) + FheRandBoundedInvalidBound(t, FheUint32, moreThan64Bits) +} + func TestFheRandEthCall(t *testing.T) { depth := 1 environment := newTestEVMEnvironment() diff --git a/fhevm/instructions_test.go b/fhevm/instructions_test.go index ba39bcd..8f8ad7c 100644 --- a/fhevm/instructions_test.go +++ b/fhevm/instructions_test.go @@ -56,7 +56,7 @@ func init() { func verifyCiphertextInTestMemory(environment EVMEnvironment, value uint64, depth int, t FheUintType) *tfheCiphertext { // Simulate as if the ciphertext is compact and comes externally. - ser := encryptAndSerializeCompact(uint32(value), t) + ser := encryptAndSerializeCompact(uint64(value), t) ct := new(tfheCiphertext) err := ct.deserializeCompact(ser, t) if err != nil { diff --git a/fhevm/params.go b/fhevm/params.go index 172f756..af9bdc5 100644 --- a/fhevm/params.go +++ b/fhevm/params.go @@ -26,6 +26,7 @@ package fhevm // Base gas costs of existing EVM operations. Used for setting gas costs relative to them. // These constants are used just for readability. const EvmNetSstoreInitGas uint64 = 20000 +const AdjustFHEGas uint64 = 10000 const ColdSloadCostEIP2929 uint64 = 2100 var ( @@ -69,7 +70,8 @@ type GasCosts struct { FheLe map[FheUintType]uint64 FheMinMax map[FheUintType]uint64 FheScalarMinMax map[FheUintType]uint64 - FheNegNot map[FheUintType]uint64 + FheNot map[FheUintType]uint64 + FheNeg map[FheUintType]uint64 FheReencrypt map[FheUintType]uint64 FheTrivialEncrypt map[FheUintType]uint64 FheRand map[FheUintType]uint64 @@ -82,69 +84,88 @@ type GasCosts struct { func DefaultGasCosts() GasCosts { return GasCosts{ FheAddSub: map[FheUintType]uint64{ - FheUint8: 120000, - FheUint16: 150000, - FheUint32: 180000, + FheUint8: 84000 + AdjustFHEGas, + FheUint16: 123000 + AdjustFHEGas, + FheUint32: 152000 + AdjustFHEGas, + FheUint64: 178000 + AdjustFHEGas, }, FheDecrypt: map[FheUintType]uint64{ FheUint8: 500000, FheUint16: 500000, FheUint32: 500000, + FheUint64: 500000, }, FheBitwiseOp: map[FheUintType]uint64{ - FheUint8: 30000, - FheUint16: 33000, - FheUint32: 36000, + FheUint8: 24000 + AdjustFHEGas, + FheUint16: 24000 + AdjustFHEGas, + FheUint32: 25000 + AdjustFHEGas, + FheUint64: 28000 + AdjustFHEGas, }, FheMul: map[FheUintType]uint64{ - FheUint8: 200000, - FheUint16: 260000, - FheUint32: 380000, + FheUint8: 187000 + AdjustFHEGas, + FheUint16: 252000 + AdjustFHEGas, + FheUint32: 349000 + AdjustFHEGas, + FheUint64: 631000 + AdjustFHEGas, }, FheScalarMul: map[FheUintType]uint64{ - FheUint8: 135000, - FheUint16: 140000, - FheUint32: 170000, + FheUint8: 149000 + AdjustFHEGas, + FheUint16: 198000 + AdjustFHEGas, + FheUint32: 254000 + AdjustFHEGas, + FheUint64: 346000 + AdjustFHEGas, }, FheScalarDiv: map[FheUintType]uint64{ - FheUint8: 450000, - FheUint16: 500000, - FheUint32: 550000, + FheUint8: 228000 + AdjustFHEGas, + FheUint16: 304000 + AdjustFHEGas, + FheUint32: 388000 + AdjustFHEGas, + FheUint64: 574000 + AdjustFHEGas, }, FheScalarRem: map[FheUintType]uint64{ - FheUint8: 450000, - FheUint16: 500000, - FheUint32: 550000, + FheUint8: 450000 + AdjustFHEGas, + FheUint16: 612000 + AdjustFHEGas, + FheUint32: 795000 + AdjustFHEGas, + FheUint64: 1095000 + AdjustFHEGas, }, FheShift: map[FheUintType]uint64{ - FheUint8: 150000, - FheUint16: 180000, - FheUint32: 210000, + FheUint8: 123000 + AdjustFHEGas, + FheUint16: 143000 + AdjustFHEGas, + FheUint32: 173000 + AdjustFHEGas, + FheUint64: 217000 + AdjustFHEGas, }, FheScalarShift: map[FheUintType]uint64{ - FheUint8: 32000, - FheUint16: 32000, - FheUint32: 32000, + FheUint8: 25000 + AdjustFHEGas, + FheUint16: 25000 + AdjustFHEGas, + FheUint32: 25000 + AdjustFHEGas, + FheUint64: 28000 + AdjustFHEGas, }, FheLe: map[FheUintType]uint64{ - FheUint8: 56000, - FheUint16: 67000, - FheUint32: 89000, + FheUint8: 46000 + AdjustFHEGas, + FheUint16: 46000 + AdjustFHEGas, + FheUint32: 72000 + AdjustFHEGas, + FheUint64: 76000 + AdjustFHEGas, }, FheMinMax: map[FheUintType]uint64{ - FheUint8: 220000, - FheUint16: 280000, - FheUint32: 340000, + FheUint8: 94000 + AdjustFHEGas, + FheUint16: 120000 + AdjustFHEGas, + FheUint32: 148000 + AdjustFHEGas, + FheUint64: 189000 + AdjustFHEGas, }, FheScalarMinMax: map[FheUintType]uint64{ - FheUint8: 140000, - FheUint16: 165000, - FheUint32: 190000, - }, - FheNegNot: map[FheUintType]uint64{ - FheUint8: 29000, - FheUint16: 31000, - FheUint32: 33000, + FheUint8: 114000 + AdjustFHEGas, + FheUint16: 140000 + AdjustFHEGas, + FheUint32: 154000 + AdjustFHEGas, + FheUint64: 182000 + AdjustFHEGas, + }, + FheNot: map[FheUintType]uint64{ + FheUint8: 25000 + AdjustFHEGas, + FheUint16: 25000 + AdjustFHEGas, + FheUint32: 26000 + AdjustFHEGas, + FheUint64: 27000 + AdjustFHEGas, + }, + FheNeg: map[FheUintType]uint64{ + FheUint8: 79000 + AdjustFHEGas, + FheUint16: 114000 + AdjustFHEGas, + FheUint32: 150000 + AdjustFHEGas, + FheUint64: 189000 + AdjustFHEGas, }, // TODO: Costs will depend on the complexity of doing reencryption/decryption by the oracle. FheReencrypt: map[FheUintType]uint64{ @@ -157,22 +178,26 @@ func DefaultGasCosts() GasCosts { FheUint8: 200, FheUint16: 300, FheUint32: 400, + FheUint64: 800, }, FheTrivialEncrypt: map[FheUintType]uint64{ FheUint8: 100, FheUint16: 200, FheUint32: 300, + FheUint64: 600, }, // TODO: These will change once we have an FHE-based random generaration. FheRand: map[FheUintType]uint64{ FheUint8: EvmNetSstoreInitGas + 100000, FheUint16: EvmNetSstoreInitGas + 100000, FheUint32: EvmNetSstoreInitGas + 100000, + FheUint64: EvmNetSstoreInitGas + 100000, }, FheIfThenElse: map[FheUintType]uint64{ - FheUint8: 60000, - FheUint16: 65000, - FheUint32: 70000, + FheUint8: 37000 + AdjustFHEGas, + FheUint16: 37000 + AdjustFHEGas, + FheUint32: 40000 + AdjustFHEGas, + FheUint64: 43000 + AdjustFHEGas, }, // TODO: As of now, only support FheUint8. All optimistic require predicates are // downcast to FheUint8 at the solidity level. Eventually move to ebool. diff --git a/fhevm/precompiles.go b/fhevm/precompiles.go index 3e77a4c..4012881 100644 --- a/fhevm/precompiles.go +++ b/fhevm/precompiles.go @@ -263,7 +263,7 @@ func FheLibRun(environment EVMEnvironment, caller common.Address, addr common.Ad bwCompatBytes := input[4:minInt(5, len(input))] return fheRandRun(environment, caller, addr, bwCompatBytes, readOnly) case signatureFheRandBounded: - bwCompatBytes := input[4:minInt(37, len(input))] + bwCompatBytes := input[4:minInt(69, len(input))] return fheRandBoundedRun(environment, caller, addr, bwCompatBytes, readOnly) case signatureFheIfThenElse: bwCompatBytes := input[4:minInt(100, len(input))] @@ -497,12 +497,22 @@ func fheNegRequiredGas(environment EVMEnvironment, input []byte) uint64 { logger.Error("fheNeg input not verified", "input", hex.EncodeToString(input)) return 0 } - return environment.FhevmParams().GasCosts.FheNegNot[ct.ciphertext.fheUintType] + return environment.FhevmParams().GasCosts.FheNeg[ct.ciphertext.fheUintType] } func fheNotRequiredGas(environment EVMEnvironment, input []byte) uint64 { // Implement in terms of neg, because costs are currently the same. - return fheNegRequiredGas(environment, input) + logger := environment.GetLogger() + if len(input) != 32 { + logger.Error("fheNot input needs to contain one 256-bit sized value", "input", hex.EncodeToString(input)) + return 0 + } + ct := getVerifiedCiphertext(environment, common.BytesToHash(input[0:32])) + if ct == nil { + logger.Error("fheNot input not verified", "input", hex.EncodeToString(input)) + return 0 + } + return environment.FhevmParams().GasCosts.FheNot[ct.ciphertext.fheUintType] } func fheDivRequiredGas(environment EVMEnvironment, input []byte) uint64 { @@ -1906,6 +1916,11 @@ func generateRandom(environment EVMEnvironment, caller common.Address, resultTyp cipher.XORKeyStream(randBytes, randBytes) randUint = uint64(binary.BigEndian.Uint32(randBytes)) randUint = uint64(applyUpperBound(randUint, 32, upperBound)) + case FheUint64: + randBytes := make([]byte, 8) + cipher.XORKeyStream(randBytes, randBytes) + randUint = uint64(binary.BigEndian.Uint64(randBytes)) + randUint = uint64(applyUpperBound(randUint, 64, upperBound)) default: return nil, fmt.Errorf("generateRandom() invalid type requested: %d", resultType) } diff --git a/fhevm/tfhe.go b/fhevm/tfhe.go index 4a3d631..f737a1c 100644 --- a/fhevm/tfhe.go +++ b/fhevm/tfhe.go @@ -124,6 +124,16 @@ void* cast_bool_32(void* ct, void* sks) { return result; } +void* cast_bool_64(void* ct, void* sks) { + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_bool_cast_into_fhe_uint64(ct, &result); + if(r != 0) return NULL; + return result; +} + int serialize_fhe_uint8(void *ct, DynamicBuffer* out) { return fhe_uint8_serialize(ct, out); } @@ -238,6 +248,44 @@ void* deserialize_compact_fhe_uint32(DynamicBufferView in) { return ct; } +int serialize_fhe_uint64(void *ct, DynamicBuffer* out) { + return fhe_uint64_serialize(ct, out); +} + +void* deserialize_fhe_uint64(DynamicBufferView in) { + FheUint64* ct = NULL; + const int r = fhe_uint64_deserialize(in, &ct); + if(r != 0) { + return NULL; + } + return ct; +} + +void* deserialize_compact_fhe_uint64(DynamicBufferView in) { + CompactFheUint64List* list = NULL; + FheUint64* ct = NULL; + + int r = compact_fhe_uint64_list_deserialize(in, &list); + if(r != 0) { + return NULL; + } + size_t len = 0; + r = compact_fhe_uint64_list_len(list, &len); + // Expect only 1 ciphertext in the list. + if(r != 0 || len != 1) { + r = compact_fhe_uint64_list_destroy(list); + assert(r == 0); + return NULL; + } + r = compact_fhe_uint64_list_expand(list, &ct, 1); + if(r != 0) { + ct = NULL; + } + r = compact_fhe_uint64_list_destroy(list); + assert(r == 0); + return ct; +} + void destroy_fhe_uint8(void* ct) { const int r = fhe_uint8_destroy(ct); assert(r == 0); @@ -253,6 +301,11 @@ void destroy_fhe_uint32(void* ct) { assert(r == 0); } +void destroy_fhe_uint64(void* ct) { + const int r = fhe_uint64_destroy(ct); + assert(r == 0); +} + void* add_fhe_uint8(void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -286,6 +339,17 @@ void* add_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* add_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_add(ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + void* scalar_add_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheUint8* result = NULL; @@ -319,6 +383,17 @@ void* scalar_add_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_add_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_add(ct, pt, &result); + if(r != 0) return NULL; + return result; +} + void* sub_fhe_uint8(void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -352,6 +427,17 @@ void* sub_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* sub_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_sub(ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + void* scalar_sub_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheUint8* result = NULL; @@ -385,6 +471,17 @@ void* scalar_sub_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_sub_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_sub(ct, pt, &result); + if(r != 0) return NULL; + return result; +} + void* mul_fhe_uint8(void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -418,6 +515,17 @@ void* mul_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* mul_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_mul(ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + void* scalar_mul_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheUint8* result = NULL; @@ -451,6 +559,17 @@ void* scalar_mul_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_mul_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_mul(ct, pt, &result); + if(r != 0) return NULL; + return result; +} + void* scalar_div_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheUint8* result = NULL; @@ -484,6 +603,17 @@ void* scalar_div_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_div_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_div(ct, pt, &result); + if(r != 0) return NULL; + return result; +} + void* scalar_rem_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheUint8* result = NULL; @@ -517,6 +647,17 @@ void* scalar_rem_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_rem_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_rem(ct, pt, &result); + if(r != 0) return NULL; + return result; +} + void* bitand_fhe_uint8(void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -550,6 +691,17 @@ void* bitand_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* bitand_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_bitand(ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + void* bitor_fhe_uint8(void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -583,6 +735,17 @@ void* bitor_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* bitor_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_bitor(ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + void* bitxor_fhe_uint8(void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -616,6 +779,17 @@ void* bitxor_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* bitxor_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_bitxor(ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + void* shl_fhe_uint8(void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -649,6 +823,17 @@ void* shl_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* shl_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_shl(ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + void* scalar_shl_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheUint8* result = NULL; @@ -682,6 +867,17 @@ void* scalar_shl_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_shl_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_shl(ct, pt, &result); + if(r != 0) return NULL; + return result; +} + void* shr_fhe_uint8(void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -715,6 +911,17 @@ void* shr_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* shr_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_shr(ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + void* scalar_shr_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheUint8* result = NULL; @@ -748,6 +955,17 @@ void* scalar_shr_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_shr_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_shr(ct, pt, &result); + if(r != 0) return NULL; + return result; +} + void* eq_fhe_uint8(void* ct1, void* ct2, void* sks) { FheBool* bool_result = NULL; @@ -784,6 +1002,18 @@ void* eq_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* eq_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_eq(ct1, ct2, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* scalar_eq_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheBool* bool_result = NULL; @@ -820,6 +1050,18 @@ void* scalar_eq_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_eq_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_eq(ct, pt, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* ne_fhe_uint8(void* ct1, void* ct2, void* sks) { FheBool* bool_result = NULL; @@ -856,6 +1098,18 @@ void* ne_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* ne_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_ne(ct1, ct2, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* scalar_ne_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheBool* bool_result = NULL; @@ -892,6 +1146,18 @@ void* scalar_ne_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_ne_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_ne(ct, pt, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* ge_fhe_uint8(void* ct1, void* ct2, void* sks) { FheBool* bool_result = NULL; @@ -928,6 +1194,18 @@ void* ge_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* ge_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_ge(ct1, ct2, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* scalar_ge_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheBool* bool_result = NULL; @@ -964,6 +1242,18 @@ void* scalar_ge_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_ge_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_ge(ct, pt, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_32(bool_result, sks); + return result; +} + void* gt_fhe_uint8(void* ct1, void* ct2, void* sks) { FheBool* bool_result = NULL; @@ -1000,6 +1290,18 @@ void* gt_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* gt_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_gt(ct1, ct2, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* scalar_gt_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheBool* bool_result = NULL; @@ -1036,6 +1338,18 @@ void* scalar_gt_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_gt_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_gt(ct, pt, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* le_fhe_uint8(void* ct1, void* ct2, void* sks) { FheBool* bool_result = NULL; @@ -1072,6 +1386,18 @@ void* le_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* le_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_le(ct1, ct2, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* scalar_le_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheBool* bool_result = NULL; @@ -1108,6 +1434,18 @@ void* scalar_le_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_le_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_le(ct, pt, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* lt_fhe_uint8(void* ct1, void* ct2, void* sks) { FheBool* bool_result = NULL; @@ -1144,6 +1482,18 @@ void* lt_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* lt_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_lt(ct1, ct2, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* scalar_lt_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheBool* bool_result = NULL; @@ -1180,6 +1530,18 @@ void* scalar_lt_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_lt_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheBool* bool_result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_lt(ct, pt, &bool_result); + if(r != 0) return NULL; + FheUint64* result = cast_bool_64(bool_result, sks); + return result; +} + void* min_fhe_uint8(void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -1213,6 +1575,17 @@ void* min_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* min_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_min(ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + void* scalar_min_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheUint8* result = NULL; @@ -1246,6 +1619,17 @@ void* scalar_min_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_min_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_min(ct, pt, &result); + if(r != 0) return NULL; + return result; +} + void* max_fhe_uint8(void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -1279,6 +1663,17 @@ void* max_fhe_uint32(void* ct1, void* ct2, void* sks) return result; } +void* max_fhe_uint64(void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_max(ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + void* scalar_max_fhe_uint8(void* ct, uint8_t pt, void* sks) { FheUint8* result = NULL; @@ -1312,6 +1707,17 @@ void* scalar_max_fhe_uint32(void* ct, uint32_t pt, void* sks) return result; } +void* scalar_max_fhe_uint64(void* ct, uint64_t pt, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_scalar_max(ct, pt, &result); + if(r != 0) return NULL; + return result; +} + void* neg_fhe_uint8(void* ct, void* sks) { FheUint8* result = NULL; @@ -1342,6 +1748,16 @@ void* neg_fhe_uint32(void* ct, void* sks) { return result; } +void* neg_fhe_uint64(void* ct, void* sks) { + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_neg(ct, &result); + if(r != 0) return NULL; + return result; +} + void* not_fhe_uint8(void* ct, void* sks) { FheUint8* result = NULL; @@ -1372,6 +1788,16 @@ void* not_fhe_uint32(void* ct, void* sks) { return result; } +void* not_fhe_uint64(void* ct, void* sks) { + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_not(ct, &result); + if(r != 0) return NULL; + return result; +} + void* if_then_else_fhe_uint8(void* condition, void* ct1, void* ct2, void* sks) { FheUint8* result = NULL; @@ -1411,6 +1837,19 @@ void* if_then_else_fhe_uint32(void* condition, void* ct1, void* ct2, void* sks) return result; } +void* if_then_else_fhe_uint64(void* condition, void* ct1, void* ct2, void* sks) +{ + FheUint64* result = NULL; + + checked_set_server_key(sks); + + FheBool* cond = cast_8_bool(condition, sks); + + const int r = fhe_uint64_if_then_else(cond, ct1, ct2, &result); + if(r != 0) return NULL; + return result; +} + int decrypt_fhe_uint8(void* cks, void* ct, uint8_t* res) { *res = 0; @@ -1429,6 +1868,12 @@ int decrypt_fhe_uint32(void* cks, void* ct, uint32_t* res) return fhe_uint32_decrypt(ct, cks, res); } +int decrypt_fhe_uint64(void* cks, void* ct, uint64_t* res) +{ + *res = 0; + return fhe_uint64_decrypt(ct, cks, res); +} + void* public_key_encrypt_fhe_uint8(void* pks, uint8_t value) { CompactFheUint8List* list = NULL; FheUint8* ct = NULL; @@ -1461,17 +1906,33 @@ void* public_key_encrypt_fhe_uint16(void* pks, uint16_t value) { return ct; } -void* public_key_encrypt_fhe_uint32(void* pks, uint32_t value) { - CompactFheUint32List* list = NULL; - FheUint32* ct = NULL; +void* public_key_encrypt_fhe_uint32(void* pks, uint32_t value) { + CompactFheUint32List* list = NULL; + FheUint32* ct = NULL; + + int r = compact_fhe_uint32_list_try_encrypt_with_compact_public_key_u32(&value, 1, pks, &list); + assert(r == 0); + + r = compact_fhe_uint32_list_expand(list, &ct, 1); + assert(r == 0); + + r = compact_fhe_uint32_list_destroy(list); + assert(r == 0); + + return ct; +} + +void* public_key_encrypt_fhe_uint64(void* pks, uint64_t value) { + CompactFheUint64List* list = NULL; + FheUint64* ct = NULL; - int r = compact_fhe_uint32_list_try_encrypt_with_compact_public_key_u32(&value, 1, pks, &list); + int r = compact_fhe_uint64_list_try_encrypt_with_compact_public_key_u64(&value, 1, pks, &list); assert(r == 0); - r = compact_fhe_uint32_list_expand(list, &ct, 1); + r = compact_fhe_uint64_list_expand(list, &ct, 1); assert(r == 0); - r = compact_fhe_uint32_list_destroy(list); + r = compact_fhe_uint64_list_destroy(list); assert(r == 0); return ct; @@ -1510,6 +1971,17 @@ void* trivial_encrypt_fhe_uint32(void* sks, uint32_t value) { return ct; } +void* trivial_encrypt_fhe_uint64(void* sks, uint64_t value) { + FheUint64* ct = NULL; + + checked_set_server_key(sks); + + int r = fhe_uint64_try_encrypt_trivial_u64(value, &ct); + assert(r == 0); + + return ct; +} + void public_key_encrypt_and_serialize_fhe_uint8_list(void* pks, uint8_t value, DynamicBuffer* out) { CompactFheUint8List* list = NULL; @@ -1549,6 +2021,19 @@ void public_key_encrypt_and_serialize_fhe_uint32_list(void* pks, uint32_t value, assert(r == 0); } +void public_key_encrypt_and_serialize_fhe_uint64_list(void* pks, uint64_t value, DynamicBuffer* out) { + CompactFheUint64List* list = NULL; + + int r = compact_fhe_uint64_list_try_encrypt_with_compact_public_key_u64(&value, 1, pks, &list); + assert(r == 0); + + r = compact_fhe_uint64_list_serialize(list, out); + assert(r == 0); + + r = compact_fhe_uint64_list_destroy(list); + assert(r == 0); +} + void* cast_8_16(void* ct, void* sks) { FheUint16* result = NULL; @@ -1569,6 +2054,16 @@ void* cast_8_32(void* ct, void* sks) { return result; } +void* cast_8_64(void* ct, void* sks) { + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint8_cast_into_fhe_uint64(ct, &result); + if(r != 0) return NULL; + return result; +} + void* cast_16_8(void* ct, void* sks) { FheUint8* result = NULL; @@ -1589,6 +2084,16 @@ void* cast_16_32(void* ct, void* sks) { return result; } +void* cast_16_64(void* ct, void* sks) { + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint16_cast_into_fhe_uint64(ct, &result); + if(r != 0) return NULL; + return result; +} + void* cast_32_8(void* ct, void* sks) { FheUint8* result = NULL; @@ -1609,6 +2114,46 @@ void* cast_32_16(void* ct, void* sks) { return result; } +void* cast_32_64(void* ct, void* sks) { + FheUint64* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint32_cast_into_fhe_uint64(ct, &result); + if(r != 0) return NULL; + return result; +} + +void* cast_64_8(void* ct, void* sks) { + FheUint8* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_cast_into_fhe_uint8(ct, &result); + if(r != 0) return NULL; + return result; +} + +void* cast_64_16(void* ct, void* sks) { + FheUint16* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_cast_into_fhe_uint16(ct, &result); + if(r != 0) return NULL; + return result; +} + +void* cast_64_32(void* ct, void* sks) { + FheUint32* result = NULL; + + checked_set_server_key(sks); + + const int r = fhe_uint64_cast_into_fhe_uint32(ct, &result); + if(r != 0) return NULL; + return result; +} + */ import "C" @@ -1670,10 +2215,12 @@ func initCiphertextSizes() { expandedFheCiphertextSize[FheUint8] = uint(len(new(tfheCiphertext).trivialEncrypt(*big.NewInt(0), FheUint8).serialize())) expandedFheCiphertextSize[FheUint16] = uint(len(new(tfheCiphertext).trivialEncrypt(*big.NewInt(0), FheUint16).serialize())) expandedFheCiphertextSize[FheUint32] = uint(len(new(tfheCiphertext).trivialEncrypt(*big.NewInt(0), FheUint32).serialize())) + expandedFheCiphertextSize[FheUint64] = uint(len(new(tfheCiphertext).trivialEncrypt(*big.NewInt(0), FheUint64).serialize())) compactFheCiphertextSize[FheUint8] = uint(len(encryptAndSerializeCompact(0, FheUint8))) compactFheCiphertextSize[FheUint16] = uint(len(encryptAndSerializeCompact(0, FheUint16))) compactFheCiphertextSize[FheUint32] = uint(len(encryptAndSerializeCompact(0, FheUint32))) + compactFheCiphertextSize[FheUint64] = uint(len(encryptAndSerializeCompact(0, FheUint64))) } func InitGlobalKeysFromFiles(keysDir string) error { @@ -1728,6 +2275,8 @@ func serialize(ptr unsafe.Pointer, t FheUintType) ([]byte, error) { ret = C.serialize_fhe_uint16(ptr, out) case FheUint32: ret = C.serialize_fhe_uint32(ptr, out) + case FheUint64: + ret = C.serialize_fhe_uint64(ptr, out) default: panic("serialize: unexpected ciphertext type") } @@ -1758,6 +2307,7 @@ const ( FheUint8 FheUintType = 0 FheUint16 FheUintType = 1 FheUint32 FheUintType = 2 + FheUint64 FheUintType = 3 ) // Represents an expanded TFHE ciphertext. @@ -1788,6 +2338,12 @@ func (ct *tfheCiphertext) deserialize(in []byte, t FheUintType) error { return errors.New("FheUint32 ciphertext deserialization failed") } C.destroy_fhe_uint32(ptr) + case FheUint64: + ptr := C.deserialize_fhe_uint64(toDynamicBufferView((in))) + if ptr == nil { + return errors.New("FheUint64 ciphertext deserialization failed") + } + C.destroy_fhe_uint64(ptr) default: panic("deserialize: unexpected ciphertext type") } @@ -1835,6 +2391,17 @@ func (ct *tfheCiphertext) deserializeCompact(in []byte, t FheUintType) error { if err != nil { return err } + case FheUint64: + ptr := C.deserialize_compact_fhe_uint64(toDynamicBufferView((in))) + if ptr == nil { + return errors.New("compact FheUint64 ciphertext deserialization failed") + } + var err error + ct.serialization, err = serialize(ptr, t) + C.destroy_fhe_uint64(ptr) + if err != nil { + return err + } default: panic("deserializeCompact: unexpected ciphertext type") } @@ -1870,6 +2437,13 @@ func (ct *tfheCiphertext) encrypt(value big.Int, t FheUintType) *tfheCiphertext if err != nil { panic(err) } + case FheUint64: + ptr = C.public_key_encrypt_fhe_uint64(pks, C.uint64_t(value.Uint64())) + ct.serialization, err = serialize(ptr, t) + C.destroy_fhe_uint64(ptr) + if err != nil { + panic(err) + } default: panic("encrypt: unexpected ciphertext type") } @@ -1903,6 +2477,13 @@ func (ct *tfheCiphertext) trivialEncrypt(value big.Int, t FheUintType) *tfheCiph if err != nil { panic(err) } + case FheUint64: + ptr = C.trivial_encrypt_fhe_uint64(sks, C.uint64_t(value.Uint64())) + ct.serialization, err = serialize(ptr, t) + C.destroy_fhe_uint64(ptr) + if err != nil { + panic(err) + } default: panic("trivialEncrypt: unexpected ciphertext type") } @@ -1918,7 +2499,8 @@ func (ct *tfheCiphertext) serialize() []byte { func (ct *tfheCiphertext) executeUnaryCiphertextOperation(rhs *tfheCiphertext, op8 func(ct unsafe.Pointer) unsafe.Pointer, op16 func(ct unsafe.Pointer) unsafe.Pointer, - op32 func(ct unsafe.Pointer) unsafe.Pointer) (*tfheCiphertext, error) { + op32 func(ct unsafe.Pointer) unsafe.Pointer, + op64 func(ct unsafe.Pointer) unsafe.Pointer) (*tfheCiphertext, error) { res := new(tfheCiphertext) res.fheUintType = ct.fheUintType @@ -1975,6 +2557,23 @@ func (ct *tfheCiphertext) executeUnaryCiphertextOperation(rhs *tfheCiphertext, } res.serialization = C.GoBytes(unsafe.Pointer(res_ser.pointer), C.int(res_ser.length)) C.destroy_dynamic_buffer(res_ser) + case FheUint64: + ct_ptr := C.deserialize_fhe_uint64(toDynamicBufferView((ct.serialization))) + if ct_ptr == nil { + return nil, errors.New("64 bit unary op deserialization failed") + } + res_ptr := op64(ct_ptr) + C.destroy_fhe_uint64(ct_ptr) + if res_ptr == nil { + return nil, errors.New("64 bit op failed") + } + ret := C.serialize_fhe_uint64(res_ptr, res_ser) + C.destroy_fhe_uint64(res_ptr) + if ret != 0 { + return nil, errors.New("64 bit unary op serialization failed") + } + res.serialization = C.GoBytes(unsafe.Pointer(res_ser.pointer), C.int(res_ser.length)) + C.destroy_dynamic_buffer(res_ser) default: panic("unary op unexpected ciphertext type") } @@ -1985,7 +2584,8 @@ func (ct *tfheCiphertext) executeUnaryCiphertextOperation(rhs *tfheCiphertext, func (lhs *tfheCiphertext) executeBinaryCiphertextOperation(rhs *tfheCiphertext, op8 func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer, op16 func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer, - op32 func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer) (*tfheCiphertext, error) { + op32 func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer, + op64 func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer) (*tfheCiphertext, error) { if lhs.fheUintType != rhs.fheUintType { return nil, errors.New("binary operations are only well-defined for identical types") } @@ -2063,6 +2663,29 @@ func (lhs *tfheCiphertext) executeBinaryCiphertextOperation(rhs *tfheCiphertext, } res.serialization = C.GoBytes(unsafe.Pointer(res_ser.pointer), C.int(res_ser.length)) C.destroy_dynamic_buffer(res_ser) + case FheUint64: + lhs_ptr := C.deserialize_fhe_uint64(toDynamicBufferView((lhs.serialization))) + if lhs_ptr == nil { + return nil, errors.New("64 bit binary op deserialization failed") + } + rhs_ptr := C.deserialize_fhe_uint64(toDynamicBufferView((rhs.serialization))) + if rhs_ptr == nil { + C.destroy_fhe_uint64(lhs_ptr) + return nil, errors.New("64 bit binary op deserialization failed") + } + res_ptr := op64(lhs_ptr, rhs_ptr) + C.destroy_fhe_uint64(lhs_ptr) + C.destroy_fhe_uint64(rhs_ptr) + if res_ptr == nil { + return nil, errors.New("64 bit binary op failed") + } + ret := C.serialize_fhe_uint64(res_ptr, res_ser) + C.destroy_fhe_uint64(res_ptr) + if ret != 0 { + return nil, errors.New("64 bit binary op serialization failed") + } + res.serialization = C.GoBytes(unsafe.Pointer(res_ser.pointer), C.int(res_ser.length)) + C.destroy_dynamic_buffer(res_ser) default: panic("binary op unexpected ciphertext type") } @@ -2073,7 +2696,8 @@ func (lhs *tfheCiphertext) executeBinaryCiphertextOperation(rhs *tfheCiphertext, func (first *tfheCiphertext) executeTernaryCiphertextOperation(lhs *tfheCiphertext, rhs *tfheCiphertext, op8 func(first unsafe.Pointer, lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer, op16 func(first unsafe.Pointer, lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer, - op32 func(first unsafe.Pointer, lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer) (*tfheCiphertext, error) { + op32 func(first unsafe.Pointer, lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer, + op64 func(first unsafe.Pointer, lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer) (*tfheCiphertext, error) { if lhs.fheUintType != rhs.fheUintType { return nil, errors.New("ternary operations are only well-defined for identical types") } @@ -2169,6 +2793,35 @@ func (first *tfheCiphertext) executeTernaryCiphertextOperation(lhs *tfheCipherte } res.serialization = C.GoBytes(unsafe.Pointer(res_ser.pointer), C.int(res_ser.length)) C.destroy_dynamic_buffer(res_ser) + case FheUint64: + lhs_ptr := C.deserialize_fhe_uint64(toDynamicBufferView((lhs.serialization))) + if lhs_ptr == nil { + return nil, errors.New("64 bit binary op deserialization failed") + } + rhs_ptr := C.deserialize_fhe_uint64(toDynamicBufferView((rhs.serialization))) + if rhs_ptr == nil { + C.destroy_fhe_uint64(lhs_ptr) + return nil, errors.New("64 bit binary op deserialization failed") + } + first_ptr := C.deserialize_fhe_uint8(toDynamicBufferView((first.serialization))) + if first_ptr == nil { + C.destroy_fhe_uint8(lhs_ptr) + C.destroy_fhe_uint8(rhs_ptr) + return nil, errors.New("8 bit binary op deserialization failed") + } + res_ptr := op64(first_ptr, lhs_ptr, rhs_ptr) + C.destroy_fhe_uint64(lhs_ptr) + C.destroy_fhe_uint64(rhs_ptr) + if res_ptr == nil { + return nil, errors.New("64 bit binary op failed") + } + ret := C.serialize_fhe_uint64(res_ptr, res_ser) + C.destroy_fhe_uint64(res_ptr) + if ret != 0 { + return nil, errors.New("64 bit binary op serialization failed") + } + res.serialization = C.GoBytes(unsafe.Pointer(res_ser.pointer), C.int(res_ser.length)) + C.destroy_dynamic_buffer(res_ser) default: panic("binary op unexpected ciphertext type") } @@ -2179,7 +2832,8 @@ func (first *tfheCiphertext) executeTernaryCiphertextOperation(lhs *tfheCipherte func (lhs *tfheCiphertext) executeBinaryScalarOperation(rhs uint64, op8 func(lhs unsafe.Pointer, rhs C.uint8_t) unsafe.Pointer, op16 func(lhs unsafe.Pointer, rhs C.uint16_t) unsafe.Pointer, - op32 func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer) (*tfheCiphertext, error) { + op32 func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer, + op64 func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer) (*tfheCiphertext, error) { res := new(tfheCiphertext) res.fheUintType = lhs.fheUintType res_ser := &C.DynamicBuffer{} @@ -2238,6 +2892,24 @@ func (lhs *tfheCiphertext) executeBinaryScalarOperation(rhs uint64, } res.serialization = C.GoBytes(unsafe.Pointer(res_ser.pointer), C.int(res_ser.length)) C.destroy_dynamic_buffer(res_ser) + case FheUint64: + lhs_ptr := C.deserialize_fhe_uint64(toDynamicBufferView((lhs.serialization))) + if lhs_ptr == nil { + return nil, errors.New("64 bit scalar op deserialization failed") + } + scalar := C.uint64_t(rhs) + res_ptr := op64(lhs_ptr, scalar) + C.destroy_fhe_uint64(lhs_ptr) + if res_ptr == nil { + return nil, errors.New("64 bit scalar op failed") + } + ret := C.serialize_fhe_uint64(res_ptr, res_ser) + C.destroy_fhe_uint64(res_ptr) + if ret != 0 { + return nil, errors.New("64 bit scalar op serialization failed") + } + res.serialization = C.GoBytes(unsafe.Pointer(res_ser.pointer), C.int(res_ser.length)) + C.destroy_dynamic_buffer(res_ser) default: panic("scalar op unexpected ciphertext type") } @@ -2255,6 +2927,9 @@ func (lhs *tfheCiphertext) add(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.add_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.add_fhe_uint64(lhs, rhs, sks) }) } @@ -2268,6 +2943,9 @@ func (lhs *tfheCiphertext) scalarAdd(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_add_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_add_fhe_uint64(lhs, rhs, sks) }) } @@ -2281,6 +2959,9 @@ func (lhs *tfheCiphertext) sub(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.sub_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.sub_fhe_uint64(lhs, rhs, sks) }) } @@ -2294,6 +2975,9 @@ func (lhs *tfheCiphertext) scalarSub(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_sub_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_sub_fhe_uint64(lhs, rhs, sks) }) } @@ -2307,6 +2991,9 @@ func (lhs *tfheCiphertext) mul(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.mul_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.mul_fhe_uint64(lhs, rhs, sks) }) } @@ -2320,6 +3007,9 @@ func (lhs *tfheCiphertext) scalarMul(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_mul_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_mul_fhe_uint64(lhs, rhs, sks) }) } @@ -2333,6 +3023,9 @@ func (lhs *tfheCiphertext) scalarDiv(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_div_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_div_fhe_uint64(lhs, rhs, sks) }) } @@ -2346,6 +3039,9 @@ func (lhs *tfheCiphertext) scalarRem(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_rem_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_rem_fhe_uint64(lhs, rhs, sks) }) } @@ -2359,6 +3055,9 @@ func (lhs *tfheCiphertext) bitand(rhs *tfheCiphertext) (*tfheCiphertext, error) }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.bitand_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.bitand_fhe_uint64(lhs, rhs, sks) }) } @@ -2372,6 +3071,9 @@ func (lhs *tfheCiphertext) bitor(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.bitor_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.bitor_fhe_uint64(lhs, rhs, sks) }) } @@ -2385,6 +3087,9 @@ func (lhs *tfheCiphertext) bitxor(rhs *tfheCiphertext) (*tfheCiphertext, error) }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.bitxor_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.bitxor_fhe_uint64(lhs, rhs, sks) }) } @@ -2398,6 +3103,9 @@ func (lhs *tfheCiphertext) shl(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.shl_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.shl_fhe_uint64(lhs, rhs, sks) }) } @@ -2411,6 +3119,9 @@ func (lhs *tfheCiphertext) scalarShl(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_shl_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_shl_fhe_uint64(lhs, rhs, sks) }) } @@ -2424,6 +3135,9 @@ func (lhs *tfheCiphertext) shr(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.shr_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.shr_fhe_uint64(lhs, rhs, sks) }) } @@ -2437,6 +3151,9 @@ func (lhs *tfheCiphertext) scalarShr(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_shr_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_shr_fhe_uint64(lhs, rhs, sks) }) } @@ -2450,6 +3167,9 @@ func (lhs *tfheCiphertext) eq(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.eq_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.eq_fhe_uint64(lhs, rhs, sks) }) } @@ -2463,6 +3183,9 @@ func (lhs *tfheCiphertext) scalarEq(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_eq_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_eq_fhe_uint64(lhs, rhs, sks) }) } @@ -2476,6 +3199,9 @@ func (lhs *tfheCiphertext) ne(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.ne_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.ne_fhe_uint64(lhs, rhs, sks) }) } @@ -2489,6 +3215,9 @@ func (lhs *tfheCiphertext) scalarNe(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_ne_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_ne_fhe_uint64(lhs, rhs, sks) }) } @@ -2502,6 +3231,9 @@ func (lhs *tfheCiphertext) ge(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.ge_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.ge_fhe_uint64(lhs, rhs, sks) }) } @@ -2515,6 +3247,9 @@ func (lhs *tfheCiphertext) scalarGe(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_ge_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_ge_fhe_uint64(lhs, rhs, sks) }) } @@ -2528,6 +3263,9 @@ func (lhs *tfheCiphertext) gt(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.gt_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.gt_fhe_uint64(lhs, rhs, sks) }) } @@ -2541,6 +3279,9 @@ func (lhs *tfheCiphertext) scalarGt(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_gt_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_gt_fhe_uint64(lhs, rhs, sks) }) } @@ -2554,6 +3295,9 @@ func (lhs *tfheCiphertext) le(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.le_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.le_fhe_uint64(lhs, rhs, sks) }) } @@ -2568,7 +3312,9 @@ func (lhs *tfheCiphertext) scalarLe(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_le_fhe_uint32(lhs, rhs, sks) - + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_le_fhe_uint64(lhs, rhs, sks) }) } @@ -2582,6 +3328,9 @@ func (lhs *tfheCiphertext) lt(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.lt_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.lt_fhe_uint64(lhs, rhs, sks) }) } @@ -2595,6 +3344,9 @@ func (lhs *tfheCiphertext) scalarLt(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_lt_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_lt_fhe_uint64(lhs, rhs, sks) }) } @@ -2608,6 +3360,9 @@ func (lhs *tfheCiphertext) min(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.min_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.min_fhe_uint64(lhs, rhs, sks) }) } @@ -2621,6 +3376,9 @@ func (lhs *tfheCiphertext) scalarMin(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_min_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_min_fhe_uint64(lhs, rhs, sks) }) } @@ -2634,6 +3392,9 @@ func (lhs *tfheCiphertext) max(rhs *tfheCiphertext) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.max_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.max_fhe_uint64(lhs, rhs, sks) }) } @@ -2647,6 +3408,9 @@ func (lhs *tfheCiphertext) scalarMax(rhs uint64) (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer, rhs C.uint32_t) unsafe.Pointer { return C.scalar_max_fhe_uint32(lhs, rhs, sks) + }, + func(lhs unsafe.Pointer, rhs C.uint64_t) unsafe.Pointer { + return C.scalar_max_fhe_uint64(lhs, rhs, sks) }) } @@ -2660,6 +3424,9 @@ func (lhs *tfheCiphertext) neg() (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer) unsafe.Pointer { return C.neg_fhe_uint32(lhs, sks) + }, + func(lhs unsafe.Pointer) unsafe.Pointer { + return C.neg_fhe_uint64(lhs, sks) }) } @@ -2673,6 +3440,9 @@ func (lhs *tfheCiphertext) not() (*tfheCiphertext, error) { }, func(lhs unsafe.Pointer) unsafe.Pointer { return C.not_fhe_uint32(lhs, sks) + }, + func(lhs unsafe.Pointer) unsafe.Pointer { + return C.not_fhe_uint64(lhs, sks) }) } @@ -2686,6 +3456,9 @@ func (condition *tfheCiphertext) ifThenElse(lhs *tfheCiphertext, rhs *tfheCipher }, func(condition unsafe.Pointer, lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { return C.if_then_else_fhe_uint32(condition, lhs, rhs, sks) + }, + func(condition unsafe.Pointer, lhs unsafe.Pointer, rhs unsafe.Pointer) unsafe.Pointer { + return C.if_then_else_fhe_uint64(condition, lhs, rhs, sks) }) } @@ -2732,6 +3505,22 @@ func (ct *tfheCiphertext) castTo(castToType FheUintType) (*tfheCiphertext, error if err != nil { return nil, err } + case FheUint64: + from_ptr := C.deserialize_fhe_uint8(toDynamicBufferView(ct.serialization)) + if from_ptr == nil { + return nil, errors.New("castTo failed to deserialize FheUint8 ciphertext") + } + to_ptr := C.cast_8_64(from_ptr, sks) + C.destroy_fhe_uint8(from_ptr) + if to_ptr == nil { + return nil, errors.New("castTo failed to cast FheUint8 to FheUint64") + } + var err error + res.serialization, err = serialize(to_ptr, castToType) + C.destroy_fhe_uint64(to_ptr) + if err != nil { + return nil, err + } default: panic("castTo: unexpected type to cast to") } @@ -2769,6 +3558,22 @@ func (ct *tfheCiphertext) castTo(castToType FheUintType) (*tfheCiphertext, error if err != nil { return nil, err } + case FheUint64: + from_ptr := C.deserialize_fhe_uint16(toDynamicBufferView(ct.serialization)) + if from_ptr == nil { + return nil, errors.New("castTo failed to deserialize FheUint16 ciphertext") + } + to_ptr := C.cast_16_64(from_ptr, sks) + C.destroy_fhe_uint16(from_ptr) + if to_ptr == nil { + return nil, errors.New("castTo failed to cast FheUint16 to FheUint64") + } + var err error + res.serialization, err = serialize(to_ptr, castToType) + C.destroy_fhe_uint64(to_ptr) + if err != nil { + return nil, err + } default: panic("castTo: unexpected type to cast to") } @@ -2806,6 +3611,75 @@ func (ct *tfheCiphertext) castTo(castToType FheUintType) (*tfheCiphertext, error if err != nil { return nil, err } + case FheUint64: + from_ptr := C.deserialize_fhe_uint32(toDynamicBufferView(ct.serialization)) + if from_ptr == nil { + return nil, errors.New("castTo failed to deserialize FheUint32 ciphertext") + } + to_ptr := C.cast_32_64(from_ptr, sks) + C.destroy_fhe_uint32(from_ptr) + if to_ptr == nil { + return nil, errors.New("castTo failed to cast FheUint32 to FheUint64") + } + var err error + res.serialization, err = serialize(to_ptr, castToType) + C.destroy_fhe_uint64(to_ptr) + if err != nil { + return nil, err + } + default: + panic("castTo: unexpected type to cast to") + } + case FheUint64: + switch castToType { + case FheUint8: + from_ptr := C.deserialize_fhe_uint64(toDynamicBufferView(ct.serialization)) + if from_ptr == nil { + return nil, errors.New("castTo failed to deserialize FheUint64 ciphertext") + } + to_ptr := C.cast_64_8(from_ptr, sks) + C.destroy_fhe_uint64(from_ptr) + if to_ptr == nil { + return nil, errors.New("castTo failed to cast FheUint64 to FheUint8") + } + var err error + res.serialization, err = serialize(to_ptr, castToType) + C.destroy_fhe_uint8(to_ptr) + if err != nil { + return nil, err + } + case FheUint16: + from_ptr := C.deserialize_fhe_uint64(toDynamicBufferView(ct.serialization)) + if from_ptr == nil { + return nil, errors.New("castTo failed to deserialize FheUint64 ciphertext") + } + to_ptr := C.cast_64_16(from_ptr, sks) + C.destroy_fhe_uint64(from_ptr) + if to_ptr == nil { + return nil, errors.New("castTo failed to cast FheUint64 to FheUint16") + } + var err error + res.serialization, err = serialize(to_ptr, castToType) + C.destroy_fhe_uint16(to_ptr) + if err != nil { + return nil, err + } + case FheUint32: + from_ptr := C.deserialize_fhe_uint64(toDynamicBufferView(ct.serialization)) + if from_ptr == nil { + return nil, errors.New("castTo failed to deserialize FheUint64 ciphertext") + } + to_ptr := C.cast_64_32(from_ptr, sks) + C.destroy_fhe_uint64(from_ptr) + if to_ptr == nil { + return nil, errors.New("castTo failed to cast FheUint64 to FheUint32") + } + var err error + res.serialization, err = serialize(to_ptr, castToType) + C.destroy_fhe_uint32(to_ptr) + if err != nil { + return nil, err + } default: panic("castTo: unexpected type to cast to") } @@ -2848,6 +3722,15 @@ func (ct *tfheCiphertext) decrypt() (big.Int, error) { ret = C.decrypt_fhe_uint32(cks, ptr, &result) C.destroy_fhe_uint32(ptr) value = uint64(result) + case FheUint64: + ptr := C.deserialize_fhe_uint64(toDynamicBufferView(ct.serialization)) + if ptr == nil { + return *new(big.Int).SetUint64(0), errors.New("failed to deserialize FheUint64") + } + var result C.uint64_t + ret = C.decrypt_fhe_uint64(cks, ptr, &result) + C.destroy_fhe_uint64(ptr) + value = uint64(result) default: panic("decrypt: unexpected ciphertext type") } @@ -2871,13 +3754,13 @@ func (ct *tfheCiphertext) getHash() common.Hash { } func isValidType(t byte) bool { - if uint8(t) < uint8(FheUint8) || uint8(t) > uint8(FheUint32) { + if uint8(t) < uint8(FheUint8) || uint8(t) > uint8(FheUint64) { return false } return true } -func encryptAndSerializeCompact(value uint32, fheUintType FheUintType) []byte { +func encryptAndSerializeCompact(value uint64, fheUintType FheUintType) []byte { out := &C.DynamicBuffer{} switch fheUintType { case FheUint8: @@ -2886,6 +3769,8 @@ func encryptAndSerializeCompact(value uint32, fheUintType FheUintType) []byte { C.public_key_encrypt_and_serialize_fhe_uint16_list(pks, C.uint16_t(value), out) case FheUint32: C.public_key_encrypt_and_serialize_fhe_uint32_list(pks, C.uint32_t(value), out) + case FheUint64: + C.public_key_encrypt_and_serialize_fhe_uint64_list(pks, C.uint64_t(value), out) } ser := C.GoBytes(unsafe.Pointer(out.pointer), C.int(out.length)) diff --git a/fhevm/tfhe_test.go b/fhevm/tfhe_test.go index b0da366..a6cfae7 100644 --- a/fhevm/tfhe_test.go +++ b/fhevm/tfhe_test.go @@ -47,6 +47,8 @@ func TfheEncryptDecrypt(t *testing.T, fheUintType FheUintType) { val.SetUint64(1337) case FheUint32: val.SetUint64(1333337) + case FheUint64: + val.SetUint64(13333377777777777) } ct := new(tfheCiphertext) ct.encrypt(val, fheUintType) @@ -65,6 +67,8 @@ func TfheTrivialEncryptDecrypt(t *testing.T, fheUintType FheUintType) { val.SetUint64(1337) case FheUint32: val.SetUint64(1333337) + case FheUint64: + val.SetUint64(13333377777777777) } ct := new(tfheCiphertext) ct.trivialEncrypt(val, fheUintType) @@ -83,6 +87,8 @@ func TfheSerializeDeserialize(t *testing.T, fheUintType FheUintType) { val = *big.NewInt(1337) case FheUint32: val = *big.NewInt(1333337) + case FheUint64: + val = *big.NewInt(13333377777777777) } ct1 := new(tfheCiphertext) ct1.encrypt(val, fheUintType) @@ -99,7 +105,7 @@ func TfheSerializeDeserialize(t *testing.T, fheUintType FheUintType) { } func TfheSerializeDeserializeCompact(t *testing.T, fheUintType FheUintType) { - var val uint32 + var val uint64 switch fheUintType { case FheUint8: val = 2 @@ -107,6 +113,8 @@ func TfheSerializeDeserializeCompact(t *testing.T, fheUintType FheUintType) { val = 1337 case FheUint32: val = 1333337 + case FheUint64: + val = 13333377777777777 } ser := encryptAndSerializeCompact(val, fheUintType) @@ -129,7 +137,7 @@ func TfheSerializeDeserializeCompact(t *testing.T, fheUintType FheUintType) { } decrypted, err := ct2.decrypt() - if err != nil || uint32(decrypted.Uint64()) != val { + if err != nil || uint64(decrypted.Uint64()) != val { t.Fatalf("decrypted value is incorrect") } } @@ -143,6 +151,8 @@ func TfheTrivialSerializeDeserialize(t *testing.T, fheUintType FheUintType) { val = *big.NewInt(1337) case FheUint32: val = *big.NewInt(1333337) + case FheUint64: + val = *big.NewInt(13333377777777777) } ct1 := new(tfheCiphertext) ct1.trivialEncrypt(val, fheUintType) @@ -169,7 +179,7 @@ func TfheDeserializeFailure(t *testing.T, fheUintType FheUintType) { } func TfheDeserializeCompact(t *testing.T, fheUintType FheUintType) { - var val uint32 + var val uint64 switch fheUintType { case FheUint8: val = 2 @@ -177,6 +187,8 @@ func TfheDeserializeCompact(t *testing.T, fheUintType FheUintType) { val = 1337 case FheUint32: val = 1333337 + case FheUint64: + val = 13333377777777777 } ser := encryptAndSerializeCompact(val, fheUintType) ct := new(tfheCiphertext) @@ -185,7 +197,7 @@ func TfheDeserializeCompact(t *testing.T, fheUintType FheUintType) { t.Fatalf("compact deserialization failed") } decryptedVal, err := ct.decrypt() - if err != nil || uint32(decryptedVal.Uint64()) != val { + if err != nil || uint64(decryptedVal.Uint64()) != val { t.Fatalf("compact deserialization wrong decryption") } } @@ -210,6 +222,9 @@ func TfheAdd(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13333377777777777) + b.SetUint64(133337777777777) } expected := new(big.Int).Add(&a, &b) ctA := new(tfheCiphertext) @@ -235,6 +250,9 @@ func TfheScalarAdd(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13333377777777777) + b.SetUint64(133337777777777) } expected := new(big.Int).Add(&a, &b) ctA := new(tfheCiphertext) @@ -258,6 +276,9 @@ func TfheSub(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13333377777777777) + b.SetUint64(133337777777777) } expected := new(big.Int).Sub(&a, &b) ctA := new(tfheCiphertext) @@ -283,6 +304,9 @@ func TfheScalarSub(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13333377777777777) + b.SetUint64(133337777777777) } expected := new(big.Int).Sub(&a, &b) ctA := new(tfheCiphertext) @@ -306,6 +330,9 @@ func TfheMul(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(1337) + b.SetUint64(133) } expected := new(big.Int).Mul(&a, &b) ctA := new(tfheCiphertext) @@ -331,6 +358,9 @@ func TfheScalarMul(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(1337) + b.SetUint64(133) } expected := new(big.Int).Mul(&a, &b) ctA := new(tfheCiphertext) @@ -354,6 +384,9 @@ func TfheScalarDiv(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(70) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } expected := new(big.Int).Div(&a, &b) ctA := new(tfheCiphertext) @@ -377,6 +410,9 @@ func TfheScalarRem(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(70) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } expected := new(big.Int).Rem(&a, &b) ctA := new(tfheCiphertext) @@ -400,6 +436,9 @@ func TfheBitAnd(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } expected := a.Uint64() & b.Uint64() ctA := new(tfheCiphertext) @@ -425,6 +464,9 @@ func TfheBitOr(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } expected := a.Uint64() | b.Uint64() ctA := new(tfheCiphertext) @@ -450,6 +492,9 @@ func TfheBitXor(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } expected := a.Uint64() ^ b.Uint64() ctA := new(tfheCiphertext) @@ -475,6 +520,9 @@ func TfheShl(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(45) } expected := new(big.Int).Lsh(&a, uint(b.Uint64())) ctA := new(tfheCiphertext) @@ -500,6 +548,9 @@ func TfheScalarShl(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(45) } expected := new(big.Int).Lsh(&a, uint(b.Uint64())) ctA := new(tfheCiphertext) @@ -523,6 +574,9 @@ func TfheShr(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } expected := new(big.Int).Rsh(&a, uint(b.Uint64())) ctA := new(tfheCiphertext) @@ -548,6 +602,9 @@ func TfheScalarShr(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } expected := new(big.Int).Rsh(&a, uint(b.Uint64())) ctA := new(tfheCiphertext) @@ -571,6 +628,9 @@ func TfheEq(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(137) + case FheUint64: + a.SetUint64(1337) + b.SetUint64(1337) } var expected uint64 expectedBool := a.Uint64() == b.Uint64() @@ -602,6 +662,9 @@ func TfheScalarEq(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } var expected uint64 expectedBool := a.Uint64() == b.Uint64() @@ -631,6 +694,9 @@ func TfheNe(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(137) + case FheUint64: + a.SetUint64(1337) + b.SetUint64(1337) } var expected uint64 expectedBool := a.Uint64() != b.Uint64() @@ -662,6 +728,9 @@ func TfheScalarNe(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(137) b.SetInt64(17) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } var expected uint64 expectedBool := a.Uint64() != b.Uint64() @@ -691,6 +760,9 @@ func TfheGe(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -720,6 +792,9 @@ func TfheScalarGe(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -742,6 +817,9 @@ func TfheGt(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -771,6 +849,9 @@ func TfheScalarGt(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -793,6 +874,9 @@ func TfheLe(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -822,6 +906,9 @@ func TfheScalarLe(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -844,6 +931,9 @@ func TfheLt(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -873,6 +963,9 @@ func TfheScalarLt(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -895,6 +988,9 @@ func TfheMin(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -924,6 +1020,9 @@ func TfheScalarMin(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -946,6 +1045,9 @@ func TfheMax(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -975,6 +1077,9 @@ func TfheScalarMax(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13371337) + b.SetUint64(1337) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -999,6 +1104,9 @@ func TfheNeg(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) expected = uint64(-uint32(a.Uint64())) + case FheUint64: + a.SetUint64(13333377777777777) + expected = uint64(-uint64(a.Uint64())) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -1022,6 +1130,9 @@ func TfheNot(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) expected = uint64(^uint32(a.Uint64())) + case FheUint64: + a.SetUint64(13333377777777777) + expected = uint64(^uint64(a.Uint64())) } ctA := new(tfheCiphertext) ctA.encrypt(a, fheUintType) @@ -1047,6 +1158,9 @@ func TfheIfThenElse(t *testing.T, fheUintType FheUintType) { case FheUint32: a.SetUint64(1333337) b.SetUint64(133337) + case FheUint64: + a.SetUint64(13333377777777777) + b.SetUint64(133337) } ctCondition := new(tfheCiphertext) ctCondition.encrypt(condition, fheUintType) @@ -1077,6 +1191,8 @@ func TfheCast(t *testing.T, fheUintTypeFrom FheUintType, fheUintTypeTo FheUintTy a.SetUint64(4283) case FheUint32: a.SetUint64(1333337) + case FheUint64: + a.SetUint64(13333377777777777) } var modulus uint64 @@ -1087,6 +1203,8 @@ func TfheCast(t *testing.T, fheUintTypeFrom FheUintType, fheUintTypeTo FheUintTy modulus = uint64(math.Pow(2, 16)) case FheUint32: modulus = uint64(math.Pow(2, 32)) + case FheUint64: + modulus = uint64(math.Pow(2, 64)) } ctA := new(tfheCiphertext) @@ -1118,6 +1236,10 @@ func TestTfheEncryptDecrypt32(t *testing.T) { TfheEncryptDecrypt(t, FheUint32) } +func TestTfheEncryptDecrypt64(t *testing.T) { + TfheEncryptDecrypt(t, FheUint64) +} + func TestTfheTrivialEncryptDecrypt8(t *testing.T) { TfheTrivialEncryptDecrypt(t, FheUint8) } @@ -1130,6 +1252,10 @@ func TestTfheTrivialEncryptDecrypt32(t *testing.T) { TfheTrivialEncryptDecrypt(t, FheUint32) } +func TestTfheTrivialEncryptDecrypt64(t *testing.T) { + TfheTrivialEncryptDecrypt(t, FheUint64) +} + func TestTfheSerializeDeserialize8(t *testing.T) { TfheSerializeDeserialize(t, FheUint8) } @@ -1142,6 +1268,10 @@ func TestTfheSerializeDeserialize32(t *testing.T) { TfheSerializeDeserialize(t, FheUint32) } +func TestTfheSerializeDeserialize64(t *testing.T) { + TfheSerializeDeserialize(t, FheUint64) +} + func TestTfheSerializeDeserializeCompact8(t *testing.T) { TfheSerializeDeserializeCompact(t, FheUint8) } @@ -1154,6 +1284,10 @@ func TestTfheSerializeDeserializeCompact32(t *testing.T) { TfheSerializeDeserializeCompact(t, FheUint32) } +func TestTfheSerializeDeserializeCompact64(t *testing.T) { + TfheSerializeDeserializeCompact(t, FheUint64) +} + func TestTfheTrivialSerializeDeserialize8(t *testing.T) { TfheTrivialSerializeDeserialize(t, FheUint8) } @@ -1166,6 +1300,10 @@ func TestTfheTrivialSerializeDeserialize32(t *testing.T) { TfheTrivialSerializeDeserialize(t, FheUint32) } +func TestTfheTrivialSerializeDeserialize64(t *testing.T) { + TfheTrivialSerializeDeserialize(t, FheUint64) +} + func TestTfheDeserializeFailure8(t *testing.T) { TfheDeserializeFailure(t, FheUint8) } @@ -1178,6 +1316,10 @@ func TestTfheDeserializeFailure32(t *testing.T) { TfheDeserializeFailure(t, FheUint32) } +func TestTfheDeserializeFailure64(t *testing.T) { + TfheDeserializeFailure(t, FheUint64) +} + func TestTfheDeserializeCompact8(t *testing.T) { TfheDeserializeCompact(t, FheUint8) } @@ -1186,10 +1328,14 @@ func TestTfheDeserializeCompact16(t *testing.T) { TfheDeserializeCompact(t, FheUint16) } -func TestTfheDeserializeCompatc32(t *testing.T) { +func TestTfheDeserializeCompact32(t *testing.T) { TfheDeserializeCompact(t, FheUint32) } +func TestTfheDeserializeCompact64(t *testing.T) { + TfheDeserializeCompact(t, FheUint64) +} + func TestTfheDeserializeCompactFailure8(t *testing.T) { TfheDeserializeCompactFailure(t, FheUint8) } @@ -1202,6 +1348,10 @@ func TestTfheDeserializeCompatcFailure32(t *testing.T) { TfheDeserializeCompactFailure(t, FheUint32) } +func TestTfheDeserializeCompatcFailure64(t *testing.T) { + TfheDeserializeCompactFailure(t, FheUint64) +} + func TestTfheAdd8(t *testing.T) { TfheAdd(t, FheUint8) } @@ -1214,6 +1364,10 @@ func TestTfheAdd32(t *testing.T) { TfheAdd(t, FheUint32) } +func TestTfheAdd64(t *testing.T) { + TfheAdd(t, FheUint64) +} + func TestTfheScalarAdd8(t *testing.T) { TfheScalarAdd(t, FheUint8) } @@ -1226,6 +1380,10 @@ func TestTfheScalarAdd32(t *testing.T) { TfheScalarAdd(t, FheUint32) } +func TestTfheScalarAdd64(t *testing.T) { + TfheScalarAdd(t, FheUint32) +} + func TestTfheSub8(t *testing.T) { TfheSub(t, FheUint8) } @@ -1238,6 +1396,10 @@ func TestTfheSub32(t *testing.T) { TfheSub(t, FheUint32) } +func TestTfheSub64(t *testing.T) { + TfheSub(t, FheUint64) +} + func TestTfheScalarSub8(t *testing.T) { TfheScalarSub(t, FheUint8) } @@ -1250,6 +1412,10 @@ func TestTfheScalarSub32(t *testing.T) { TfheScalarSub(t, FheUint32) } +func TestTfheScalarSub64(t *testing.T) { + TfheScalarSub(t, FheUint64) +} + func TestTfheMul8(t *testing.T) { TfheMul(t, FheUint8) } @@ -1262,6 +1428,10 @@ func TestTfheMul32(t *testing.T) { TfheMul(t, FheUint32) } +func TestTfheMul64(t *testing.T) { + TfheMul(t, FheUint64) +} + func TestTfheScalarMul8(t *testing.T) { TfheScalarMul(t, FheUint8) } @@ -1274,6 +1444,11 @@ func TestTfheScalarMul32(t *testing.T) { TfheScalarMul(t, FheUint32) } +func TestTfheScalarMul64(t *testing.T) { + TfheScalarMul(t, FheUint64) +} + + func TestTfheScalarDiv8(t *testing.T) { TfheScalarDiv(t, FheUint8) } @@ -1286,6 +1461,10 @@ func TestTfheScalarDiv32(t *testing.T) { TfheScalarDiv(t, FheUint32) } +func TestTfheScalarDiv64(t *testing.T) { + TfheScalarDiv(t, FheUint64) +} + func TestTfheScalarRem8(t *testing.T) { TfheScalarRem(t, FheUint8) } @@ -1298,6 +1477,10 @@ func TestTfheScalarRem32(t *testing.T) { TfheScalarRem(t, FheUint32) } +func TestTfheScalarRem64(t *testing.T) { + TfheScalarRem(t, FheUint64) +} + func TestTfheBitAnd8(t *testing.T) { TfheBitAnd(t, FheUint8) } @@ -1310,6 +1493,10 @@ func TestTfheBitAnd32(t *testing.T) { TfheBitAnd(t, FheUint32) } +func TestTfheBitAnd64(t *testing.T) { + TfheBitAnd(t, FheUint64) +} + func TestTfheBitOr8(t *testing.T) { TfheBitOr(t, FheUint8) } @@ -1322,6 +1509,10 @@ func TestTfheBitOr32(t *testing.T) { TfheBitOr(t, FheUint32) } +func TestTfheBitOr64(t *testing.T) { + TfheBitOr(t, FheUint64) +} + func TestTfheBitXor8(t *testing.T) { TfheBitXor(t, FheUint8) } @@ -1334,6 +1525,10 @@ func TestTfheBitXor32(t *testing.T) { TfheBitXor(t, FheUint32) } +func TestTfheBitXor64(t *testing.T) { + TfheBitXor(t, FheUint64) +} + func TestTfheShl8(t *testing.T) { TfheShl(t, FheUint8) } @@ -1346,6 +1541,10 @@ func TestTfheShl32(t *testing.T) { TfheShl(t, FheUint32) } +func TestTfheShl64(t *testing.T) { + TfheShl(t, FheUint64) +} + func TestTfheScalarShl8(t *testing.T) { TfheScalarShl(t, FheUint8) } @@ -1358,6 +1557,10 @@ func TestTfheScalarShl32(t *testing.T) { TfheScalarShl(t, FheUint32) } +func TestTfheScalarShl64(t *testing.T) { + TfheScalarShl(t, FheUint64) +} + func TestTfheShr8(t *testing.T) { TfheShr(t, FheUint8) } @@ -1370,6 +1573,10 @@ func TestTfheShr32(t *testing.T) { TfheShr(t, FheUint32) } +func TestTfheShr64(t *testing.T) { + TfheShr(t, FheUint64) +} + func TestTfheScalarShr8(t *testing.T) { TfheScalarShr(t, FheUint8) } @@ -1382,6 +1589,10 @@ func TestTfheScalarShr32(t *testing.T) { TfheScalarShr(t, FheUint32) } +func TestTfheScalarShr64(t *testing.T) { + TfheScalarShr(t, FheUint64) +} + func TestTfheEq8(t *testing.T) { TfheEq(t, FheUint8) } @@ -1394,6 +1605,10 @@ func TestTfheEq32(t *testing.T) { TfheEq(t, FheUint32) } +func TestTfheEq64(t *testing.T) { + TfheEq(t, FheUint64) +} + func TestTfheScalarEq8(t *testing.T) { TfheScalarEq(t, FheUint8) } @@ -1406,6 +1621,10 @@ func TestTfheScalarEq32(t *testing.T) { TfheScalarEq(t, FheUint32) } +func TestTfheScalarEq64(t *testing.T) { + TfheScalarEq(t, FheUint64) +} + func TestTfheNe8(t *testing.T) { TfheNe(t, FheUint8) } @@ -1418,6 +1637,10 @@ func TestTfheNe32(t *testing.T) { TfheNe(t, FheUint32) } +func TestTfheNe64(t *testing.T) { + TfheNe(t, FheUint64) +} + func TestTfheScalarNe8(t *testing.T) { TfheScalarNe(t, FheUint8) } @@ -1430,6 +1653,10 @@ func TestTfheScalarNe32(t *testing.T) { TfheScalarNe(t, FheUint32) } +func TestTfheScalarNe64(t *testing.T) { + TfheScalarNe(t, FheUint64) +} + func TestTfheGe8(t *testing.T) { TfheGe(t, FheUint8) } @@ -1442,6 +1669,10 @@ func TestTfheGe32(t *testing.T) { TfheGe(t, FheUint32) } +func TestTfheGe64(t *testing.T) { + TfheGe(t, FheUint64) +} + func TestTfheScalarGe8(t *testing.T) { TfheScalarGe(t, FheUint8) } @@ -1454,6 +1685,10 @@ func TestTfheScalarGe32(t *testing.T) { TfheScalarGe(t, FheUint32) } +func TestTfheScalarGe64(t *testing.T) { + TfheScalarGe(t, FheUint64) +} + func TestTfheGt8(t *testing.T) { TfheGt(t, FheUint8) } @@ -1466,6 +1701,10 @@ func TestTfheGt32(t *testing.T) { TfheGt(t, FheUint32) } +func TestTfheGt64(t *testing.T) { + TfheGt(t, FheUint64) +} + func TestTfheScalarGt8(t *testing.T) { TfheScalarGt(t, FheUint8) } @@ -1478,6 +1717,10 @@ func TestTfheScalarGt32(t *testing.T) { TfheScalarGt(t, FheUint32) } +func TestTfheScalarGt64(t *testing.T) { + TfheScalarGt(t, FheUint64) +} + func TestTfheLe8(t *testing.T) { TfheLe(t, FheUint8) } @@ -1490,6 +1733,10 @@ func TestTfheLe32(t *testing.T) { TfheLe(t, FheUint32) } +func TestTfheLe64(t *testing.T) { + TfheLe(t, FheUint64) +} + func TestTfheScalarLe8(t *testing.T) { TfheScalarLe(t, FheUint8) } @@ -1502,6 +1749,10 @@ func TestTfheScalarLe32(t *testing.T) { TfheScalarLe(t, FheUint32) } +func TestTfheScalarLe64(t *testing.T) { + TfheScalarLe(t, FheUint64) +} + func TestTfheLt8(t *testing.T) { TfheLt(t, FheUint8) } @@ -1512,6 +1763,9 @@ func TestTfheLt16(t *testing.T) { func TestTfheLt32(t *testing.T) { TfheLt(t, FheUint32) } +func TestTfheLt64(t *testing.T) { + TfheLt(t, FheUint64) +} func TestTfheScalarLt8(t *testing.T) { TfheScalarLt(t, FheUint8) @@ -1525,6 +1779,10 @@ func TestTfheScalarLt32(t *testing.T) { TfheScalarLt(t, FheUint32) } +func TestTfheScalarLt64(t *testing.T) { + TfheScalarLt(t, FheUint64) +} + func TestTfheMin8(t *testing.T) { TfheMin(t, FheUint8) } @@ -1535,6 +1793,9 @@ func TestTfheMin16(t *testing.T) { func TestTfheMin32(t *testing.T) { TfheMin(t, FheUint32) } +func TestTfheMin64(t *testing.T) { + TfheMin(t, FheUint64) +} func TestTfheScalarMin8(t *testing.T) { TfheScalarMin(t, FheUint8) @@ -1548,6 +1809,10 @@ func TestTfheScalarMin32(t *testing.T) { TfheScalarMin(t, FheUint32) } +func TestTfheScalarMin64(t *testing.T) { + TfheScalarMin(t, FheUint64) +} + func TestTfheMax8(t *testing.T) { TfheMax(t, FheUint8) } @@ -1558,6 +1823,9 @@ func TestTfheMax16(t *testing.T) { func TestTfheMax32(t *testing.T) { TfheMax(t, FheUint32) } +func TestTfheMax64(t *testing.T) { + TfheMax(t, FheUint64) +} func TestTfheScalarMax8(t *testing.T) { TfheScalarMax(t, FheUint8) @@ -1571,6 +1839,10 @@ func TestTfheScalarMax32(t *testing.T) { TfheScalarMax(t, FheUint32) } +func TestTfheScalarMax64(t *testing.T) { + TfheScalarMax(t, FheUint64) +} + func TestTfheNeg8(t *testing.T) { TfheNeg(t, FheUint8) } @@ -1581,6 +1853,9 @@ func TestTfheNeg16(t *testing.T) { func TestTfheNeg32(t *testing.T) { TfheNeg(t, FheUint32) } +func TestTfheNeg64(t *testing.T) { + TfheNeg(t, FheUint64) +} func TestTfheNot8(t *testing.T) { TfheNot(t, FheUint8) @@ -1592,6 +1867,9 @@ func TestTfheNot16(t *testing.T) { func TestTfheNot32(t *testing.T) { TfheNot(t, FheUint32) } +func TestTfheNot64(t *testing.T) { + TfheNot(t, FheUint64) +} func TestTfheIfThenElse8(t *testing.T) { TfheIfThenElse(t, FheUint8) @@ -1603,6 +1881,9 @@ func TestTfheIfThenElse16(t *testing.T) { func TestTfheIfThenElse32(t *testing.T) { TfheIfThenElse(t, FheUint32) } +func TestTfheIfThenElse64(t *testing.T) { + TfheIfThenElse(t, FheUint64) +} func TestTfhe8Cast16(t *testing.T) { TfheCast(t, FheUint8, FheUint16) @@ -1612,6 +1893,10 @@ func TestTfhe8Cast32(t *testing.T) { TfheCast(t, FheUint8, FheUint32) } +func TestTfhe8Cast64(t *testing.T) { + TfheCast(t, FheUint8, FheUint64) +} + func TestTfhe16Cast8(t *testing.T) { TfheCast(t, FheUint16, FheUint8) } @@ -1620,10 +1905,30 @@ func TestTfhe16Cast32(t *testing.T) { TfheCast(t, FheUint16, FheUint32) } +func TestTfhe16Cast64(t *testing.T) { + TfheCast(t, FheUint16, FheUint64) +} + func TestTfhe32Cast8(t *testing.T) { - TfheCast(t, FheUint16, FheUint8) + TfheCast(t, FheUint32, FheUint8) } func TestTfhe32Cast16(t *testing.T) { - TfheCast(t, FheUint16, FheUint8) + TfheCast(t, FheUint32, FheUint16) +} + +func TestTfhe32Cast64(t *testing.T) { + TfheCast(t, FheUint32, FheUint64) +} + +func TestTfhe64Cast8(t *testing.T) { + TfheCast(t, FheUint64, FheUint8) +} + +func TestTfhe64Cast16(t *testing.T) { + TfheCast(t, FheUint64, FheUint16) +} + +func TestTfhe64Cast32(t *testing.T) { + TfheCast(t, FheUint64, FheUint32) }