Skip to content

sp301415/tfhe-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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, as well as advanced algorithms such as:
    • BFV-style evaluation
    • PBSManyLUT [CLOT21]
    • Circuit Bootstrapping [WHS+24]
    • LMKCDEY/FHEW Bootstrapping [LMK+22]
    • Circuit Privacy/Sanitization [HMS25b]
  • 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()

enc := tfhe.NewEncryptor(params)

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

// Decrypt Everything!
fmt.Println(enc.DecryptLWE(ctLWE))
fmt.Println(enc.DecryptGLWE(ctGLWE)[:4])
// Output:
// 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)

// 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])
// Output:
// 5

Programmable Bootstrapping

params := tfhe.ParamsUint4.Compile()

enc := tfhe.NewEncryptor(params)

ct := enc.EncryptLWE(3)

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

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

Comparison using Binary TFHE

params := tfhe.ParamsBinary.Compile()

enc := tfhe.NewBinaryEncryptor(params)

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))
// Output:
// 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))
// Output:
// false

Benchmarks

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

Precision Bootstrapping Time
Binary 9.295ms
Uint2 7.187ms
Uint3 10.25ms
Uint4 12.47ms
Uint5 14.23ms
Uint6 21.88ms
Uint7 36.60ms
Uint8 78.88ms

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

About

Go implementation of (MK)TFHE scheme

Topics

Resources

License

Security policy

Stars

Watchers

Forks