Files
fhe/decryptor.go
T

100 lines
2.1 KiB
Go
Raw Normal View History

2026-01-03 19:11:38 -08:00
// Copyright (c) 2025, Lux Industries Inc
// SPDX-License-Identifier: BSD-3-Clause
package fhe
import (
"github.com/luxfi/lattice/v7/core/rlwe"
"github.com/luxfi/lattice/v7/ring"
)
// Decryptor decrypts FHE ciphertexts to boolean values
type Decryptor struct {
params Parameters
decryptor *rlwe.Decryptor
ringQ *ring.Ring
}
// NewDecryptor creates a new decryptor from secret key
func NewDecryptor(params Parameters, sk *SecretKey) *Decryptor {
return &Decryptor{
params: params,
decryptor: rlwe.NewDecryptor(params.paramsLWE, sk.SKLWE),
ringQ: params.paramsLWE.RingQ(),
}
}
// Decrypt decrypts a ciphertext to a boolean
func (dec *Decryptor) Decrypt(ct *Ciphertext) bool {
pt := rlwe.NewPlaintext(dec.params.paramsLWE, ct.Level())
dec.decryptor.Decrypt(ct.Ciphertext, pt)
if pt.IsNTT {
dec.ringQ.INTT(pt.Value, pt.Value)
}
// Get the constant term
c := pt.Value.Coeffs[0][0]
q := dec.params.QLWE()
qHalf := q >> 1
// Decode:
// - true was encoded as Q/8, so c ∈ [0, Q/2) means true
// - false was encoded as 7Q/8, so c ∈ [Q/2, Q) means false
return c < qHalf
}
// DecryptBit returns the decrypted bit as int (0 or 1)
func (dec *Decryptor) DecryptBit(ct *Ciphertext) int {
if dec.Decrypt(ct) {
return 1
}
return 0
}
// DecryptByte decrypts 8 ciphertexts to a byte
func (dec *Decryptor) DecryptByte(cts [8]*Ciphertext) byte {
var b byte
for i := 0; i < 8; i++ {
if dec.Decrypt(cts[i]) {
b |= 1 << i
}
}
return b
}
// DecryptUint32 decrypts 32 ciphertexts to uint32
func (dec *Decryptor) DecryptUint32(cts [32]*Ciphertext) uint32 {
var v uint32
for i := 0; i < 32; i++ {
if dec.Decrypt(cts[i]) {
v |= 1 << i
}
}
return v
}
// DecryptUint64 decrypts 64 ciphertexts to uint64
func (dec *Decryptor) DecryptUint64(cts [64]*Ciphertext) uint64 {
var v uint64
for i := 0; i < 64; i++ {
if dec.Decrypt(cts[i]) {
v |= 1 << i
}
}
return v
}
// DecryptUint256 decrypts 256 ciphertexts to 4 uint64s
func (dec *Decryptor) DecryptUint256(cts [256]*Ciphertext) [4]uint64 {
var v [4]uint64
for w := 0; w < 4; w++ {
for i := 0; i < 64; i++ {
if dec.Decrypt(cts[w*64+i]) {
v[w] |= 1 << i
}
}
}
return v
}