he

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2024 License: Apache-2.0, BSD-3-Clause, ISC, + 1 more Imports: 13 Imported by: 0

Documentation

Overview

Package he implements scheme agnostic functionalities for RLWE-based Homomorphic Encryption schemes implemented in lattigo.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BSGSIndex

func BSGSIndex(nonZeroDiags []int, slots, N1 int) (index map[int][]int, rotN1, rotN2 []int)

BSGSIndex returns the index map and needed rotation for the BSGS matrix-vector multiplication algorithm.

func EncodeLinearTransformation

func EncodeLinearTransformation[T any](encoder Encoder, diagonals Diagonals[T], allocated *LinearTransformation) (err error)

EncodeLinearTransformation encodes on a pre-allocated LinearTransformation a set of non-zero diagonaes of a matrix representing a linear transformation.

func EvaluateGianStep

func EvaluateGianStep(i int, giantSteps []int, babySteps []*BabyStep, eval Evaluator, pb *PowerBasis) (err error)

EvaluateGianStep evaluates a giant-step of the PatersonStockmeyer polynomial evaluation algorithm, which consists in combining the baby-steps <[1, T, T^2, ..., T^{n-1}], [ci0, ci1, ci2, ..., ci{n-1}]> together with powers T^{2^k}.

func EvaluateLinearTranformationSequential

func EvaluateLinearTranformationSequential(evalLT EvaluatorForLinearTransformation, evalDiag EvaluatorForDiagonalMatrix, ctIn *rlwe.Ciphertext, linearTransformations []*LinearTransformation, buf rlwe.HoistingBuffer, opOut *rlwe.Ciphertext) (err error)

EvaluateLinearTranformationSequential takes as input a ciphertext ctIn and a list of linear transformations [M0, M1, M2, ...] and evaluates opOut:...M2(M1(M0(ctIn))

func EvaluateLinearTransformationsMany

func EvaluateLinearTransformationsMany(evalLT EvaluatorForLinearTransformation, evalDiag EvaluatorForDiagonalMatrix, ctIn *rlwe.Ciphertext, linearTransformations []*LinearTransformation, buf rlwe.HoistingBuffer, opOut []*rlwe.Ciphertext) (err error)

EvaluateLinearTransformationsMany takes as input a ciphertext ctIn, a list of linear transformations [M0, M1, M2, ...] and a list of pre-allocated receiver opOut and evaluates opOut: [M0(ctIn), M1(ctIn), M2(ctIn), ...]

func EvaluateMonomial

func EvaluateMonomial(a, b, xpow *rlwe.Ciphertext, eval Evaluator) (err error)

EvaluateMonomial evaluates a monomial of the form a + b * X^{pow} and writes the results in b.

func EvaluatePatersonStockmeyerPolynomialVector

func EvaluatePatersonStockmeyerPolynomialVector[T any](eval Evaluator, poly *PatersonStockmeyerPolynomialVector, cg CoefficientGetter[T], pb *PowerBasis) (res *rlwe.Ciphertext, err error)

EvaluatePatersonStockmeyerPolynomialVector evaluates a pre-decomposed PatersonStockmeyerPolynomialVector on a pre-computed power basis [1, X^{1}, X^{2}, ..., X^{2^{n}}, X^{2^{n+1}}, ..., X^{2^{m}}]

func EvaluatePolynomial

func EvaluatePolynomial(eval EvaluatorForPolynomial, input interface{}, p interface{}, targetScale rlwe.Scale, SimEval SimEvaluator) (opOut *rlwe.Ciphertext, err error)

EvaluatePolynomial is a generic and scheme agnostic method to evaluate polynomials on rlwe.Ciphertexts.

func EvaluatePolynomialVectorFromPowerBasis

func EvaluatePolynomialVectorFromPowerBasis[T any](eval Evaluator, targetLevel int, pol *PolynomialVector, cg CoefficientGetter[T], pb *PowerBasis, targetScale rlwe.Scale) (res *rlwe.Ciphertext, err error)

EvaluatePolynomialVectorFromPowerBasis a method that complies to the interface he.PolynomialVectorEvaluator. This method evaluates P(ct) = sum c_i * ct^{i}.

func GaloisElementsForExpand

func GaloisElementsForExpand(params rlwe.ParameterProvider, logN int) (galEls []uint64)

GaloisElementsForExpand returns the list of Galois elements required to perform the `Expand` operation with parameter `logN`.

func GaloisElementsForPack

func GaloisElementsForPack(params rlwe.ParameterProvider, logGap int) (galEls []uint64)

GaloisElementsForPack returns the list of Galois elements required to perform the `Pack` operation.

func GenXPow2NTT

func GenXPow2NTT(r ring.RNSRing, logN int, div bool) (xPow []ring.RNSPoly)

GenXPow2NTT generates X^({-1 if div else 1} * {2^{0 <= i < LogN}}) in NTT.

func GetBabyStepPlaintextVector

func GetBabyStepPlaintextVector[T any](p rlwe.ParameterProvider, encoder Encoder, targetLevel int, pol *PolynomialVector, cg CoefficientGetter[T], pb SimPowerBasis, logDimensions ring.Dimensions, targetScale rlwe.Scale) (pts []*rlwe.Plaintext, err error)

GetBabyStepPlaintextVector a method that complies to the interface he.PolynomialVectorEvaluator. This method evaluates P(ct) = sum pt_i * ct^{i}.

func GetPreRotatedCiphertextForDiagonalMatrixMultiplication

func GetPreRotatedCiphertextForDiagonalMatrixMultiplication(LevelQ, LevelP int, eval EvaluatorForLinearTransformation, ctIn *rlwe.Ciphertext, buf rlwe.HoistingBuffer, rots []int, ctPreRot map[int]*rlwe.Ciphertext) (err error)

GetPreRotatedCiphertextForDiagonalMatrixMultiplication populates ctPreRot with the pre-rotated ciphertext for the rotations rots.

func MultiplyByDiagMatrix

func MultiplyByDiagMatrix(eval EvaluatorForLinearTransformation, ctIn *rlwe.Ciphertext, matrix *LinearTransformation, buf rlwe.HoistingBuffer, opOut *rlwe.Ciphertext) (err error)

MultiplyByDiagMatrix multiplies the Ciphertext "ctIn" by the plaintext matrix "matrix" and returns the result on the Ciphertext "opOut". Memory buffers for the decomposed ciphertext BuffDecompQP, BuffDecompQP must be provided, those are list of poly of ringQ and ringP respectively, each of size params.Beta(). The naive approach is used (single hoisting and no baby-step giant-step), which is faster than MultiplyByDiagMatrixBSGS for matrix of only a few non-zero diagonals but uses more keys.

func MultiplyByDiagMatrixBSGS

func MultiplyByDiagMatrixBSGS(eval EvaluatorForLinearTransformation, ctIn *rlwe.Ciphertext, matrix *LinearTransformation, ctInPreRot map[int]*rlwe.Ciphertext, opOut *rlwe.Ciphertext) (err error)

MultiplyByDiagMatrixBSGS multiplies the Ciphertext "ctIn" by the plaintext matrix "matrix" and returns the result on the Ciphertext "opOut". ctInPreRotated can be obtained with GetPreRotatedCiphertextForDiagonalMatrixMultiplication. The BSGS approach is used (double hoisting with baby-step giant-step), which is faster than MultiplyByDiagMatrix for matrix with more than a few non-zero diagonals and uses significantly less keys.

func NumBSGSGalEls

func NumBSGSGalEls(nonZeroDiags []int, slots, N1 int) (rotN1, rotN2 int)

func OptimalLinearTransformationGiantStep

func OptimalLinearTransformationGiantStep(nonZeroDiags []int, slots int) (opt int)

OptimalLinearTransformationGiantStep returns the giant step that minimize N1 + N2 + |N1 - N2| where: - N1 is the number of giant steps (one rotation per giant step) - N2 is the maximum number of baby steps per giant step (one rotation per baby step)

func ProcessBabySteps

func ProcessBabySteps(eval Evaluator, babySteps []*BabyStep, pb *PowerBasis) (res *rlwe.Ciphertext, err error)

func SplitDegree

func SplitDegree(n int) (a, b int)

SplitDegree returns a * b = n such that |a-b| is minimized with a and/or b odd if possible.

Types

type BabyStep

type BabyStep struct {
	Degree int
	Value  *rlwe.Ciphertext
}

BabyStep is a struct storing the result of a baby-step of the Paterson-Stockmeyer polynomial evaluation algorithm.

func EvaluateBabyStep

func EvaluateBabyStep[T any](i int, eval Evaluator, poly *PatersonStockmeyerPolynomialVector, cg CoefficientGetter[T], pb *PowerBasis) (ct *BabyStep, err error)

EvaluateBabyStep evaluates a baby-step of the PatersonStockmeyer polynomial evaluation algorithm, i.e. the inner-product between the precomputed powers [1, T, T^2, ..., T^{n-1}] and the coefficients [ci0, ci1, ci2, ..., ci{n-1}].

type Bootstrapper

type Bootstrapper[CiphertextType any] interface {

	// Bootstrap defines a method that takes a single Ciphertext as input and applies
	// an in place scheme-specific bootstrapping. The result is also returned.
	// An error should notably be returned if ct.Level() < Bootstrapper.MinimumInputLevel().
	Bootstrap(ct *CiphertextType) (*CiphertextType, error)

	// BootstrapMany defines a method that takes a slice of Ciphertexts as input and applies an
	// in place scheme-specific bootstrapping to each Ciphertext. The result is also returned.
	// An error should notably be returned if cts[i].Level() < Bootstrapper.MinimumInputLevel().
	BootstrapMany(cts []CiphertextType) ([]CiphertextType, error)

	// Depth is the number of levels consumed by the bootstrapping circuit.
	// This value is equivalent to params.MaxLevel() - OutputLevel().
	Depth() int

	// MinimumInputLevel defines the minimum level that the ciphertext
	// must be at when given to the bootstrapper.
	// For the centralized bootstrapping this value is usually zero.
	// For the collective bootstrapping it is given by the user-defined
	// security parameters
	MinimumInputLevel() int

	// OutputLevel defines the level that the ciphertext will be at
	// after the bootstrapping.
	// For the centralized bootstrapping this value is the maximum
	// level minus the depth of the bootstrapping circuit.
	// For the collective bootstrapping this value is usually the
	// maximum level.
	OutputLevel() int
}

Bootstrapper is a scheme-independent generic interface to handle bootstrapping.

type CoefficientGetter

type CoefficientGetter[T any] interface {

	// GetVectorCoefficient should return a slice []T containing the k-th coefficient
	// of each polynomial of PolynomialVector indexed by its Mapping.
	// See PolynomialVector for additional information about the Mapping.
	GetVectorCoefficient(pol *PolynomialVector, k int) (values []T)

	// GetSingleCoefficient should return the k-th coefficient of Polynomial as the type T.
	GetSingleCoefficient(pol *Polynomial, k int) (value T)

	// ShallowCopy should return a thread-safe copy of the original CoefficientGetter.
	ShallowCopy() CoefficientGetter[T]
}

CoefficientGetter defines an interface to get the coefficients of a Polynomial.

type Complex

type Complex interface {
	~complex64 | ~complex128 | bignum.Complex
}

type Diagonals

type Diagonals[T any] map[int][]T

func (Diagonals[T]) Add

func (m Diagonals[T]) Add(d Diagonals[T], add func(a, b, c []T), clone func(a []T) (b []T))

func (Diagonals[T]) At

func (m Diagonals[T]) At(i, slots int) ([]T, error)

At returns the i-th non-zero diagonal. Method accepts negative values with the equivalency -i = n - i.

func (Diagonals[T]) Evaluate

func (m Diagonals[T]) Evaluate(in, buff, out []T, LTParams LinearTransformationParameters, zero func(a []T), add func(a, b, c []T), muladd func(a, b, c []T))

Evaluate evaluates the [hefloat.Diagonals] on the input vector. - zero: evaluates c[i] = 0 - add: evaluates c[i] = a[i] + b[i] - muladd: evaluates c[i] = a[i] * b[i]

func (Diagonals[T]) GaloisElements

func (m Diagonals[T]) GaloisElements(params rlwe.ParameterProvider, LogDimensions ring.Dimensions, GiantStep int) (galEls []uint64)

func (Diagonals[T]) Indexes

func (m Diagonals[T]) Indexes() (indexes []int)

Indexes returns the list of the non-zero diagonals of the square matrix. A non zero diagonals is a diagonal with a least one non-zero element.

func (Diagonals[T]) Mul

func (m Diagonals[T]) Mul(d Diagonals[T], buff []T, add func(a, b, c []T), rot func(a []T, k int, b []T), mul func(a, b []T, c []T), clone func(a []T) (b []T))

type EncodedPolynomialVector

type EncodedPolynomialVector struct {
	Value     [][]*rlwe.Plaintext
	Basis     bignum.Basis
	Depth     int
	LogDegree int
	LogSplit  int
	IsOdd     bool
	IsEven    bool
	Lazy      bool
}

EncodedPolynomialVector is a struct storing an encoded PolynomialVector. Using an EncodedPolynomialVector provides significantly faster polynomial evaluation as the plaintext vectors are pre-encoded, the tradeoff being a loss in flexibility as an EncodedPolynomialVector must be evaluated on a ciphertext at a specific level and scale.

func GetEncodedPolynomialVector

func GetEncodedPolynomialVector[T any](params rlwe.ParameterProvider, ecd Encoder, polys *PolynomialVector, cg CoefficientGetter[T], inputLevel int, inputScale, targetScale rlwe.Scale, eval SimEvaluator) (pspe *EncodedPolynomialVector, err error)

GetEncodedPolynomialVector generates an EncodedPolynomialVector from a PolynomialVector.

func (*EncodedPolynomialVector) Evaluate

func (p *EncodedPolynomialVector) Evaluate(eval EvaluatorForPolynomial, input interface{}) (opOut *rlwe.Ciphertext, err error)

Evaluate evlauates an EncodedPolynomialVector on an rlwe.Ciphertext or using a pre-computed PowerBasis.

func (*EncodedPolynomialVector) PopulatePowerBasis

func (p *EncodedPolynomialVector) PopulatePowerBasis(eval EvaluatorForPolynomial, pb *PowerBasis) (err error)

PopulatePowerBasis populates a PowerBasis with the missing ciphertext powers to evaluate the EncodedPolynomialVector.

type Encoder

type Encoder interface {
	Embed(values interface{}, metaData *rlwe.MetaData, output interface{}) (err error)
}

Encoder defines a set of common and scheme agnostic method provided by an Encoder struct.

type Evaluator

type Evaluator interface {
	rlwe.ParameterProvider
	Add(op0 *rlwe.Ciphertext, op1 rlwe.Operand, opOut *rlwe.Ciphertext) (err error)
	AddNew(op0 *rlwe.Ciphertext, op1 rlwe.Operand) (opOut *rlwe.Ciphertext, err error)
	Sub(op0 *rlwe.Ciphertext, op1 rlwe.Operand, opOut *rlwe.Ciphertext) (err error)
	SubNew(op0 *rlwe.Ciphertext, op1 rlwe.Operand) (opOut *rlwe.Ciphertext, err error)
	Mul(op0 *rlwe.Ciphertext, op1 rlwe.Operand, opOut *rlwe.Ciphertext) (err error)
	MulNew(op0 *rlwe.Ciphertext, op1 rlwe.Operand) (opOut *rlwe.Ciphertext, err error)
	MulRelin(op0 *rlwe.Ciphertext, op1 rlwe.Operand, opOut *rlwe.Ciphertext) (err error)
	MulRelinNew(op0 *rlwe.Ciphertext, op1 rlwe.Operand) (opOut *rlwe.Ciphertext, err error)
	MulThenAdd(op0 *rlwe.Ciphertext, op1 rlwe.Operand, opOut *rlwe.Ciphertext) (err error)
	Relinearize(op0, op1 *rlwe.Ciphertext) (err error)
	Rescale(op0, op1 *rlwe.Ciphertext) (err error)
	GetEvaluatorBuffer() *rlwe.EvaluatorBuffers // TODO extract
	DropLevel(op0 *rlwe.Ciphertext, Level int)
	LevelsConsumedPerRescaling() int
}

Evaluator defines a set of common and scheme agnostic method provided by an Evaluator struct.

type EvaluatorForDiagonalMatrix

type EvaluatorForDiagonalMatrix interface {
	FillHoistingBuffer(LevelQ, LevelP int, c1 ring.RNSPoly, isNTT bool, buf rlwe.HoistingBuffer)
	GetPreRotatedCiphertextForDiagonalMatrixMultiplication(LevelQ, LevelP int, ctIn *rlwe.Ciphertext, buf rlwe.HoistingBuffer, rots []int, ctPreRot map[int]*rlwe.Ciphertext) (err error)
	MultiplyByDiagMatrix(ctIn *rlwe.Ciphertext, matrix *LinearTransformation, buf rlwe.HoistingBuffer, opOut *rlwe.Ciphertext) (err error)
	MultiplyByDiagMatrixBSGS(ctIn *rlwe.Ciphertext, matrix *LinearTransformation, ctInPreRot map[int]*rlwe.Ciphertext, opOut *rlwe.Ciphertext) (err error)
}

type EvaluatorForLinearTransformation

type EvaluatorForLinearTransformation interface {
	rlwe.ParameterProvider
	Rescale(op1, op2 *rlwe.Ciphertext) (err error)
	GetBuffQ() [6]ring.RNSPoly
	GetBuffP() [6]ring.RNSPoly
	GetBuffCt() *rlwe.Ciphertext
	NewHoistingBuffer(LevelQ, LevelP int) rlwe.HoistingBuffer
	FillHoistingBuffer(LevelQ, LevelP int, c1 ring.RNSPoly, isNTT bool, buf rlwe.HoistingBuffer)
	CheckAndGetGaloisKey(galEl uint64) (evk *rlwe.GaloisKey, err error)
	GadgetProductLazy(LevelQ int, overwrite bool, cx ring.RNSPoly, cxIsNTT bool, gadgetCt *rlwe.GadgetCiphertext, ct *rlwe.Ciphertext) (err error)
	GadgetProductHoistedLazy(LevelQ int, overwrite bool, buf rlwe.HoistingBuffer, gadgetCt *rlwe.GadgetCiphertext, ct *rlwe.Ciphertext) (err error)
	AutomorphismHoistedLazy(LevelQ int, ctIn *rlwe.Ciphertext, buf rlwe.HoistingBuffer, galEl uint64, ctQP *rlwe.Ciphertext) (err error)
	ModDownNTT(LevelQ, LevelP int, p1Q, p1P, p2Q ring.RNSPoly)
	AutomorphismIndex(uint64) []uint64
}

EvaluatorForLinearTransformation defines a set of common and scheme agnostic method necessary to instantiate an LinearTransformationEvaluator.

type EvaluatorForPolynomial

type EvaluatorForPolynomial interface {
	Evaluator
	LevelsConsumedPerRescaling() int
	EvaluatePatersonStockmeyerPolynomialVector(poly *PatersonStockmeyerPolynomialVector, pb *PowerBasis) (res *rlwe.Ciphertext, err error)
}

EvaluatorForPolynomial defines a set of common and scheme agnostic method that are necessary to instantiate a PolynomialVectorEvaluator.

type Float

type Float interface {
	~float32 | ~float64 | big.Float
}

type Integer

type Integer interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | big.Int
}

type LinearTransformation

type LinearTransformation struct {
	*rlwe.MetaData
	GiantStep int // If left to zero, indicates naive evaluation.
	LevelQ    int
	LevelP    int
	Vec       map[int]ring.Point
}

LinearTransformation is a type for linear transformations on ciphertexts. It stores a plaintext matrix in diagonal form and can be evaluated on a ciphertext using a LinearTransformationEvaluator.

func NewLinearTransformation

func NewLinearTransformation(params rlwe.ParameterProvider, ltparams LinearTransformationParameters) *LinearTransformation

NewLinearTransformation allocates a new LinearTransformation with zero values according to the parameters specified by the LinearTransformationParameters.

func (LinearTransformation) BSGSIndex

func (lt LinearTransformation) BSGSIndex() (index map[int][]int, n1, n2 []int)

BSGSIndex returns the BSGSIndex of the target linear transformation.

func (LinearTransformation) GaloisElements

func (lt LinearTransformation) GaloisElements(params rlwe.ParameterProvider) (galEls []uint64)

GaloisElements returns the list of Galois elements needed for the evaluation of the linear transformation.

func (LinearTransformation) GetParameters

GetParameters returns the he.LinearTransformationParameters of the receiver.

type LinearTransformationEvaluator

type LinearTransformationEvaluator struct {
	EvaluatorForLinearTransformation
	EvaluatorForDiagonalMatrix
}

func NewLinearTransformationEvaluator

func NewLinearTransformationEvaluator(eval EvaluatorForLinearTransformation) (linTransEval *LinearTransformationEvaluator)

NewLinearTransformationEvaluator instantiates a new LinearTransformationEvaluator from a circuit.EvaluatorForLinearTransformation. The default hefloat.Evaluator is compliant to the EvaluatorForLinearTransformation interface. This method is allocation free.

func (LinearTransformationEvaluator) Evaluate

func (eval LinearTransformationEvaluator) Evaluate(ctIn *rlwe.Ciphertext, linearTransformation *LinearTransformation, buf rlwe.HoistingBuffer, opOut *rlwe.Ciphertext) (err error)

Evaluate takes as input a ciphertext ctIn, a linear transformation M and evaluates opOut: M(ctIn).

func (LinearTransformationEvaluator) EvaluateMany

func (eval LinearTransformationEvaluator) EvaluateMany(ctIn *rlwe.Ciphertext, linearTransformations []*LinearTransformation, buf rlwe.HoistingBuffer, opOut []*rlwe.Ciphertext) (err error)

EvaluateMany takes as input a ciphertext ctIn, a list of linear transformations [M0, M1, M2, ...] and a list of pre-allocated receiver opOut and evaluates opOut: [M0(ctIn), M1(ctIn), M2(ctIn), ...]

func (LinearTransformationEvaluator) EvaluateManyNew

func (eval LinearTransformationEvaluator) EvaluateManyNew(ctIn *rlwe.Ciphertext, linearTransformations []*LinearTransformation, buf rlwe.HoistingBuffer) (opOut []*rlwe.Ciphertext, err error)

EvaluateManyNew takes as input a ciphertext ctIn and a list of linear transformations [M0, M1, M2, ...] and returns opOut:[M0(ctIn), M1(ctIn), M2(ctInt), ...].

func (LinearTransformationEvaluator) EvaluateNew

func (eval LinearTransformationEvaluator) EvaluateNew(ctIn *rlwe.Ciphertext, linearTransformation *LinearTransformation, buf rlwe.HoistingBuffer) (opOut *rlwe.Ciphertext, err error)

EvaluateNew takes as input a ciphertext ctIn and a linear transformation M and evaluate and returns opOut: M(ctIn).

func (LinearTransformationEvaluator) EvaluateSequential

func (eval LinearTransformationEvaluator) EvaluateSequential(ctIn *rlwe.Ciphertext, linearTransformations []*LinearTransformation, buf rlwe.HoistingBuffer, opOut *rlwe.Ciphertext) (err error)

EvaluateSequential takes as input a ciphertext ctIn and a list of linear transformations [M0, M1, M2, ...] and returns opOut:...M2(M1(M0(ctIn))

func (LinearTransformationEvaluator) EvaluateSequentialNew

func (eval LinearTransformationEvaluator) EvaluateSequentialNew(ctIn *rlwe.Ciphertext, linearTransformations []*LinearTransformation, buf rlwe.HoistingBuffer) (opOut *rlwe.Ciphertext, err error)

EvaluateSequentialNew takes as input a ciphertext ctIn and a list of linear transformations [M0, M1, M2, ...] and returns opOut:...M2(M1(M0(ctIn))

type LinearTransformationParameters

type LinearTransformationParameters struct {
	// Indexes is the list of the non-zero diagonals of the square matrix.
	// A non zero diagonals is a diagonal with a least one non-zero element.
	Indexes []int

	// LevelQ is the level at which to encode the linear transformation.
	LevelQ int

	// LevelP is the level of the auxliary prime used during the automorphisms
	// User must ensure that this value is the same as the one used to generate
	// the evaluation keys used to perform the automorphisms.
	LevelP int

	// Scale is the plaintext scale at which to encode the linear transformation.
	Scale rlwe.Scale

	// LogDimensions is the log2 dimensions of the matrix that can be SIMD packed
	// in a single plaintext polynomial.
	// This method is equivalent to params.PlaintextDimensions().
	// Note that the linear transformation is evaluated independently on each rows of
	// the SIMD packed matrix.
	LogDimensions ring.Dimensions

	// Size of the giant step in the BSGS algorithm. If left to zero, then the optimal
	// value is derived. If set to -1, then indicates that the naive evaluation should
	// be used.
	GiantStep int
}

LinearTransformationParameters is a struct storing the parameterization of a linear transformation.

A homomorphic linear transformations on a ciphertext acts as evaluating:

Ciphertext([1 x n] vector) <- Ciphertext([1 x n] vector) x Plaintext([n x n] matrix)

where n is the number of plaintext slots.

The diagonal representation of a linear transformations is defined by first expressing the linear transformation through its nxn matrix and then traversing the matrix diagonally.

For example, the following nxn for n=4 matrix:

0 1 2 3 (diagonal index) | 1 2 3 0 | | 0 1 2 3 | | 3 0 1 2 | | 2 3 0 1 |

its diagonal traversal representation is comprised of 3 non-zero diagonals at indexes [0, 1, 2]: 0: [1, 1, 1, 1] 1: [2, 2, 2, 2] 2: [3, 3, 3, 3] 3: [0, 0, 0, 0] -> this diagonal is omitted as it is composed only of zero values.

Note that negative indexes can be used and will be interpreted modulo the matrix dimension.

The diagonal representation is well suited for two reasons:

  1. It is the effective format used during the homomorphic evaluation.
  2. It enables on average a more compact and efficient representation of linear transformations than their matrix representation by being able to only store the non-zero diagonals.

Finally, some metrics about the time and storage complexity of homomorphic linear transformations:

  • Storage: #diagonals polynomials mod Q * P
  • Evaluation: #diagonals multiplications and 2sqrt(#diagonals) ciphertexts rotations.

func (*LinearTransformationParameters) GaloisElements

func (ltParams *LinearTransformationParameters) GaloisElements(params rlwe.ParameterProvider) (galEls []uint64)

GaloisElements returns the list of Galois elements needed for the evaluation of the linear transformation.

type PatersonStockmeyerPolynomial

type PatersonStockmeyerPolynomial struct {
	Degree int
	Base   int
	Level  int
	Scale  rlwe.Scale
	Value  []Polynomial
}

PatersonStockmeyerPolynomial is a struct that stores the Paterson Stockmeyer decomposition of a polynomial. The decomposition of P(X) is given as sum pi(X) * X^{2^{n}} where degree(pi(X)) =~ sqrt(degree(P(X)))

type PatersonStockmeyerPolynomialVector

type PatersonStockmeyerPolynomialVector struct {
	Value   map[int]*PatersonStockmeyerPolynomial
	Mapping []int
}

PatersonStockmeyerPolynomialVector is a struct implementing the Paterson Stockmeyer decomposition of a PolynomialVector. See PatersonStockmeyerPolynomial for additional information.

func (*PatersonStockmeyerPolynomialVector) Degree

Degree returns the degree of the i-th baby polynomial.

func (*PatersonStockmeyerPolynomialVector) Level

Level returns the level of the i-th baby polynomial.

func (*PatersonStockmeyerPolynomialVector) Scale

func (p *PatersonStockmeyerPolynomialVector) Scale(i int) (scale rlwe.Scale)

Scale returns the scale of the i-th baby polynomial.

func (*PatersonStockmeyerPolynomialVector) Split

Split returns the number of baby polynomials.

type Permutation

type Permutation[T any] []struct {
	X int // Start index
	Y int // End index
	C T   // Scalar factor
}

Permutation is a struct that defines a linear transformation acting as a permutation over a vector. The defined permutation can be injective but not surjective.

func NewPermutation

func NewPermutation[T any](size int) Permutation[T]

NewPermutation allocates a new [hefloat.Permutation] that can then be populated manually.

func (Permutation[T]) Diagonals

func (p Permutation[T]) Diagonals(LogDimensions ring.Dimensions) Diagonals[T]

Diagonals returns the [hefloat.Diagonals] representation of the permutation. The [hefloat.Diagonals] struct is used to instantiate an [hefloat.LinearTransformationParameters].

func (Permutation[T]) GaloisElements

func (p Permutation[T]) GaloisElements(params rlwe.ParameterProvider, LogDimensions ring.Dimensions) (galEls []uint64)

func (Permutation[T]) Indexes

func (p Permutation[T]) Indexes(LogDimensions ring.Dimensions) (indexes []int)

type Polynomial

type Polynomial struct {
	*bignum.Polynomial
	MaxDeg int        // Always set to len(Coeffs)-1
	Lead   bool       // Always set to true
	Lazy   bool       // Flag for lazy-relinearization
	Level  int        // Metadata for BSGS polynomial evaluation
	Scale  rlwe.Scale // Metadata for BSGS polynomial evaluation
}

Polynomial is a struct for representing plaintext polynomials for their homomorphic evaluation in an encrypted point. The type wraps a bignum.Polynomial along with several evaluation- related parameters.

func NewPolynomial

func NewPolynomial(poly *bignum.Polynomial) *Polynomial

NewPolynomial returns an instantiated Polynomial for the provided bignum.Polynomial.

func (*Polynomial) Factorize

func (p *Polynomial) Factorize(n int) (pq, pr *Polynomial)

Factorize factorizes p as X^{n} * pq + pr.

func (*Polynomial) GetPatersonStockmeyerPolynomial

func (p *Polynomial) GetPatersonStockmeyerPolynomial(params rlwe.ParameterProvider, inputLevel int, inputScale, outputScale rlwe.Scale, eval SimEvaluator) *PatersonStockmeyerPolynomial

GetPatersonStockmeyerPolynomial returns the Paterson Stockmeyer polynomial decomposition of the target polynomial. The decomposition is done with the power of two basis.

type PolynomialVector

type PolynomialVector struct {
	Value   map[int]*Polynomial
	Mapping []int
}

PolynomialVector is a struct storing a set of polynomials and a mapping that indicates on which slot each polynomial has to be independently evaluated. For example, if we are given two polynomials P0(X) and P1(X) and the folling mapping: map[int][]int{0:[0, 1, 2], 1:[3, 4, 5]}, then the polynomial evaluation on a vector [a, b, c, d, e, f, g, h] will evaluate to [P0(a), P0(b), P0(c), P1(d), P1(e), P1(f), 0, 0]

func NewPolynomialVector

func NewPolynomialVector(polys map[int]*Polynomial, mapping []int) (*PolynomialVector, error)

NewPolynomialVector instantiates a new PolynomialVector from a set of bignum.Polynomial and a mapping indicating which polynomial has to be evaluated on which slot. For example, if we are given two polynomials P0(X) and P1(X) and the folling mapping: map[int][]int{0:[0, 1, 2], 1:[3, 4, 5]}, then the polynomial evaluation on a vector [a, b, c, d, e, f, g, h] will evaluate to [P0(a), P0(b), P0(c), P1(d), P1(e), P1(f), 0, 0]

func (*PolynomialVector) Basis

func (p *PolynomialVector) Basis() bignum.Basis

func (*PolynomialVector) ChangeOfBasis

func (p *PolynomialVector) ChangeOfBasis(slots int) (scalar, constant []big.Float)

func (*PolynomialVector) Degree

func (p *PolynomialVector) Degree() int

func (*PolynomialVector) Depth

func (p *PolynomialVector) Depth() (depth int)

Depth returns the depth required to evaluate the receiver.

func (*PolynomialVector) Evaluate

func (p *PolynomialVector) Evaluate(values interface{})

func (*PolynomialVector) Factorize

func (p *PolynomialVector) Factorize(n int) (polyq, polyr *PolynomialVector)

Factorize factorizes the underlying Polynomial vector p into p = polyq * X^{n} + polyr.

func (*PolynomialVector) GetPatersonStockmeyerPolynomial

func (p *PolynomialVector) GetPatersonStockmeyerPolynomial(params rlwe.ParameterProvider, inputLevel int, inputScale, outputScale rlwe.Scale, eval SimEvaluator) *PatersonStockmeyerPolynomialVector

GetPatersonStockmeyerPolynomial returns the Paterson Stockmeyer polynomial decomposition of the target PolynomialVector. The decomposition is done with the power of two basis

func (*PolynomialVector) IsEven

func (p *PolynomialVector) IsEven() (even bool)

IsEven returns true if all underlying polynomials are even, i.e. all odd powers are zero.

func (*PolynomialVector) IsOdd

func (p *PolynomialVector) IsOdd() (odd bool)

IsOdd returns true if all underlying polynomials are odd, i.e. all even powers are zero.

func (*PolynomialVector) Lazy

func (p *PolynomialVector) Lazy() (lazy bool)

Lazy return true if at least one polynomial is set to Lazy=true

func (*PolynomialVector) PopulatePowerBasis

func (p *PolynomialVector) PopulatePowerBasis(eval EvaluatorForPolynomial, pb *PowerBasis) (err error)

type PowerBasis

type PowerBasis struct {
	bignum.Basis
	Value structs.Map[int, rlwe.Ciphertext]
}

PowerBasis is a struct storing powers of a ciphertext.

func NewPowerBasis

func NewPowerBasis(ct *rlwe.Ciphertext, basis bignum.Basis) (p *PowerBasis)

NewPowerBasis creates a new PowerBasis. It takes as input a ciphertext and a basis type. The struct treats the input ciphertext as a monomial X and can be used to generates power of this monomial X^{n} in the given BasisType.

func (PowerBasis) BinarySize

func (p PowerBasis) BinarySize() (size int)

BinarySize returns the serialized size of the object in bytes.

func (*PowerBasis) GenPower

func (p *PowerBasis) GenPower(n int, lazy bool, eval Evaluator) (err error)

GenPower recursively computes X^{n}. If lazy = true, the final X^{n} will not be relinearized. Previous non-relinearized X^{n} that are required to compute the target X^{n} are automatically relinearized.

func (PowerBasis) MarshalBinary

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

MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.

func (*PowerBasis) ReadFrom

func (p *PowerBasis) ReadFrom(r io.Reader) (n int64, err error)

ReadFrom reads on the object from an io.Writer. It implements the io.ReaderFrom interface.

Unless r implements the buffer.Reader interface (see see lattigo/utils/buffer/reader.go), it will be wrapped into a bufio.Reader. Since this requires allocation, it is preferable to pass a buffer.Reader directly:

  • When reading multiple values from a io.Reader, it is preferable to first first wrap io.Reader in a pre-allocated bufio.Reader.
  • When reading from a var b []byte, it is preferable to pass a buffer.NewBuffer(b) as w (see lattigo/utils/buffer/buffer.go).

func (*PowerBasis) UnmarshalBinary

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

UnmarshalBinary decodes a slice of bytes generated by MarshalBinary or WriteTo on the object.

func (PowerBasis) WriteTo

func (p PowerBasis) WriteTo(w io.Writer) (n int64, err error)

WriteTo writes the object on an io.Writer. It implements the io.WriterTo interface, and will write exactly object.BinarySize() bytes on w.

Unless w implements the buffer.Writer interface (see lattigo/utils/buffer/writer.go), it will be wrapped into a bufio.Writer. Since this requires allocations, it is preferable to pass a buffer.Writer directly:

  • When writing multiple times to a io.Writer, it is preferable to first wrap the io.Writer in a pre-allocated bufio.Writer.
  • When writing to a pre-allocated var b []byte, it is preferable to pass buffer.NewBuffer(b) as w (see lattigo/utils/buffer/buffer.go).

type RingPackingEvaluationKey

type RingPackingEvaluationKey struct {
	// Parameters are the different Parameters among
	// which a ciphertext will be switched during the
	// procedure. These parameters share the same primes
	// but support different ring degrees.
	Parameters map[int]rlwe.ParameterProvider

	// RingSwitchingKeys are the ring degree switching keys
	// indexed as map[inputLogN][outputLogN]
	RingSwitchingKeys map[int]map[int]*rlwe.EvaluationKey

	// RepackKeys are the [rlwe.EvaluationKey] used for the
	// RLWE repacking.
	RepackKeys map[int]rlwe.EvaluationKeySet

	// ExtractKeys are the [rlwe.EvaluationKey] used for the
	// RLWE extraction.
	ExtractKeys map[int]rlwe.EvaluationKeySet
}

RingPackingEvaluationKey is a struct storing the ring packing evaluation keys. All fields of this struct are public, enabling custom instantiations.

func (*RingPackingEvaluationKey) GenExtractEvaluationKeys

func (rpk *RingPackingEvaluationKey) GenExtractEvaluationKeys(params rlwe.ParameterProvider, sk *rlwe.SecretKey, evkParams rlwe.EvaluationKeyParameters)

GenExtractEvaluationKeys generates the set of params.LogN() [rlwe.EvaluationKey]s necessary to perform the extraction operation. See RingPackingEvaluator.Extract for additional information.

func (*RingPackingEvaluationKey) GenRepackEvaluationKeys

func (rpk *RingPackingEvaluationKey) GenRepackEvaluationKeys(params rlwe.ParameterProvider, sk *rlwe.SecretKey, evkParams rlwe.EvaluationKeyParameters)

GenRepackEvaluationKeys generates the set of params.LogN() [rlwe.EvaluationKey]s necessary to perform the repacking operation. See RingPackingEvaluator.Repack for additional information.

func (*RingPackingEvaluationKey) GenRingSwitchingKeys

func (rpk *RingPackingEvaluationKey) GenRingSwitchingKeys(params rlwe.ParameterProvider, sk *rlwe.SecretKey, minLogN int, evkParams rlwe.EvaluationKeyParameters) (ski map[int]*rlwe.SecretKey, err error)

GenRingSwitchingKeys generates the [rlwe.Parameter]s and [rlwe.EvaluationKey]s to be able to split an rlwe.Ciphertext into two [rlwe.Ciphertext]s of half the ring degree and merge two [rlwe.Ciphertext]s into one rlwe.Ciphertext of twice the ring degree.

The method returns the [rlwe.Parameter]s, [rlwe.EvaluationKey]s and ephemeral [rlwe.SecretKey]s used to generate the ring-switching [rlwe.EvaluationKey]s.

See the methods RingPackingEvaluator.Split and RingPackingEvaluator.Repack.

This function will return an error if minLogN >= params.LogN().

func (RingPackingEvaluationKey) MaxLogN

func (rpk RingPackingEvaluationKey) MaxLogN() (maxLogN int)

MaxLogN returns the maximum Log(N) among the supported ring degrees. This method requires that the field Parameters of RingPackingEvaluationKey has been populated.

func (RingPackingEvaluationKey) MinLogN

func (rpk RingPackingEvaluationKey) MinLogN() (minLogN int)

MinLogN returns the minimum Log(N) among the supported ring degrees. This method requires that the field Parameters of RingPackingEvaluationKey has been populated.

type RingPackingEvaluator

type RingPackingEvaluator struct {
	*RingPackingEvaluationKey

	Evaluators map[int]*rlwe.Evaluator

	//XPow2NTT: [1, x, x^2, x^4, ..., x^2^s] / (X^2^s +1)
	XPow2NTT map[int][]ring.RNSPoly

	//XInvPow2NTT: [1, x^-1, x^-2, x^-4, ..., x^-2^s/2] / (X^2^s +1)
	XInvPow2NTT map[int][]ring.RNSPoly
}

RingPackingEvaluator is an evaluator for Ring-LWE packing operations. All fields of this struct are public, enabling custom instantiations.

func NewRingPackingEvaluator

func NewRingPackingEvaluator(evk *RingPackingEvaluationKey) *RingPackingEvaluator

NewRingPackingEvaluator instantiates a new RingPackingEvaluator from a RingPackingEvaluationKey.

func (RingPackingEvaluator) Expand

func (eval RingPackingEvaluator) Expand(ct *rlwe.Ciphertext, logGap int) (cts map[int]*rlwe.Ciphertext, err error)

Expand expands a RLWE Ciphertext encrypting P(X) = ci * X^i and returns a map of ciphertexts, each encrypting P(X) = ci * X^0, indexed by i, for 0<= i < 2^{logN} and i divisible by 2^{logGap}.

This method is a used as a sub-routine of the Extract method.

The method will return an error if:

  • The input ciphertext degree is not one
  • The ring type is not ring.Standard

func (RingPackingEvaluator) Extract

func (eval RingPackingEvaluator) Extract(ct *rlwe.Ciphertext, idx map[int]bool) (cts map[int]*rlwe.Ciphertext, err error)

Extract takes as input a ciphertext encrypting P(X) = c[i] * X^i and returns a map of ciphertexts of degree eval.MinLogN(), each encrypting P(X) = c[i] * X^{0} for i in idx. All non-constant coefficients are zeroed and thus correctness is ensured if this method is composed with either Repack or RepackNaive.

func (RingPackingEvaluator) ExtractNaive

func (eval RingPackingEvaluator) ExtractNaive(ct *rlwe.Ciphertext, idx map[int]bool) (cts map[int]*rlwe.Ciphertext, err error)

ExtractNaive takes as input a ciphertext encrypting P(X) = c[i] * X^i and returns a map of ciphertexts of degree eval.MinLogN(), each encrypting P(X) = c[i] * X^{0} for i in idx. Non-constant coefficients are NOT zeroed thus correctness is only ensured if this method is composed with Repack.

If eval.MinLogN() = eval.MaxLogN(), no evaluation keys are required for this method. If eval.MinLogN() < eval.MaxLogN(), only RingSwitchingKeys are required for this method.

func (RingPackingEvaluator) Merge

func (eval RingPackingEvaluator) Merge(ctEvenNHalf, ctOddNHalf, ctN *rlwe.Ciphertext) (err error)

Merge merges two ciphertexts of degree N/2 into a ciphertext of degre N: ctN[X] = ctEvenNHalf[Y] + X * ctOddNHalf[Y] where Y = X^2.

func (RingPackingEvaluator) MergeNew

func (eval RingPackingEvaluator) MergeNew(ctEvenNHalf, ctOddNHalf *rlwe.Ciphertext) (ctN *rlwe.Ciphertext, err error)

MergeNew merges two ciphertexts of degree N/2 into a ciphertext of degre N: ctN[X] = ctEvenNHalf[Y] + X * ctOddNHalf[Y] where Y = X^2.

func (RingPackingEvaluator) Pack

func (eval RingPackingEvaluator) Pack(cts map[int]*rlwe.Ciphertext, inputLogGap int, zeroGarbageSlots bool) (ct *rlwe.Ciphertext, err error)

Pack packs a map of of ciphertexts, each encrypting Pi(X) = ci * X^{i} for 0 <= i * 2^{inputLogGap} < 2^{LogN} and indexed by j, for 0<= j < 2^{eval.MaxLogN()} and returns ciphertext encrypting P(X) = Pi(X) * X^i. zeroGarbageSlots: if set to true, slots which are not multiples of X^{2^{logGap}} will be zeroed during the procedure.

The method will return an error if:

  • The number of ciphertexts is 0
  • Any input ciphertext degree is not one
  • Gaps between ciphertexts is smaller than inputLogGap > N
  • The ring type is not ring.Standard

Example: we want to pack 4 ciphertexts into one, and keep only coefficients which are a multiple of X^{4}.

To do so, we must set logGap = 2.
Here the `X` slots are treated as garbage slots that we want to discard during the procedure.

input: map[int]{
   0: [x00, X, X, X, x01, X, X, X],   with logGap = 2
   1: [x10, X, X, X, x11, X, X, X],
   2: [x20, X, X, X, x21, X, X, X],
   3: [x30, X, X, X, x31, X, X, X],
	}

 Step 1:
         map[0]: 2^{-1} * (map[0] + X^2 * map[2] + phi_{5^2}(map[0] - X^2 * map[2]) = [x00, X, x20, X, x01, X, x21, X]
         map[1]: 2^{-1} * (map[1] + X^2 * map[3] + phi_{5^2}(map[1] - X^2 * map[3]) = [x10, X, x30, X, x11, X, x31, X]
 Step 2:
         map[0]: 2^{-1} * (map[0] + X^1 * map[1] + phi_{5^4}(map[0] - X^1 * map[1]) = [x00, x10, x20, x30, x01, x11, x21, x22]

func (RingPackingEvaluator) Repack

func (eval RingPackingEvaluator) Repack(cts map[int]*rlwe.Ciphertext) (ct *rlwe.Ciphertext, err error)

Repack takes as input a map of ciphertext and repacks the constant coefficient each ciphertext into a single ciphertext of degree eval.MaxLogN() following the indexing of the map.

For example, if cts = map[int]*rlwe.Ciphertext{0:ct0, 1:ct1, 4:ct2}, then the method will return a ciphertext encrypting P(X) = ct0[0] + ct1[0] * X + ct2[0] * X^4.

The method accepts ciphertexts of a ring degree between eval.MinLogN() and eval.MaxLogN().

All non-constant coefficient are zeroed during the repacking, thus correctness is ensured if this method can be composed with either Extract or ExtractNaive.

func (RingPackingEvaluator) RepackNaive

func (eval RingPackingEvaluator) RepackNaive(cts map[int]*rlwe.Ciphertext) (ct *rlwe.Ciphertext, err error)

RepackNaive takes as input a map of ciphertext and repacks the constant coefficient each ciphertext into a single ciphertext of degree eval.MaxLogN() following the indexing of the map.

For example, if cts = map[int]*rlwe.Ciphertext{0:ct0, 1:ct1, 4:ct2}, then the method will return a ciphertext encrypting P(X) = ct0[0] + ct1[0] * X + ct2[0] * X^4.

The method accepts ciphertexts of a ring degree between eval.MinLogN() and eval.MaxLogN().

If eval.MinLogN() = eval.MaxLogN(), no evaluation keys are required for this method. If eval.MinLogN() < eval.MaxLogN(), only RingSwitchingKeys are required for this method.

Unlike Repack, non-constant coefficient are NOT zeroed during the repacking, thus correctness is only ensured if this method is composed with either Extract.

func (RingPackingEvaluator) ShallowCopy

func (eval RingPackingEvaluator) ShallowCopy() *RingPackingEvaluator

ShallowCopy creates a shallow copy of this struct in which all the read-only data-structures are shared with the receiver and the temporary buffers are reallocated. The receiver and the returned Evaluators can be used concurrently.

func (RingPackingEvaluator) Split

func (eval RingPackingEvaluator) Split(ctN, ctEvenNHalf, ctOddNHalf *rlwe.Ciphertext) (err error)

Split splits a ciphertext of degree N into two ciphertexts of degree N/2: ctN[X] = ctEvenNHalf[Y] + X * ctOddNHalf[Y] where Y = X^2.

func (RingPackingEvaluator) SplitNew

func (eval RingPackingEvaluator) SplitNew(ctN *rlwe.Ciphertext) (ctEvenNHalf, ctOddNHalf *rlwe.Ciphertext, err error)

SplitNew splits a ciphertext of degree N into two ciphertexts of degree N/2: ctN[X] = ctEvenNHalf[Y] + X * ctOddNHalf[Y] where Y = X^2.

type SimEvaluator

type SimEvaluator interface {
	LogDimensions() ring.Dimensions
	MulNew(op0, op1 *SimOperand) *SimOperand
	Rescale(op0 *SimOperand)
	PolynomialDepth(degree int) int
	UpdateLevelAndScaleGiantStep(lead bool, tLevelOld int, tScaleOld, xPowScale rlwe.Scale, p *Polynomial) (tLevelNew int, tScaleNew rlwe.Scale)
	UpdateLevelAndScaleBabyStep(lead bool, tLevelOld int, tScaleOld rlwe.Scale, p *Polynomial, pb SimPowerBasis) (tLevelNew int, tScaleNew rlwe.Scale, degree int)
}

SimEvaluator defines a set of method on SimOperands.

type SimOperand

type SimOperand struct {
	Level  int
	Degree int
	Scale  rlwe.Scale
}

SimOperand is a dummy operand that only stores its level and scale.

type SimPowerBasis

type SimPowerBasis map[int]*SimOperand

SimPowerBasis is a map storing powers of SimOperands indexed by their power.

func (SimPowerBasis) GenPower

func (d SimPowerBasis) GenPower(Lazy bool, n int, eval SimEvaluator)

GenPower populates the target SimPowerBasis with the nth power.

Directories

Path Synopsis
Package hebin implements blind rotations evaluation for RLWE schemes.
Package hebin implements blind rotations evaluation for RLWE schemes.
Package hefloat implements Homomorphic Encryption with fixed-point approximate arithmetic over the complex or real numbers.
Package hefloat implements Homomorphic Encryption with fixed-point approximate arithmetic over the complex or real numbers.
bootstrapping
Package bootstrapping implements bootstrapping for fixed-point encrypted approximate homomorphic encryption over the complex/real numbers.
Package bootstrapping implements bootstrapping for fixed-point encrypted approximate homomorphic encryption over the complex/real numbers.
cosine
Package cosine method is the Go implementation of the polynomial-approximation algorithm by Han and Ki in
Package cosine method is the Go implementation of the polynomial-approximation algorithm by Han and Ki in
Package heint provides Homomorphic Encryption for encrypted modular arithmetic over the integers.
Package heint provides Homomorphic Encryption for encrypted modular arithmetic over the integers.

Jump to

Keyboard shortcuts

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