/tfhe-go

Go implementation of (MK)TFHE scheme

Primary LanguageGoApache License 2.0Apache-2.0

TFHE-go

Go implementation of (MK)TFHE scheme

Important

TFHE-go is still under heavy development. There may be backward-incompatible changes at any time.

TFHE-go is a Go implementation of TFHE[CGGI16] and Multi-Key TFHE[KMS22] scheme. It provides:

  • Support for binary and integer TFHE and its multi-key variant
  • Pure Go implementation, along with SIMD-accelerated Go Assembly on amd64 platforms
  • Comparable performance to state-of-the-art C++/Rust libraries
  • Readable code and user-friendly API using modern Go features like generics

The goal of this library is to be fast, simple and versatile, offering a robust basis for researchers and developers interested in TFHE. The overall structure and design is heavily influenced by two excellent FHE libraries: Lattigo by Tune Insight, and TFHE-rs by Zama.

Installation

You can install TFHE-go in your project using go get:

$ go get -u github.com/sp301415/tfhe-go

TFHE-go uses Go Assembly for SIMD operations on amd64 platforms. To disable this, you can pass purego build tag.

Examples

Encryption

// Parameters must be compiled before use.
params := tfhe.ParamsUint4.Compile()

// Set up Encryptor.
enc := tfhe.NewEncryptor(params)

ctLWE := enc.EncryptLWE(4)
ctGLWE := enc.EncryptGLWE([]int{1, 2, 3, 4})

// Decrypt Everything!
fmt.Println(enc.DecryptLWE(ctLWE))       // 4
fmt.Println(enc.DecryptGLWE(ctGLWE)[:4]) // [1, 2, 3, 4]

CMUX

params := tfhe.ParamsUint4.Compile()
gadgetParams := tfhe.GadgetParametersLiteral[uint64]{
	Base:  1 << 3,
	Level: 6,
}.Compile()

enc := tfhe.NewEncryptor(params)

ct0 := enc.EncryptGLWE([]int{2})
ct1 := enc.EncryptGLWE([]int{5})
ctFlag := enc.EncryptFourierGGSW([]int{1}, gadgetParams)

// Set up Evaluator.
// Note that we don't need evaluation key for CMUX.
eval := tfhe.NewEvaluator(params, tfhe.EvaluationKey[uint64]{})

ctOut := eval.CMux(ctFlag, ct0, ct1)
fmt.Println(enc.DecryptGLWE(ctOut)[0]) // 5

Programmable Bootstrapping

params := tfhe.ParamsUint4.Compile()

enc := tfhe.NewEncryptor(params)

ct := enc.EncryptLWE(3)

// Set up Evaluator with EvaluationKey.
eval := tfhe.NewEvaluator(params, enc.GenEvaluationKeyParallel())

ctOut := eval.BootstrapFunc(ct, func(x int) int { return 2*x + 1 })
fmt.Println(enc.DecryptLWE(ctOut)) // 7 = 2*3+1

Comparison using Binary TFHE

params := tfhe.ParamsBinary.Compile()

enc := tfhe.NewBinaryEncryptor(params)

// Change these values yourself!
bits := 16
ct0 := enc.EncryptLWEBits(3, bits)
ct1 := enc.EncryptLWEBits(3, bits)

eval := tfhe.NewBinaryEvaluator(params, enc.GenEvaluationKeyParallel())

ctXNOR := tfhe.NewLWECiphertext(params)
ctOut := eval.XNOR(ct0[0], ct1[0])
for i := 1; i < bits; i++ {
	eval.XNORAssign(ct0[i], ct1[i], ctXNOR)
	eval.ANDAssign(ctXNOR, ctOut, ctOut)
}

fmt.Println(enc.DecryptLWEBool(ctOut)) // true

Multi-Key TFHE

// This parameters can take up to two parties.
params := mktfhe.ParamsBinaryParty2.Compile()

// Sample a seed for CRS.
seed := make([]byte, 512)
rand.Read(seed)

// Each Encryptor should be marked with index.
enc0 := mktfhe.NewBinaryEncryptor(params, 0, seed)
enc1 := mktfhe.NewBinaryEncryptor(params, 1, seed)

// Set up Decryptor.
// In practice, one should use a distributed decryption protocol
// to decrypt multi-key ciphertexts.
// However, in multi-key TFHE, this procedure is very difficult and slow.
// Therefore, we use a trusted third party for decryption.
dec := mktfhe.NewBinaryDecryptor(params, map[int]tfhe.SecretKey[uint64]{
  0: enc0.BaseEncryptor.SecretKey,
  1: enc1.BaseEncryptor.SecretKey,
})

ct0 := enc0.EncryptLWEBool(true)
ct1 := enc1.EncryptLWEBool(false)

// Set up Evaluator.
eval := mktfhe.NewBinaryEvaluator(params, map[int]mktfhe.EvaluationKey[uint64]{
  0: enc0.GenEvaluationKeyParallel(),
  1: enc1.GenEvaluationKeyParallel(),
})

// Execute AND operation in parallel.
ctOut := eval.ANDParallel(ct0, ct1)

fmt.Println(dec.DecryptLWEBool(ctOut)) // false

Benchmarks

All benchmarks were measured on a machine equipped with Intel Xeon Platinum 8268 CPU @ 2.90GHz and 384GB of RAM.

Operation TFHE-go TFHE-rs (v0.7.1)
Gate Bootstrapping 9.03ms 15.03ms
Programmable Bootstrapping (6 bits) 20.41ms 111.33ms

You can use the standard go test tool to reproduce benchmarks:

$ go test ./tfhe -run=^$ -bench="GateBootstrap|ProgrammableBootstrap"

Security

TFHE-go has not been audited or reviewed by security experts, and may contain critical vulnerabilities. Use at your own risk. See SECURITY for more details.

License

TFHE-go is licensed under the Apache 2.0 License.

Citing

To cite TFHE-go, please use the following BibTeX entry:

@misc{TFHE-go,
  title={{TFHE-go}},
  author={Intak Hwang},
  year={2023},
  howpublished = {Online: \url{https://github.com/sp301415/tfhe-go}},
}

Acknowledgements

Special thanks to Seonhong Min(@snu-lukemin) for providing many helpful insights. TFHE-go logo is designed by @mlgng2010, based on the Go Gopher by Renee French.

References