bfv

package
v6.0.0-...-cdc8096 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 7, 2023 License: Apache-2.0 Imports: 11 Imported by: 0

README

BFV

The BFV package is an RNS-accelerated implementation of the Fan-Vercauteren version of Brakerski's scale-invariant homomorphic encryption scheme. It provides modular arithmetic over the integers.

Brief description

This scheme can be used to do arithmetic over   equation.

The plaintext space and the ciphertext space share the same domain

,

with a power of 2.

The batch encoding of this scheme

maps an array of integers to a polynomial with the property:

,

where represents   ![equation](https://latex.codecogs.com/gif.latex?%24%5Codot%24)   a component-wise product,and   ![equation](https://latex.codecogs.com/gif.latex?%24%5Cotimes%24)   represents a nega-cyclic convolution.

Security parameters

equation: the ring dimension, which defines the degree of the cyclotomic polynomial, and the number of coefficients of the plaintext/ciphertext polynomials; it should always be a power of two. This parameter has an impact on both security and performance (security increases with N and performance decreases with N). It should be carefully chosen to suit the intended use of the scheme.

equation: the ciphertext modulus. In Lattigo, it is chosen to be the product of small coprime moduli equation that verify equation in order to enable both the RNS and NTT representation. The used moduli equation are chosen to be of size 50 to 60 bits for the best performance. This parameter has an impact on both security and performance (for a fixed equation, a larger equation implies both lower security and lower performance). It is closely related to equation and should be chosen carefully to suit the intended use of the scheme.

equation: the variance used for the error polynomials. This parameter is closely tied to the security of the scheme (a larger equation implies higher security).

Other parameters

equation: the extended ciphertext modulus. This modulus is used during the multiplication, and it has no impact on the security. It is also defined as the product of small coprime moduli equation and should be chosen such that equation by a small margin (~20 bits). This can be done by using one more small coprime modulus than equation.

equation: the plaintext modulus. This parameter defines the maximum value that a plaintext coefficient can take. If a computation leads to a higher value, this value will be reduced modulo the plaintext modulus. It can be initialized with any value, but in order to enable batching, it must be prime and verify equation. It has no impact on the security.

Choosing security parameters

The BFV scheme supports the standard recommended parameters chosen to offer a security of 128 bits for a secret key with uniform ternary distribution equation, according to the Homomorphic Encryption Standards group (https://homomorphicencryption.org/standard/).

Each set of parameters is defined by the tuple equation:

  • {12, 109, 3.2}
  • {13, 218, 3.2}
  • {14, 438, 3.2}
  • {15, 881, 3.2}

These parameter sets are hard-coded in the file params.go. By default the variance should always be set to 3.2 unless the user is perfectly aware of the security implications of changing this parameter.

Finally, it is worth noting that these security parameters are computed for fully entropic ternary keys (with probability distribution {1/3,1/3,1/3} for values {-1,0,1}). Lattigo uses this fully-entropic key configuration by default. It is possible, though, to generate keys with lower entropy, by modifying their distribution to {(1-p)/2, p, (1-p)/2}, for any p between 0 and 1, which for p>>1/3 can result in low Hamming weight keys (sparse keys). We recall that it has been shown that the security of sparse keys can be considerably lower than that of fully entropic keys, and the BFV security parameters should be re-evaluated if sparse keys are used.

Documentation

Overview

Package bfv implements a RNS-accelerated Fan-Vercauteren version of Brakerski's scale invariant homomorphic encryption scheme. It provides modular arithmetic over the integers.

Index

Constants

View Source
const (
	DefaultNTTFlag = false
)
View Source
const GaloisGen uint64 = ring.GaloisGen

GaloisGen is an integer of order N=2^d modulo M=2N and that spans Z_M with the integer -1. The j-th ring automorphism takes the root zeta to zeta^(5j).

Variables

View Source
var (
	// PN11QP54 is a set of default parameters with logN=11 and logQP=54
	PN11QP54 = ParametersLiteral{
		LogN:     11,
		Q:        []uint64{0x3001, 0x15400000001},
		Pow2Base: 6,
		T:        0x3001,
	}

	// PN12QP109 is a set of default parameters with logN=12 and logQP=109
	PN12QP109 = ParametersLiteral{
		LogN: 12,
		Q:    []uint64{0x7ffffec001, 0x8000016001},
		P:    []uint64{0x40002001},
		T:    65537,
	}
	// PN13QP218 is a set of default parameters with logN=13 and logQP=218
	PN13QP218 = ParametersLiteral{
		LogN: 13,
		Q:    []uint64{0x3fffffffef8001, 0x4000000011c001, 0x40000000120001},
		P:    []uint64{0x7ffffffffb4001},
		T:    65537,
	}

	// PN14QP438 is a set of default parameters with logN=14 and logQP=438
	PN14QP438 = ParametersLiteral{
		LogN: 14,
		Q: []uint64{0x100000000060001, 0x80000000068001, 0x80000000080001,
			0x3fffffffef8001, 0x40000000120001, 0x3fffffffeb8001},
		P: []uint64{0x80000000130001, 0x7fffffffe90001},
		T: 65537,
	}

	// PN15QP880 is a set of default parameters with logN=15 and logQP=880
	PN15QP880 = ParametersLiteral{
		LogN: 15,
		Q: []uint64{0x7ffffffffe70001, 0x7ffffffffe10001, 0x7ffffffffcc0001,
			0x400000000270001, 0x400000000350001, 0x400000000360001,
			0x3ffffffffc10001, 0x3ffffffffbe0001, 0x3ffffffffbd0001,
			0x4000000004d0001, 0x400000000570001, 0x400000000660001},
		P: []uint64{0xffffffffffc0001, 0x10000000001d0001, 0x10000000006e0001},
		T: 65537,
	}

	// PN12QP101pq is a set of default (post quantum) parameters with logN=12 and logQP=101
	PN12QP101pq = ParametersLiteral{
		LogN: 12,
		Q:    []uint64{0x800004001, 0x800008001},
		P:    []uint64{0x80014001},
		T:    65537,
	}

	// PN13QP202pq is a set of default (post quantum) parameters with logN=13 and logQP=202
	PN13QP202pq = ParametersLiteral{
		LogN: 13,
		Q:    []uint64{0x7fffffffe0001, 0x7fffffffcc001, 0x3ffffffffc001},
		P:    []uint64{0x4000000024001},
		T:    65537,
	}

	// PN14QP411pq is a set of default (post quantum) parameters with logN=14 and logQP=411
	PN14QP411pq = ParametersLiteral{
		LogN: 14,
		Q:    []uint64{0x7fffffffff18001, 0x8000000000f8001, 0x7ffffffffeb8001, 0x800000000158001, 0x7ffffffffe70001},
		P:    []uint64{0x7ffffffffe10001, 0x400000000068001},
		T:    65537,
	}

	// PN15QP827pq is a set of default (post quantum) parameters with logN=15 and logQP=827
	PN15QP827pq = ParametersLiteral{
		LogN: 15,
		Q: []uint64{0x7ffffffffe70001, 0x7ffffffffe10001, 0x7ffffffffcc0001, 0x7ffffffffba0001, 0x8000000004a0001,
			0x7ffffffffb00001, 0x800000000890001, 0x8000000009d0001, 0x7ffffffff630001, 0x800000000a70001,
			0x7ffffffff510001},
		P: []uint64{0x800000000b80001, 0x800000000bb0001, 0xffffffffffc0001},
		T: 65537,
	}
)

DefaultParams is a set of default BFV parameters ensuring 128 bit security in the classic setting.

DefaultPostQuantumParams is a set of default BFV parameters ensuring 128 bit security in the post-quantum setting.

Functions

func NewCiphertext

func NewCiphertext(params Parameters, degree, level int) (ct *rlwe.Ciphertext)

func NewDecryptor

func NewDecryptor(params Parameters, key *rlwe.SecretKey) rlwe.Decryptor

func NewEncryptor

func NewEncryptor(params Parameters, key interface{}) rlwe.Encryptor

func NewKeyGenerator

func NewKeyGenerator(params Parameters) rlwe.KeyGenerator

func NewPRNGEncryptor

func NewPRNGEncryptor(params Parameters, key *rlwe.SecretKey) rlwe.PRNGEncryptor

func NewPlaintext

func NewPlaintext(params Parameters, level int) (pt *rlwe.Plaintext)

NewPlaintext creates and allocates a new plaintext in RingQ (multiple moduli of Q). The plaintext will be in RingQ and scaled by Q/t. Slower encoding and larger plaintext size

func Noise

func Noise(params Parameters, ct *rlwe.Ciphertext, dec rlwe.Decryptor) (std, min, max float64)

Noise decrypts a ciphertext and returns the log2 of the standard deviation, minimum and maximum norm of the noise assuming the decryption is correct. This function is used for testing/profiling/evaluation purposes

func ScaleUpTCoprimeWithQVecLvl

func ScaleUpTCoprimeWithQVecLvl(level int, ringQ, ringT *ring.Ring, tInvModQi, buffN []uint64, pIn, pOut *ring.Poly)

ScaleUpTCoprimeWithQVecLvl takes a Poly pIn in ringT, scales its coefficients up by (Q/T) mod Q, and writes the result in a Poly pOut in ringQ.

func ScaleUpTIsQ0VecLvl

func ScaleUpTIsQ0VecLvl(level int, ringQ *ring.Ring, pIn, pOut *ring.Poly)

ScaleUpTIsQ0VecLvl takes a Poly pIn in ringT, scales its coefficients up by (Q/T) mod Q, and writes the result on a Poly pOut in ringQ. T is in this case assumed to be the first prime in the moduli chain.

Types

type Encoder

type Encoder interface {
	Encode(coeffs interface{}, pt *rlwe.Plaintext)
	EncodeNew(coeffs interface{}, level int) (pt *rlwe.Plaintext)
	EncodeRingT(coeffs interface{}, pt *PlaintextRingT)
	EncodeRingTNew(coeffs interface{}) (pt *PlaintextRingT)
	EncodeMul(coeffs interface{}, pt *PlaintextMul)
	EncodeMulNew(coeffs interface{}, level int) (pt *PlaintextMul)

	SwitchToRingT(pt interface{}, ptRt *PlaintextRingT)
	ScaleUp(ptRt *PlaintextRingT, pt *rlwe.Plaintext)
	ScaleDown(pt *rlwe.Plaintext, ptRt *PlaintextRingT)
	RingTToMul(ptRt *PlaintextRingT, ptmul *PlaintextMul)
	MulToRingT(pt *PlaintextMul, ptRt *PlaintextRingT)

	Decode(pt interface{}, coeffs interface{})
	DecodeUintNew(pt interface{}) (coeffs []uint64)
	DecodeIntNew(pt interface{}) (coeffs []int64)

	ShallowCopy() Encoder
}

Encoder is an interface for plaintext encoding and decoding operations. It provides methods to embed []uint64 and []int64 types into the various plaintext types and the inverse operations. It also provides methods to convert between the different plaintext types. The different plaintext types represent different embeddings of the message in the polynomial space. This relation is illustrated in the figure below:

                  ┌-> Encoder.Encode(.) -----------------------------------------------------┐
[]uint64/[]int64 -┼-> Encoder.EncodeRingT(.) ---> PlaintextRingT -┬-> Encoder.ScaleUp(.) ----┴-> rlwe.Plaintext
                  |                                               └-> Encoder.RingTToMul(.) -┬-> PlaintextMul
                  └-> Encoder.EncodeMul(.) --------------------------------------------------┘

The different plaintext types have different efficiency-related characteristics that we summarize in the Table below. For more information about the different plaintext types, see plaintext.go.

Relative efficiency of operations

 -------------------------------------------------------------------------
|                      |  PlaintextRingT  |  Plaintext  | PlaintextMul    |
 -------------------------------------------------------------------------
| Encoding/Decoding    |    Faster        |    Slower   |    Slower       |
| Memory size          |    Smaller       |    Larger   |    Larger       |
| Ct-Pt Add / Sub      |    Slower        |    Faster   |    N/A          |
| Ct-Pt Mul            |    Faster        |    Slower   |    Much Faster  |
 -------------------------------------------------------------------------

func NewEncoder

func NewEncoder(params Parameters) Encoder

NewEncoder creates a new encoder from the provided parameters.

type Evaluator

type Evaluator interface {
	Add(ctIn *rlwe.Ciphertext, op1 rlwe.Operand, ctOut *rlwe.Ciphertext)
	AddNew(ctIn *rlwe.Ciphertext, op1 rlwe.Operand) (ctOut *rlwe.Ciphertext)
	Sub(ctIn *rlwe.Ciphertext, op1 rlwe.Operand, ctOut *rlwe.Ciphertext)
	SubNew(ctIn *rlwe.Ciphertext, op1 rlwe.Operand) (ctOut *rlwe.Ciphertext)
	Neg(ctIn *rlwe.Ciphertext, ctOut *rlwe.Ciphertext)
	NegNew(ctIn *rlwe.Ciphertext) (ctOut *rlwe.Ciphertext)
	AddScalar(ctIn *rlwe.Ciphertext, scalar uint64, ctOut *rlwe.Ciphertext)
	MulScalar(ctIn *rlwe.Ciphertext, scalar uint64, ctOut *rlwe.Ciphertext)
	MulScalarThenAdd(ctIn *rlwe.Ciphertext, scalar uint64, ctOut *rlwe.Ciphertext)
	MulScalarNew(ctIn *rlwe.Ciphertext, scalar uint64) (ctOut *rlwe.Ciphertext)
	Rescale(ctIn, ctOut *rlwe.Ciphertext)
	RescaleTo(level int, ctIn, ctOut *rlwe.Ciphertext)
	Mul(ctIn *rlwe.Ciphertext, op1 rlwe.Operand, ctOut *rlwe.Ciphertext)
	MulNew(ctIn *rlwe.Ciphertext, op1 rlwe.Operand) (ctOut *rlwe.Ciphertext)
	MulThenAdd(ctIn *rlwe.Ciphertext, op1 rlwe.Operand, ctOut *rlwe.Ciphertext)
	Relinearize(ctIn *rlwe.Ciphertext, ctOut *rlwe.Ciphertext)
	RelinearizeNew(ctIn *rlwe.Ciphertext) (ctOut *rlwe.Ciphertext)
	SwitchKeys(ctIn *rlwe.Ciphertext, switchKey *rlwe.SwitchingKey, ctOut *rlwe.Ciphertext)
	EvaluatePoly(input interface{}, pol *Polynomial) (opOut *rlwe.Ciphertext, err error)
	EvaluatePolyVector(input interface{}, pols []*Polynomial, encoder Encoder, slotsIndex map[int][]int) (opOut *rlwe.Ciphertext, err error)
	EvalUnary(ctIn, ctOut *rlwe.Ciphertext, ev func(enc *ring.Poly, dec *ring.Poly))
	SwitchKeysNew(ctIn *rlwe.Ciphertext, switchkey *rlwe.SwitchingKey) (ctOut *rlwe.Ciphertext)
	RotateColumnsNew(ctIn *rlwe.Ciphertext, k int) (ctOut *rlwe.Ciphertext)
	RotateColumns(ctIn *rlwe.Ciphertext, k int, ctOut *rlwe.Ciphertext)
	RotateRows(ctIn *rlwe.Ciphertext, ctOut *rlwe.Ciphertext)
	RotateRowsNew(ctIn *rlwe.Ciphertext) (ctOut *rlwe.Ciphertext)
	InnerSum(op0 *rlwe.Ciphertext, batch, n int, ctOut *rlwe.Ciphertext)
	ShallowCopy() Evaluator
	WithKey(rlwe.EvaluationKey) Evaluator

	CheckBinary(op0, op1, opOut rlwe.Operand, opOutMinDegree int) (degree, level int)
	CheckUnary(op0, opOut rlwe.Operand) (degree, level int)
	BuffQ() [][]*ring.Poly
	BuffQMul() [][]*ring.Poly
	BuffPt() *rlwe.Plaintext
}

Evaluator is an interface implementing the public methods of the eval.

func NewEvaluator

func NewEvaluator(params Parameters, evaluationKey rlwe.EvaluationKey) Evaluator

NewEvaluator creates a new Evaluator, that can be used to do homomorphic operations on ciphertexts and/or plaintexts. It stores a memory buffer and ciphertexts that will be used for intermediate values.

func NewEvaluators

func NewEvaluators(params Parameters, evaluationKey rlwe.EvaluationKey, n int) []Evaluator

NewEvaluators creates n evaluators sharing the same read-only data-structures.

type Parameters

type Parameters struct {
	rlwe.Parameters
	// contains filtered or unexported fields
}

Parameters represents a parameter set for the BFV cryptosystem. Its fields are private and immutable. See ParametersLiteral for user-specified parameters.

func NewParameters

func NewParameters(rlweParams rlwe.Parameters, t uint64) (p Parameters, err error)

NewParameters instantiate a set of BFV parameters from the generic RLWE parameters and the BFV-specific ones. It returns the empty parameters Parameters{} and a non-nil error if the specified parameters are invalid.

func NewParametersFromLiteral

func NewParametersFromLiteral(pl ParametersLiteral) (Parameters, error)

NewParametersFromLiteral instantiate a set of BFV parameters from a ParametersLiteral specification. It returns the empty parameters Parameters{} and a non-nil error if the specified parameters are invalid.

See `rlwe.NewParametersFromLiteral` for default values of the optional fields.

func (Parameters) CopyNew deprecated

func (p Parameters) CopyNew() Parameters

CopyNew makes a deep copy of the receiver and returns it.

Deprecated: Parameter is now a read-only struct, except for the UnmarshalBinary method: deep copying should only be required to save a Parameter struct before calling its UnmarshalBinary method and it will be deprecated when transitioning to a immutable serialization interface.

func (Parameters) Equals

func (p Parameters) Equals(other Parameters) bool

Equals compares two sets of parameters for equality.

func (Parameters) LogT

func (p Parameters) LogT() int

LogT returns log2(plaintext coefficient modulus).

func (Parameters) MarshalBinary

func (p Parameters) MarshalBinary() ([]byte, error)

MarshalBinary returns a []byte representation of the parameter set.

func (Parameters) MarshalBinarySize

func (p Parameters) MarshalBinarySize() int

MarshalBinarySize returns the length of the []byte encoding of the receiver.

func (Parameters) MarshalJSON

func (p Parameters) MarshalJSON() ([]byte, error)

MarshalJSON returns a JSON representation of this parameter set. See `Marshal` from the `encoding/json` package.

func (Parameters) ParametersLiteral

func (p Parameters) ParametersLiteral() ParametersLiteral

func (Parameters) RingQMul

func (p Parameters) RingQMul() *ring.Ring

RingQMul returns a pointer to the ring of the extended basis for multiplication.

func (Parameters) RingT

func (p Parameters) RingT() *ring.Ring

RingT returns a pointer to the plaintext ring.

func (Parameters) T

func (p Parameters) T() uint64

T returns the plaintext coefficient modulus t.

func (*Parameters) UnmarshalBinary

func (p *Parameters) UnmarshalBinary(data []byte) (err error)

UnmarshalBinary decodes a []byte into a parameter set struct.

func (*Parameters) UnmarshalJSON

func (p *Parameters) UnmarshalJSON(data []byte) (err error)

UnmarshalJSON reads a JSON representation of a parameter set into the receiver Parameter. See `Unmarshal` from the `encoding/json` package.

type ParametersLiteral

type ParametersLiteral struct {
	LogN     int
	Q        []uint64
	P        []uint64
	LogQ     []int `json:",omitempty"`
	LogP     []int `json:",omitempty"`
	Pow2Base int
	Sigma    float64
	H        int
	T        uint64 // Plaintext modulus
}

ParametersLiteral is a literal representation of BFV parameters. It has public fields and is used to express unchecked user-defined parameters literally into Go programs. The NewParametersFromLiteral function is used to generate the actual checked parameters from the literal representation.

Users must set the polynomial degree (LogN) and the coefficient modulus, by either setting the Q and P fields to the desired moduli chain, or by setting the LogQ and LogP fields to the desired moduli sizes. Users must also specify the coefficient modulus in plaintext-space (T).

Optionally, users may specify the error variance (Sigma) and secrets' density (H). If left unset, standard default values for these field are substituted at parameter creation (see NewParametersFromLiteral).

func (ParametersLiteral) RLWEParameters

func (p ParametersLiteral) RLWEParameters() rlwe.ParametersLiteral

RLWEParameters returns the rlwe.ParametersLiteral from the target bfv.ParametersLiteral.

type PlaintextMul

type PlaintextMul struct {
	*rlwe.Plaintext
}

PlaintextMul represents a plaintext element in R_q, in NTT and Montgomery form, but without scale up by Q/t. A PlaintextMul is a special-purpose plaintext for efficient Ciphertext x Plaintext multiplication. However, other operations on plaintexts are not supported. See bfv/encoder.go for more information on plaintext types.

func NewPlaintextMul

func NewPlaintextMul(params Parameters, level int) *PlaintextMul

NewPlaintextMul creates and allocates a new plaintext optimized for Ciphertext x Plaintext multiplication. The Plaintext is allocated with level+1 moduli. The Plaintext will be in the NTT and Montgomery domain of RingQ and not scaled by Q/t.

type PlaintextRingT

type PlaintextRingT struct {
	*rlwe.Plaintext
}

PlaintextRingT represents a plaintext element in R_t. This is the most compact representation of a plaintext, but performing operations have the extra-cost of performing the scaling up by Q/t. See bfv/encoder.go for more information on plaintext types.

func NewPlaintextRingT

func NewPlaintextRingT(params Parameters) *PlaintextRingT

NewPlaintextRingT creates and allocates a new plaintext in RingT (single modulus T). The plaintext will be in RingT.

type Polynomial

type Polynomial struct {
	MaxDeg int
	Coeffs []uint64
	Lead   bool
}

Polynomial is a struct storing the coefficients of a plaintext polynomial that then can be evaluated on the ciphertext.

func NewPoly

func NewPoly(coeffs []uint64) (p *Polynomial)

NewPoly creates a new Poly from the input coefficients.

func (*Polynomial) Degree

func (p *Polynomial) Degree() int

Degree returns the degree of the polynomial.

func (*Polynomial) Depth

func (p *Polynomial) Depth() int

Depth returns the depth needed to evaluate the polynomial.

type PowerBasis

type PowerBasis struct {
	Value map[int]*rlwe.Ciphertext
}

PowerBasis is a struct storing powers of a ciphertext.

func NewPowerBasis

func NewPowerBasis(ct *rlwe.Ciphertext) (p *PowerBasis)

NewPowerBasis creates a new PowerBasis.

func (*PowerBasis) GenPower

func (p *PowerBasis) GenPower(n int, eval Evaluator)

GenPower generates the n-th power of the power basis, as well as all the necessary intermediate powers if they are not yet present.

func (*PowerBasis) MarshalBinary

func (p *PowerBasis) MarshalBinary() (data []byte, err error)

MarshalBinary encodes the target on a slice of bytes.

func (*PowerBasis) UnmarshalBinary

func (p *PowerBasis) UnmarshalBinary(data []byte) (err error)

UnmarshalBinary decodes a slice of bytes on the target.

type RNSScaler

type RNSScaler struct {
	// contains filtered or unexported fields
}

RNSScaler implements the Scaler interface by performing a scaling by t/Q in the RNS domain.

func NewRNSScaler

func NewRNSScaler(ringQ *ring.Ring, T uint64) (rnss *RNSScaler)

NewRNSScaler creates a new RNSScaler from t, the modulus under which the reconstruction is returned, the Ring in which the polynomial to reconstruct is represented.

func (*RNSScaler) DivByQOverTRoundedLvl

func (rnss *RNSScaler) DivByQOverTRoundedLvl(level int, p1Q, p2T *ring.Poly)

DivByQOverTRoundedLvl returns p1 scaled by a factor t/Q and mod t on the receiver p2.

func (*RNSScaler) ScaleUpByQOverTLvl

func (rnss *RNSScaler) ScaleUpByQOverTLvl(level int, pIn, pOut *ring.Poly)

ScaleUpByQOverTLvl takes a Poly pIn in ringT, scales its coefficients up by (Q/T) mod Q, and writes the result on pOut.

type Scaler

type Scaler interface {
	// DivByQOverTRoundedLvl returns p1 scaled by a factor t/Q and mod t on the receiver p2.
	DivByQOverTRoundedLvl(level int, p1, p2 *ring.Poly)
	ScaleUpByQOverTLvl(level int, p1, p2 *ring.Poly)
}

Scaler is an interface that rescales polynomial coefficients by a fraction t/Q.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL