ckks

package
v2.4.1 Latest Latest
Warning

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

Go to latest
Published: Nov 15, 2023 License: Apache-2.0 Imports: 12 Imported by: 17

README

CKKS

The package CKKS is an RNS-accelerated version of the Homomorphic Encryption for Arithmetic of Approximate Numbers (HEAAN, a.k.a. CKKS) scheme originally proposed by Cheon, Kim, Kim and Song. The package supports two variants of the scheme: the standard one that encrypts vectors of complex numbers, and the conjugate-invariant one that encrypts vectors of real numbers, as proposed by Kim and Song.The RingType field of the Parameter struct controls which variant is instantiated:

For RingType: ring.Standard, the standard variant of CKKS is used. This requires that all moduli in the chain are congruent to 1 modulo 2N for N the ring degree. This variant supports packing of up to N/2 plaintext complex values into a single ciphertext.

For RingType: ring.ConjugateInvariant, the conjugate-invariant variant of CKKS is used. This requires that all moduli in the chain are congruent to 1 modulo 4N for N the ring degree. This variant supports packing of up to N plaintext real values into a single ciphertext.

Brief description of the Standard variant

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 complex numbers to a polynomial with the property:

,

where represents a component-wise product, and 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 chosen carefully to suit the intended use of the scheme.

equation: the ciphertext modulus. In Lattigo, it is chosen to be the product of a chain 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 30 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 carefully chosen 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 plaintext scale. Since complex numbers are encoded on polynomials with integer coefficients, the original values must be scaled during the encoding, before being rounded to the nearest integer. The equation parameter is the power of two by which the values are multiplied during the encoding. It has an impact on the precision of the output and on the amount of operations a fresh encryption can undergo before overflowing.

Choosing the right parameters for a given application

There are 3 application-dependent parameters:

  • LogN: it determines (a) how many values can be encoded (batched) at once (maximum N/2) in one plaintext, and (b) the maximum total modulus bit size (the product of all the moduli) for a given security parameter.
  • Modulichain: it determines how many consecutive scalar and non-scalar multiplications (the depth of the arithmetic circuit) can be evaluated before requiring decryption. Since Lattigo features an RNS implementation, this parameter requires careful fine-tuning depending on the application; i.e., the rescaling procedure can only rescale by one of the RNS modulus at a time, whose size has to be chosen when creating the CKKS context. Additionally, the individual size of each of the moduli also has an effect on the error introduced during the rescaling, since they cannot be powers of 2, so they should be chosen as NTT primes as close as possible to a power of 2 instead.
  • Logscale: it determines the scale of the plaintext, affecting both the precision and the maximum allowed depth for a given security parameter.

Configuring parameters for CKKS is very application dependent, requiring a prior analysis of the circuit to be executed under encryption. The following example illustrates how this parametrization can be done, showing that it is possible to come up with different parameter sets for a given circuit, each set having pros and cons.

Let us define the evaluation of an arbitrary smooth function f(x) on an array of ~4000 complex elements contained in a square of side 2 centered at the complex origin (with values ranging between -1-1i and 1+1i). We first need to find a good polynomial approximation for the given range. Lattigo provides an automatic Chebyshev approximation for any given polynomial degree, which can be used for this purpose (it is also possible to define a different polynomial approximation of lower degree with an acceptable error).

Let us assume that we find an approximation of degree 5, i.e., a + bx + cx^3 + dx^5. This function can be evaluated with 3 scalar multiplications, 3 additions and 3 non-scalar multiplications, consuming a total of 4 levels (one for the scalar multiplications and 3 for the non-scalar multiplications).

We then need to chose a scale for the plaintext, that will influence both the bit consumption for the rescaling, and the precision of the computation. If we choose a scale of 2^40, we need to consume at least 160 bits (4 levels) during the evaluation, and we still need some bits left to store the final result with an acceptable precision. Let us assume that the output of the approximation lies always in the square between -20-20i and 20+20i; then, the final modulus must be at least 5 bits larger than the final scale (to preserve the integer precision).

The following parameters will work for the posed example:

  • LogN = 13
  • Modulichain = [45, 40, 40, 40, 40], for a logQ <= 205
  • LogScale = 40

But it is also possible to use less levels to have ciphertexts of smaller size and, therefore, a faster evaluation, at the expense of less precision. This can be achieved by using a scale of 30 bits and squeezing two multiplications in a single level, while pre-computing the last scalar multiplication already in the plaintext. Instead of evaluating a + bx + cx^3 + dx^5, we pre-multiply the plaintext by d^(1/5) and evaluate a + b/(d^(1/5))x + c/(d^(3/5)) + x^5.

The following parameters are enough to evaluate this modified function:

  • LogN = 13
  • Modulichain = [35, 60, 60], for a logQ <= 155
  • LogScale = 30

To summarize, several parameter sets can be used to evaluate a given function, achieving different trade-offs for space and time versus precision.

Choosing secure parameters

The CKKS 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 security parameters is defined by the tuple equation :

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

As mentioned, setting parameters for CKKS involves not only choosing this tuple, but also defining the actual moduli chain depending on the application at hand, which is why the provided default parameter sets have to be fine-tuned, preserving the values of the aforementioned tuples, in order to maintain the required security level of 128 bits. That is, Lattigo provides a set of default parameters for CKKS, including example moduli chains, ensuring 128 bit security. The user might want to choose different values in the moduli chain optimized for a specific application. As long as the total modulus is equal or below the above values for a given logN, the scheme will still provide a security of at least 128 bits against the current best known attacks.

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 CKKS security parameters should be re-evaluated if sparse keys are used.

Documentation

Overview

Package ckks implements a RNS-accelerated version of the Homomorphic Encryption for Arithmetic for Approximate Numbers (HEAAN, a.k.a. CKKS) scheme. It provides approximate arithmetic over the complex numbers.package ckks

Index

Constants

View Source
const (
	// StandardBasis : x^(a+b) = x^a * x^b
	StandardBasis = PolynomialBasis(0)
	// ChebyshevBasis : x^(a+b) = 2 * x^a *x^b - T^|a-b|
	ChebyshevBasis = PolynomialBasis(1)
)
View Source
const GaloisGen uint64 = 5

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

View Source
const IsNegligbleThreshold float64 = 1e-14

IsNegligbleThreshold : threshold under which a coefficient of a polynomial is ignored.

Variables

View Source
var (

	// PN12QP109 is a default parameter set for logN=12 and logQP=109
	PN12QP109 = ParametersLiteral{
		LogN:     12,
		LogSlots: 11,
		Q: []uint64{0x200000e001,
			0x100006001},
		P:            []uint64{0x3ffffea001},
		DefaultScale: 1 << 32,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.Standard,
	}

	// PN13QP218 is a default parameter set for logN=13 and logQP=218
	PN13QP218 = ParametersLiteral{
		LogN:     13,
		LogSlots: 12,
		Q: []uint64{0x1fffec001,
			0x3fff4001,
			0x3ffe8001,
			0x40020001,
			0x40038001,
			0x3ffc0001},
		P:            []uint64{0x800004001},
		DefaultScale: 1 << 30,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.Standard,
	}
	// PN14QP438 is a default parameter set for logN=14 and logQP=438
	PN14QP438 = ParametersLiteral{
		LogN:     14,
		LogSlots: 13,
		Q: []uint64{0x200000008001, 0x400018001,
			0x3fffd0001, 0x400060001,
			0x400068001, 0x3fff90001,
			0x400080001, 0x4000a8001,
			0x400108001, 0x3ffeb8001},
		P:            []uint64{0x7fffffd8001, 0x7fffffc8001},
		DefaultScale: 1 << 34,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.Standard,
	}

	// PN15QP880 is a default parameter set for logN=15 and logQP=880
	PN15QP880 = ParametersLiteral{
		LogN:     15,
		LogSlots: 14,
		Q: []uint64{0x4000000120001, 0x10000140001, 0xffffe80001,
			0x10000290001, 0xffffc40001, 0x100003e0001,
			0x10000470001, 0x100004b0001, 0xffffb20001,
			0x10000500001, 0x10000650001, 0xffff940001,
			0xffff8a0001, 0xffff820001, 0xffff780001,
			0x10000890001, 0xffff750001, 0x10000960001},
		P:            []uint64{0x40000001b0001, 0x3ffffffdf0001, 0x4000000270001},
		DefaultScale: 1 << 40,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.Standard,
	}
	// PN16QP1761 is a default parameter set for logN=16 and logQP = 1761
	PN16QP1761 = ParametersLiteral{
		LogN:     16,
		LogSlots: 15,
		Q: []uint64{0x80000000080001, 0x2000000a0001, 0x2000000e0001, 0x1fffffc20001,
			0x200000440001, 0x200000500001, 0x200000620001, 0x1fffff980001,
			0x2000006a0001, 0x1fffff7e0001, 0x200000860001, 0x200000a60001,
			0x200000aa0001, 0x200000b20001, 0x200000c80001, 0x1fffff360001,
			0x200000e20001, 0x1fffff060001, 0x200000fe0001, 0x1ffffede0001,
			0x1ffffeca0001, 0x1ffffeb40001, 0x200001520001, 0x1ffffe760001,
			0x2000019a0001, 0x1ffffe640001, 0x200001a00001, 0x1ffffe520001,
			0x200001e80001, 0x1ffffe0c0001, 0x1ffffdee0001, 0x200002480001,
			0x1ffffdb60001, 0x200002560001},
		P:            []uint64{0x80000000440001, 0x7fffffffba0001, 0x80000000500001, 0x7fffffffaa0001},
		DefaultScale: 1 << 45,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.Standard,
	}

	// PN12QP109CI is a default parameter set for logN=12 and logQP=109
	PN12QP109CI = ParametersLiteral{
		LogN:     12,
		LogSlots: 12,
		Q: []uint64{0x1ffffe0001,
			0x100014001},
		P:            []uint64{0x4000038001},
		DefaultScale: 1 << 32,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.ConjugateInvariant,
	}

	// PN13QP218CI is a default parameter set for logN=13 and logQP=218
	PN13QP218CI = ParametersLiteral{
		LogN:     13,
		LogSlots: 13,
		Q: []uint64{0x200038001,
			0x3ffe8001,
			0x40020001,
			0x40038001,
			0x3ffc0001,
			0x40080001},
		P:            []uint64{0x800008001},
		DefaultScale: 1 << 30,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.ConjugateInvariant,
	}
	// PN14QP438CI is a default parameter set for logN=14 and logQP=438
	PN14QP438CI = ParametersLiteral{
		LogN:     14,
		LogSlots: 14,
		Q: []uint64{0x2000000a0001, 0x3fffd0001,
			0x400060001, 0x3fff90001,
			0x400080001, 0x400180001,
			0x3ffd20001, 0x400300001,
			0x400360001, 0x4003e0001},
		P:            []uint64{0x80000050001, 0x7ffffdb0001},
		DefaultScale: 1 << 34,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.ConjugateInvariant,
	}

	// PN15QP880CI is a default parameter set for logN=15 and logQP=880
	PN15QP880CI = ParametersLiteral{
		LogN:     15,
		LogSlots: 15,
		Q: []uint64{0x4000000120001,
			0x10000140001, 0xffffe80001, 0xffffc40001,
			0x100003e0001, 0xffffb20001, 0x10000500001,
			0xffff940001, 0xffff8a0001, 0xffff820001,
			0xffff780001, 0x10000960001, 0x10000a40001,
			0xffff580001, 0x10000b60001, 0xffff480001,
			0xffff420001, 0xffff340001},
		P:            []uint64{0x3ffffffd20001, 0x4000000420001, 0x3ffffffb80001},
		DefaultScale: 1 << 40,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.ConjugateInvariant,
	}
	// PN16QP1761CI is a default parameter set for logN=16 and logQP = 1761
	PN16QP1761CI = ParametersLiteral{
		LogN:     16,
		LogSlots: 16,
		Q: []uint64{0x80000000080001,
			0x200000440001, 0x200000500001, 0x1fffff980001, 0x200000c80001,
			0x1ffffeb40001, 0x1ffffe640001, 0x200001a00001, 0x200001e80001,
			0x1ffffe0c0001, 0x200002480001, 0x200002800001, 0x1ffffd800001,
			0x200002900001, 0x1ffffd700001, 0x2000029c0001, 0x1ffffcf00001,
			0x200003140001, 0x1ffffcc80001, 0x1ffffcb40001, 0x1ffffc980001,
			0x200003740001, 0x200003800001, 0x200003d40001, 0x1ffffc200001,
			0x1ffffc140001, 0x200004100001, 0x200004180001, 0x1ffffbc40001,
			0x200004700001, 0x1ffffb900001, 0x200004cc0001, 0x1ffffb240001,
			0x200004e80001},
		P:            []uint64{0x80000000440001, 0x80000000500001, 0x7fffffff380001, 0x80000000e00001},
		DefaultScale: 1 << 45,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.ConjugateInvariant,
	}

	// PN12QP101pq is a default (post quantum) parameter set for logN=12 and logQP=101
	PN12QP101pq = ParametersLiteral{
		LogN:         12,
		LogSlots:     11,
		Q:            []uint64{0x800004001, 0x40002001},
		P:            []uint64{0x1000002001},
		DefaultScale: 1 << 30,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.Standard,
	}
	// PN13QP202pq is a default (post quantum) parameter set for logN=13 and logQP=202
	PN13QP202pq = ParametersLiteral{
		LogN:         13,
		LogSlots:     12,
		Q:            []uint64{0x1fffec001, 0x8008001, 0x8020001, 0x802c001, 0x7fa8001, 0x7f74001},
		P:            []uint64{0x400018001},
		DefaultScale: 1 << 27,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.Standard,
	}

	// PN14QP411pq is a default (post quantum) parameter set for logN=14 and logQP=411
	PN14QP411pq = ParametersLiteral{
		LogN:     14,
		LogSlots: 13,
		Q: []uint64{0x10000048001, 0x200038001, 0x1fff90001, 0x200080001, 0x1fff60001,
			0x2000b8001, 0x200100001, 0x1fff00001, 0x1ffef0001, 0x200128001},

		P:            []uint64{0x1ffffe0001, 0x1ffffc0001},
		DefaultScale: 1 << 33,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.Standard,
	}

	// PN15QP827pq is a default (post quantum) parameter set for logN=15 and logQP=827
	PN15QP827pq = ParametersLiteral{
		LogN:     15,
		LogSlots: 14,
		Q: []uint64{0x400000060001, 0x4000170001, 0x3fffe80001, 0x40002f0001, 0x4000300001,
			0x3fffcf0001, 0x40003f0001, 0x3fffc10001, 0x4000450001, 0x3fffb80001,
			0x3fffb70001, 0x40004a0001, 0x3fffb20001, 0x4000510001, 0x3fffaf0001,
			0x4000540001, 0x4000560001, 0x4000590001},
		P:            []uint64{0x2000000a0001, 0x2000000e0001, 0x2000001d0001},
		DefaultScale: 1 << 38,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.Standard,
	}
	// PN16QP1654pq is a default (post quantum) parameter set for logN=16 and logQP=1654
	PN16QP1654pq = ParametersLiteral{LogN: 16,
		LogSlots: 15,
		Q: []uint64{0x80000000080001, 0x2000000a0001, 0x2000000e0001, 0x1fffffc20001, 0x200000440001,
			0x200000500001, 0x200000620001, 0x1fffff980001, 0x2000006a0001, 0x1fffff7e0001,
			0x200000860001, 0x200000a60001, 0x200000aa0001, 0x200000b20001, 0x200000c80001,
			0x1fffff360001, 0x200000e20001, 0x1fffff060001, 0x200000fe0001, 0x1ffffede0001,
			0x1ffffeca0001, 0x1ffffeb40001, 0x200001520001, 0x1ffffe760001, 0x2000019a0001,
			0x1ffffe640001, 0x200001a00001, 0x1ffffe520001, 0x200001e80001, 0x1ffffe0c0001,
			0x1ffffdee0001, 0x200002480001},
		P:            []uint64{0x7fffffffe0001, 0x80000001c0001, 0x80000002c0001, 0x7ffffffd20001},
		DefaultScale: 1 << 45,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.Standard,
	}

	// PN12QP101pq is a default (post quantum) parameter set for logN=12 and logQP=101
	PN12QP101CIpq = ParametersLiteral{
		LogN:         12,
		LogSlots:     12,
		Q:            []uint64{0x800004001, 0x3fff4001},
		P:            []uint64{0xffffc4001},
		DefaultScale: 1 << 30,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.ConjugateInvariant,
	}
	// PN13QP202CIpq is a default (post quantum) parameter set for logN=13 and logQP=202
	PN13QP202CIpq = ParametersLiteral{
		LogN:         13,
		LogSlots:     13,
		Q:            []uint64{0x1ffffe0001, 0x100050001, 0xfff88001, 0x100098001, 0x1000b0001},
		P:            []uint64{0x1ffffc0001},
		DefaultScale: 1 << 32,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.ConjugateInvariant,
	}

	// PN14QP411CIpq is a default (post quantum) parameter set for logN=14 and logQP=411
	PN14QP411CIpq = ParametersLiteral{
		LogN:     14,
		LogSlots: 14,
		Q: []uint64{0x10000140001, 0x1fff90001, 0x200080001,
			0x1fff60001, 0x200100001, 0x1fff00001,
			0x1ffef0001, 0x1ffe60001, 0x2001d0001,
			0x2002e0001},

		P:            []uint64{0x1ffffe0001, 0x1ffffc0001},
		DefaultScale: 1 << 33,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.ConjugateInvariant,
	}

	// PN15QP827CIpq is a default (post quantum) parameter set for logN=15 and logQP=827
	PN15QP827CIpq = ParametersLiteral{
		LogN:     15,
		LogSlots: 15,
		Q: []uint64{0x400000060001, 0x3fffe80001, 0x4000300001, 0x3fffb80001,
			0x40004a0001, 0x3fffb20001, 0x4000540001, 0x4000560001,
			0x3fff900001, 0x4000720001, 0x3fff8e0001, 0x4000800001,
			0x40008a0001, 0x3fff6c0001, 0x40009e0001, 0x3fff300001,
			0x3fff1c0001, 0x4000fc0001},
		P:            []uint64{0x2000000a0001, 0x2000000e0001, 0x1fffffc20001},
		DefaultScale: 1 << 38,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.ConjugateInvariant,
	}
	// PN16QP1654CIpq is a default (post quantum) parameter set for logN=16 and logQP=1654
	PN16QP1654CIpq = ParametersLiteral{LogN: 16,
		LogSlots: 16,
		Q: []uint64{0x80000000080001, 0x200000440001, 0x200000500001, 0x1fffff980001,
			0x200000c80001, 0x1ffffeb40001, 0x1ffffe640001, 0x200001a00001,
			0x200001e80001, 0x1ffffe0c0001, 0x200002480001, 0x200002800001,
			0x1ffffd800001, 0x200002900001, 0x1ffffd700001, 0x2000029c0001,
			0x1ffffcf00001, 0x200003140001, 0x1ffffcc80001, 0x1ffffcb40001,
			0x1ffffc980001, 0x200003740001, 0x200003800001, 0x200003d40001,
			0x1ffffc200001, 0x1ffffc140001, 0x200004100001, 0x200004180001,
			0x1ffffbc40001, 0x200004700001, 0x1ffffb900001, 0x200004cc0001},
		P:            []uint64{0x80000001c0001, 0x80000002c0001, 0x8000000500001, 0x7ffffff9c0001},
		DefaultScale: 1 << 45,
		Sigma:        rlwe.DefaultSigma,
		RingType:     ring.ConjugateInvariant,
	}
)

Name of the different default parameter sets

DefaultConjugateInvariantParams is a set of default conjugate invariant parameters for encrypting real values and ensuring 128 bit security in a classic setting.

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

View Source
var DefaultPostQuantumConjugateInvariantParams = []ParametersLiteral{PN12QP101CIpq, PN13QP202CIpq, PN14QP411CIpq, PN15QP827CIpq, PN16QP1654CIpq}

DefaultPostQuantumConjugateInvariantParams is a set of default conjugate invariant parameters for encrypting real values and ensuring 128 bit security in a post-quantum setting.

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

Functions

func BsgsIndex added in v2.4.0

func BsgsIndex(el interface{}, 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 FindBestBSGSSplit added in v2.3.0

func FindBestBSGSSplit(diagMatrix interface{}, maxN int, maxRatio float64) (minN int)

FindBestBSGSSplit finds the best N1*N2 = N for the baby-step giant-step algorithm for matrix multiplication.

func GenSwitchkeysRescalingParams

func GenSwitchkeysRescalingParams(Q, P []uint64) (params []uint64)

GenSwitchkeysRescalingParams generates the parameters for rescaling the switching keys

func NewPublicKey

func NewPublicKey(params Parameters) (pk *rlwe.PublicKey)

NewPublicKey returns an allocated CKKS public with zero values.

func NewRelinearizationKey added in v2.2.0

func NewRelinearizationKey(params Parameters) *rlwe.RelinearizationKey

NewRelinearizationKey returns an allocated CKKS public relinearization key with zero value.

func NewRotationKeySet added in v2.2.0

func NewRotationKeySet(params Parameters, galoisElements []uint64) *rlwe.RotationKeySet

NewRotationKeySet returns an allocated set of CKKS public rotation keys with zero values for each galois element (i.e., for each supported rotation).

func NewSecretKey

func NewSecretKey(params Parameters) (sk *rlwe.SecretKey)

NewSecretKey returns an allocated CKKS secret key with zero values.

func NewSwitchingKey

func NewSwitchingKey(params Parameters) *rlwe.SwitchingKey

NewSwitchingKey returns an allocated CKKS public switching key with zero values.

func SliceBitReverseInPlaceComplex128 added in v2.3.0

func SliceBitReverseInPlaceComplex128(slice []complex128, N int)

SliceBitReverseInPlaceComplex128 applies an in-place bit-reverse permuation on the input slice.

func SliceBitReverseInPlaceFloat64 added in v2.3.0

func SliceBitReverseInPlaceFloat64(slice []float64, N int)

SliceBitReverseInPlaceFloat64 applies an in-place bit-reverse permuation on the input slice.

func SliceBitReverseInPlaceRingComplex added in v2.3.0

func SliceBitReverseInPlaceRingComplex(slice []*ring.Complex, N int)

SliceBitReverseInPlaceRingComplex applies an in-place bit-reverse permuation on the input slice.

func StandardDeviation added in v2.2.0

func StandardDeviation(vec []float64, scale float64) (std float64)

StandardDeviation computes the scaled standard deviation of the input vector.

Types

type Ciphertext

type Ciphertext struct {
	*rlwe.Ciphertext
	Scale float64
}

Ciphertext is *ring.Poly array representing a polynomial of degree > 0 with coefficients in R_Q.

func NewCiphertext

func NewCiphertext(params Parameters, degree, level int, scale float64) (ciphertext *Ciphertext)

NewCiphertext creates a new Ciphertext parameterized by degree, level and scale.

func NewCiphertextAtLevelFromPoly added in v2.3.0

func NewCiphertextAtLevelFromPoly(level int, poly [2]*ring.Poly) *Ciphertext

NewCiphertextAtLevelFromPoly construct a new Ciphetext at a specific level where the message is set to the passed poly. No checks are performed on poly and the returned Ciphertext will share its backing array of coefficient.

func NewCiphertextRandom

func NewCiphertextRandom(prng utils.PRNG, params Parameters, degree, level int, scale float64) (ciphertext *Ciphertext)

NewCiphertextRandom generates a new uniformly distributed Ciphertext of degree, level and scale.

func (*Ciphertext) Copy added in v2.2.0

func (ct *Ciphertext) Copy(ctp *Ciphertext)

Copy copies the given ciphertext ctp into the receiver ciphertext.

func (*Ciphertext) CopyNew added in v2.2.0

func (ct *Ciphertext) CopyNew() (ctc *Ciphertext)

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

func (*Ciphertext) GetDataLen

func (ct *Ciphertext) GetDataLen(WithMetaData bool) (dataLen int)

GetDataLen returns the length in bytes of the target Ciphertext.

func (*Ciphertext) MarshalBinary

func (ct *Ciphertext) MarshalBinary() (data []byte, err error)

MarshalBinary encodes a Ciphertext on a byte slice. The total size in byte is 4 + 8* N * numberModuliQ * (degree + 1).

func (*Ciphertext) ScalingFactor added in v2.2.0

func (ct *Ciphertext) ScalingFactor() float64

ScalingFactor returns the scaling factor of the ciphertext

func (*Ciphertext) SetScalingFactor added in v2.2.0

func (ct *Ciphertext) SetScalingFactor(scale float64)

SetScalingFactor sets the scaling factor of the ciphertext

func (*Ciphertext) UnmarshalBinary

func (ct *Ciphertext) UnmarshalBinary(data []byte) (err error)

UnmarshalBinary decodes a previously marshaled Ciphertext on the target Ciphertext.

type Decryptor

type Decryptor interface {
	DecryptNew(ciphertext *Ciphertext) (plaintext *Plaintext)
	Decrypt(ciphertext *Ciphertext, plaintext *Plaintext)
}

Decryptor is an interface wrapping a rlwe.Decryptor.

func NewDecryptor

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

NewDecryptor instantiates a Decryptor for the CKKS scheme.

type DomainSwitcher added in v2.4.0

type DomainSwitcher struct {
	rlwe.KeySwitcher

	*SwkComplexToReal
	*SwkRealToComplex
	// contains filtered or unexported fields
}

DomainSwitcher is a type for switching between the standard CKKS domain (which encrypts vectors of complex numbers) and the conjugate invariant variant of CKKS (which encrypts vectors of real numbers).

func NewDomainSwitcher added in v2.4.0

func NewDomainSwitcher(params Parameters, comlexToRealSwk *SwkComplexToReal, RealToComplexSwk *SwkRealToComplex) (DomainSwitcher, error)

NewDomainSwitcher instantiate a new DomainSwitcher type. It may be instantiated from parameters from either RingType. The method returns an error if the parameters cannot support the switching (e.g., the NTTs are undefined for either of the two ring types).

func (*DomainSwitcher) ComplexToReal added in v2.4.0

func (switcher *DomainSwitcher) ComplexToReal(ctIn, ctOut *Ciphertext)

ComplexToReal switches the provided ciphertext `ctIn` from the standard domain to the conjugate invariant domain and writes the result into `ctOut`. Given ctInCKKS = enc(real(m) + imag(m)) in Z[X](X^N + 1), returns ctOutCI = enc(real(m)) in Z[X+X^-1]/(X^N + 1) in compressed form (N/2 coefficients). The scale of the output ciphertext is twice the scale of the input one. Requires the ring degree of ctOut to be half the ring degree of ctIn. The security is changed from Z[X]/(X^N+1) to Z[X]/(X^N/2+1). The method panics if the DomainSwitcher was not initialized with a SwkComplexToReal key.

func (*DomainSwitcher) RealToComplex added in v2.4.0

func (switcher *DomainSwitcher) RealToComplex(ctIn, ctOut *Ciphertext)

RealToComplex switches the provided ciphertext `ctIn` from the conjugate invariant domain to the standard domain and writes the result into `ctOut`. Given ctInCI = enc(real(m)) in Z[X+X^-1]/(X^2N+1) in compressed form (N coefficients), returns ctOutCKKS = enc(real(m) + imag(0)) in Z[X]/(X^2N+1). Requires the ring degree of ctOut to be twice the ring degree of ctIn. The security is changed from Z[X]/(X^N+1) to Z[X]/(X^2N+1). The method panics if the DomainSwitcher was not initialized with a SwkRealToComplex key.

type Encoder

type Encoder interface {

	// Encode encodes a set of values on the target plaintext.
	// This method is identical to "EncodeSlots".
	// Encoding is done at the level and scale of the plaintext.
	// User must ensure that 1 <= len(values) <= 2^logSlots < 2^logN.
	// values.(type) can be either []complex128 of []float64.
	// The imaginary part of []complex128 will be discarded if ringType == ring.ConjugateInvariant.
	// Returned plaintext is always in the NTT domain.
	Encode(values interface{}, plaintext *Plaintext, logSlots int)

	// EncodeNew encodes a set of values on a new plaintext.
	// This method is identical to "EncodeSlotsNew".
	// Encoding is done at the provided level and with the provided scale.
	// User must ensure that 1 <= len(values) <= 2^logSlots < 2^logN.
	// values.(type) can be either []complex128 of []float64.
	// The imaginary part of []complex128 will be discarded if ringType == ring.ConjugateInvariant.
	// Returned plaintext is always in the NTT domain.
	EncodeNew(values interface{}, level int, scale float64, logSlots int) (plaintext *Plaintext)

	// EncodeSlots encodes a set of values on the target plaintext.
	// Encoding is done at the level and scale of the plaintext.
	// User must ensure that 1 <= len(values) <= 2^logSlots < 2^logN.
	// values.(type) can be either []complex128 of []float64.
	// The imaginary part of []complex128 will be discarded if ringType == ring.ConjugateInvariant.
	// Returned plaintext is always in the NTT domain.
	EncodeSlots(values interface{}, plaintext *Plaintext, logSlots int)

	// EncodeSlotsNew encodes a set of values on a new plaintext.
	// Encoding is done at the provided level and with the provided scale.
	// User must ensure that 1 <= len(values) <= 2^logSlots < 2^logN.
	// values.(type) can be either []complex128 of []float64.
	// The imaginary part of []complex128 will be discarded if ringType == ring.ConjugateInvariant.
	// Returned plaintext is always in the NTT domain.
	EncodeSlotsNew(values interface{}, level int, scale float64, logSlots int) (plaintext *Plaintext)

	// Decode decodes the input plaintext on a new slice of complex128.
	Decode(plaintext *Plaintext, logSlots int) (res []complex128)

	// DecodeSlots decodes the input plaintext on a new slice of complex128.
	DecodeSlots(plaintext *Plaintext, logSlots int) (res []complex128)

	// DecodePublic decodes the input plaintext on a new slice of complex128.
	// Adds, before the decoding step, an error with standard deviation sigma.
	// If the underlying ringType is ConjugateInvariant, the imaginary part (and
	// its related error) are zero.
	DecodePublic(plaintext *Plaintext, logSlots int, sigma float64) []complex128

	// DecodeSlotsPublic decodes the input plaintext on a new slice of complex128.
	// Adds, before the decoding step, an error with standard deviation sigma.
	// If the underlying ringType is ConjugateInvariant, the imaginary part (and
	// its related error) are zero.
	DecodeSlotsPublic(plaintext *Plaintext, logSlots int, sigma float64) []complex128

	// EncodeCoeffs encodes the values on the coefficient of the plaintext.
	// Encoding is done at the level and scale of the plaintext.
	// User must ensure that 1<= len(values) <= 2^LogN
	EncodeCoeffs(values []float64, plaintext *Plaintext)

	// EncodeCoeffsNew encodes the values on the coefficient of a new plaintext.
	// Encoding is done at the provided level and with the provided scale.
	// User must ensure that 1<= len(values) <= 2^LogN
	EncodeCoeffsNew(values []float64, level int, scale float64) (plaintext *Plaintext)

	// DecodeCoeffs reconstructs the RNS coefficients of the plaintext on a slice of float64.
	DecodeCoeffs(plaintext *Plaintext) (res []float64)

	// DecodeCoeffsPublic reconstructs the RNS coefficients of the plaintext on a slice of float64.
	// Adds an error with standard deviation sigma.
	DecodeCoeffsPublic(plaintext *Plaintext, bound float64) (res []float64)

	// GetErrSTDCoeffDomain returns StandardDeviation(Encode(valuesWant-valuesHave))*scale
	// Which is the scaled standard deviation in the coefficient domain of the difference
	// of two complex vector in the slot domain.
	GetErrSTDCoeffDomain(valuesWant, valuesHave []complex128, scale float64) (std float64)

	// GetErrSTDSlotDomain returns StandardDeviation(valuesWant-valuesHave)*scale
	// Which is the scaled standard deviation of two complex vectors.
	GetErrSTDSlotDomain(valuesWant, valuesHave []complex128, scale float64) (std float64)
}

Encoder is an interface that implements the encoding and decoding operations. It provides methods to encode/decode []complex128 and []float64 types into/from Plaintext types. Two different encodings are provided:

  • Coeffs: The coefficients are directly embedded on the plaintext. This encoding only allows to encode []float64 slices, but of size up to N (N being the ring degree) and does not preserve the point-wise multiplication. A ciphertext multiplication will result in a nega- cyclic polynomial convolution in the plaintext domain. This encoding does not provide native slot cyclic rotation. Other operations, like addition or constant multiplication, behave as usual.

  • Slots: The coefficients are first subjected to a special Fourier transform before being embedded in the plaintext by using Coeffs encoding. This encoding can embed []complex128 and []float64 slices of size at most N/2 (N being the ring degree) and leverages the convolution property of the DFT to preserve point-wise complex multiplication in the plaintext domain, i.e. a ciphertext multiplication will result in an element-wise multiplication in the plaintext domain. It also enables cyclic rotations on plaintext slots. Other operations, like constant multiplication, behave as usual. It is considered the default encoding method for CKKS.

The figure bellow illustrates the relationship between these two encodings:

Real^{N}          Z_Q[X]/(X^N+1)

EncodeCoeffs: ----------------------------->[]float64 ---------> Plaintext

                             |
Complex^{N/2}                |

EncodeSlots: []complex128/[]float64 -> iDFT ---┘

func NewEncoder

func NewEncoder(params Parameters) Encoder

NewEncoder creates a new Encoder that is used to encode a slice of complex values of size at most N/2 (the number of slots) on a Plaintext.

type EncoderBigComplex

type EncoderBigComplex interface {

	// Encode encodes a set of values on the target plaintext.
	// Encoding is done at the level and scale of the plaintext.
	// User must ensure that 1 <= len(values) <= 2^logSlots < 2^LogN.
	Encode(values []*ring.Complex, plaintext *Plaintext, logSlots int)

	// EncodeNew encodes a set of values on a new plaintext.
	// Encoding is done at the provided level and with the provided scale.
	// User must ensure that 1 <= len(values) <= 2^logSlots < 2^LogN.
	EncodeNew(values []*ring.Complex, level int, scale float64, logSlots int) (plaintext *Plaintext)

	// Decode decodes the input plaintext on a new slice of ring.Complex.
	Decode(plaintext *Plaintext, logSlots int) (res []*ring.Complex)

	// FFT evaluates the decoding matrix on a slice of ring.Complex values.
	FFT(values []*ring.Complex, N int)

	// InvFFT evaluates the encoding matrix on a slice of ring.Complex values.
	InvFFT(values []*ring.Complex, N int)
}

EncoderBigComplex is an interface that implements the encoding algorithms with arbitrary precision.

func NewEncoderBigComplex

func NewEncoderBigComplex(params Parameters, logPrecision int) EncoderBigComplex

NewEncoderBigComplex creates a new encoder using arbitrary precision complex arithmetic.

type Encryptor

type Encryptor interface {
	Encrypt(plaintext *Plaintext, ciphertext *Ciphertext)
	EncryptNew(plaintext *Plaintext) *Ciphertext
	EncryptFromCRP(plaintext *Plaintext, crp *ring.Poly, ciphertext *Ciphertext)
	EncryptFromCRPNew(plaintext *Plaintext, crp *ring.Poly) *Ciphertext
}

Encryptor an encryption interface for the CKKS scheme.

func NewEncryptor added in v2.2.0

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

NewEncryptor instantiates a new Encryptor for the CKKS scheme. The key argument can be either a *rlwe.PublicKey or a *rlwe.SecretKey.

func NewFastEncryptor added in v2.2.0

func NewFastEncryptor(params Parameters, key *rlwe.PublicKey) Encryptor

NewFastEncryptor instantiates a new Encryptor for the CKKS scheme. This encryptor's Encrypt method first encrypts zero in Q and then adds the plaintext. This method is faster than the normal encryptor but result in a noisier ciphertext.

type Evaluator

type Evaluator interface {

	// Addition
	Add(op0, op1 Operand, ctOut *Ciphertext)
	AddNoMod(op0, op1 Operand, ctOut *Ciphertext)
	AddNew(op0, op1 Operand) (ctOut *Ciphertext)
	AddNoModNew(op0, op1 Operand) (ctOut *Ciphertext)

	// Subtraction
	Sub(op0, op1 Operand, ctOut *Ciphertext)
	SubNoMod(op0, op1 Operand, ctOut *Ciphertext)
	SubNew(op0, op1 Operand) (ctOut *Ciphertext)
	SubNoModNew(op0, op1 Operand) (ctOut *Ciphertext)

	// Negation
	Neg(ctIn *Ciphertext, ctOut *Ciphertext)
	NegNew(ctIn *Ciphertext) (ctOut *Ciphertext)

	// Constant Addition
	AddConstNew(ctIn *Ciphertext, constant interface{}) (ctOut *Ciphertext)
	AddConst(ctIn *Ciphertext, constant interface{}, ctOut *Ciphertext)

	// Constant Multiplication
	MultByConstNew(ctIn *Ciphertext, constant interface{}) (ctOut *Ciphertext)
	MultByConst(ctIn *Ciphertext, constant interface{}, ctOut *Ciphertext)
	MultByGaussianInteger(ctIn *Ciphertext, cReal, cImag interface{}, ctOut *Ciphertext)

	// Constant Multiplication with Addition
	MultByConstAndAdd(ctIn *Ciphertext, constant interface{}, ctOut *Ciphertext)
	MultByGaussianIntegerAndAdd(ctIn *Ciphertext, cReal, cImag interface{}, ctOut *Ciphertext)

	// Multiplication by the imaginary unit
	MultByiNew(ctIn *Ciphertext) (ctOut *Ciphertext)
	MultByi(ctIn *Ciphertext, ctOut *Ciphertext)
	DivByiNew(ctIn *Ciphertext) (ctOut *Ciphertext)
	DivByi(ctIn *Ciphertext, ctOut *Ciphertext)

	// Conjugation
	ConjugateNew(ctIn *Ciphertext) (ctOut *Ciphertext)
	Conjugate(ctIn *Ciphertext, ctOut *Ciphertext)

	// Multiplication
	Mul(op0, op1 Operand, ctOut *Ciphertext)
	MulNew(op0, op1 Operand) (ctOut *Ciphertext)
	MulRelin(op0, op1 Operand, ctOut *Ciphertext)
	MulRelinNew(op0, op1 Operand) (ctOut *Ciphertext)

	MulAndAdd(op0, op1 Operand, ctOut *Ciphertext)
	MulRelinAndAdd(op0, op1 Operand, ctOut *Ciphertext)

	// Slot Rotations
	RotateNew(ctIn *Ciphertext, k int) (ctOut *Ciphertext)
	Rotate(ctIn *Ciphertext, k int, ctOut *Ciphertext)
	RotateHoistedNew(ctIn *Ciphertext, rotations []int) (ctOut map[int]*Ciphertext)
	RotateHoisted(ctIn *Ciphertext, rotations []int, ctOut map[int]*Ciphertext)
	RotateHoistedNoModDownNew(level int, rotations []int, c0 *ring.Poly, c2DecompQP []rlwe.PolyQP) (cOut map[int][2]rlwe.PolyQP)
	PermuteNTTHoisted(level int, c0, c1 *ring.Poly, c2DecompQP []rlwe.PolyQP, k int, cOut0, cOut1 *ring.Poly)
	PermuteNTTHoistedNoModDown(level int, c0 *ring.Poly, c2DecompQP []rlwe.PolyQP, k int, ct0OutQ, ct1OutQ, ct0OutP, ct1OutP *ring.Poly)

	// Multiplication by 2^{s}
	MulByPow2New(ctIn *Ciphertext, pow2 int) (ctOut *Ciphertext)
	MulByPow2(ctIn *Ciphertext, pow2 int, ctOut *Ciphertext)

	// Exponentiation
	PowerOf2(ctIn *Ciphertext, logPow2 int, ctOut *Ciphertext)
	Power(ctIn *Ciphertext, degree int, ctOut *Ciphertext)
	PowerNew(ctIn *Ciphertext, degree int) (ctOut *Ciphertext)

	// Polynomial evaluation
	EvaluatePoly(ctIn *Ciphertext, pol *Polynomial, targetScale float64) (ctOut *Ciphertext, err error)
	EvaluatePolyVector(ctIn *Ciphertext, pols []*Polynomial, encoder Encoder, slotIndex map[int][]int, targetScale float64) (ctOut *Ciphertext, err error)

	// Inversion
	InverseNew(ctIn *Ciphertext, steps int) (ctOut *Ciphertext)

	// Linear Transformations
	LinearTransformNew(ctIn *Ciphertext, linearTransform interface{}) (ctOut []*Ciphertext)
	LinearTransform(ctIn *Ciphertext, linearTransform interface{}, ctOut []*Ciphertext)
	MultiplyByDiagMatrix(ctIn *Ciphertext, matrix LinearTransform, c2DecompQP []rlwe.PolyQP, ctOut *Ciphertext)
	MultiplyByDiagMatrixBSGS(ctIn *Ciphertext, matrix LinearTransform, c2DecompQP []rlwe.PolyQP, ctOut *Ciphertext)

	// Inner sum
	InnerSumLog(ctIn *Ciphertext, batch, n int, ctOut *Ciphertext)
	InnerSum(ctIn *Ciphertext, batch, n int, ctOut *Ciphertext)
	Average(ctIn *Ciphertext, batch int, ctOut *Ciphertext)

	// Replication (inverse of Inner sum)
	ReplicateLog(ctIn *Ciphertext, batch, n int, ctOut *Ciphertext)
	Replicate(ctIn *Ciphertext, batch, n int, ctOut *Ciphertext)

	// Trace
	Trace(ctIn *Ciphertext, logSlotsStart, logSlotsEnd int, ctOut *Ciphertext)
	TraceNew(ctIn *Ciphertext, logSlotsStart, logSlotsEnd int) (ctOut *Ciphertext)

	// Key-Switching
	SwitchKeysNew(ctIn *Ciphertext, switchingKey *rlwe.SwitchingKey) (ctOut *Ciphertext)
	SwitchKeys(ctIn *Ciphertext, switchingKey *rlwe.SwitchingKey, ctOut *Ciphertext)

	// Degree Management
	RelinearizeNew(ctIn *Ciphertext) (ctOut *Ciphertext)
	Relinearize(ctIn *Ciphertext, ctOut *Ciphertext)

	// Scale Management
	ScaleUpNew(ctIn *Ciphertext, scale float64) (ctOut *Ciphertext)
	ScaleUp(ctIn *Ciphertext, scale float64, ctOut *Ciphertext)
	SetScale(ctIn *Ciphertext, scale float64)
	Rescale(ctIn *Ciphertext, minScale float64, ctOut *Ciphertext) (err error)

	// Level Management
	DropLevelNew(ctIn *Ciphertext, levels int) (ctOut *Ciphertext)
	DropLevel(ctIn *Ciphertext, levels int)

	// Modular Overflow Management
	ReduceNew(ctIn *Ciphertext) (ctOut *Ciphertext)
	Reduce(ctIn *Ciphertext, ctOut *Ciphertext) error

	// ==============
	// === Others ===
	// ==============
	GetKeySwitcher() *rlwe.KeySwitcher
	PoolQMul() [3]*ring.Poly
	CtxPool() *Ciphertext
	ShallowCopy() Evaluator
	WithKey(rlwe.EvaluationKey) Evaluator
}

Evaluator is an interface implementing the methods to conduct homomorphic operations between ciphertext and/or plaintexts.

func NewEvaluator

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

NewEvaluator creates a new Evaluator, that can be used to do homomorphic operations on the Ciphertexts and/or Plaintexts. It stores a small pool of polynomials and Ciphertexts that will be used for intermediate values.

type KeyGenerator

type KeyGenerator interface {
	rlwe.KeyGenerator
	GenSwitchingKeysForBridge(skCKKS, skCI *rlwe.SecretKey) (*SwkComplexToReal, *SwkRealToComplex)
}

KeyGenerator is an interface for the generation of CKKS keys.

func NewKeyGenerator

func NewKeyGenerator(params Parameters) KeyGenerator

NewKeyGenerator creates a rlwe.KeyGenerator instance from the CKKS parameters.

type LinearTransform added in v2.4.0

type LinearTransform struct {
	LogSlots int                 // Log of the number of slots of the plaintext (needed to compute the appropriate rotation keys)
	N1       int                 // N1 is the number of inner loops of the baby-step giant-step algorithm used in the evaluation (if N1 == 0, BSGS is not used).
	Level    int                 // Level is the level at which the matrix is encoded (can be circuit dependent)
	Scale    float64             // Scale is the scale at which the matrix is encoded (can be circuit dependent)
	Vec      map[int]rlwe.PolyQP // Vec is the matrix, in diagonal form, where each entry of vec is an indexed non-zero diagonal.
}

LinearTransform is a type for linear transformations on ciphertexts. It stores a plaintext matrix diagonalized in diagonal form and can be evaluated on a ciphertext by using the evaluator.LinearTransform method.

func GenLinearTransform added in v2.4.0

func GenLinearTransform(encoder Encoder, value interface{}, level int, scale float64, logslots int) LinearTransform

GenLinearTransform allocates and encode a new LinearTransform struct from the linear transforms' matrix in diagonal form `value`. values.(type) can be either map[int][]complex128 or map[int][]float64. User must ensure that 1 <= len([]complex128\[]float64) <= 2^logSlots < 2^logN. It can then be evaluated on a ciphertext using evaluator.LinearTransform. Evaluation will use the naive approach (single hoisting and no baby-step giant-step). Faster if there is only a few non-zero diagonals but uses more keys.

func GenLinearTransformBSGS added in v2.4.0

func GenLinearTransformBSGS(encoder Encoder, value interface{}, level int, scale, BSGSRatio float64, logSlots int) (LT LinearTransform)

GenLinearTransformBSGS allocates and encodes a new LinearTransform struct from the linear transforms' matrix in diagonal form `value` for evaluation with a baby-step giant-step approach. values.(type) can be either map[int][]complex128 or map[int][]float64. User must ensure that 1 <= len([]complex128\[]float64) <= 2^logSlots < 2^logN. LinearTransform types can be be evaluated on a ciphertext using evaluator.LinearTransform. Evaluation will use the optimized approach (double hoisting and baby-step giant-step). Faster if there is more than a few non-zero diagonals. BSGSRatio is the maximum ratio between the inner and outer loop of the baby-step giant-step algorithm used in evaluator.LinearTransform. Optimal BSGSRatio value is between 4 and 16 depending on the sparsity of the matrix.

func NewLinearTransform added in v2.4.0

func NewLinearTransform(params Parameters, nonZeroDiags []int, level, logSlots int, BSGSRatio float64) LinearTransform

NewLinearTransform allocates a new LinearTransform with zero plaintexts at the specified level. If BSGSRatio == 0, the LinearTransform is set to not use the BSGS approach. Method will panic if BSGSRatio < 0.

func (*LinearTransform) Encode added in v2.4.0

func (LT *LinearTransform) Encode(encoder Encoder, value interface{}, scale float64)

Encode encodes on a pre-allocated LinearTransform the linear transforms' matrix in diagonal form `value`. values.(type) can be either map[int][]complex128 or map[int][]float64. User must ensure that 1 <= len([]complex128\[]float64) <= 2^logSlots < 2^logN. It can then be evaluated on a ciphertext using evaluator.LinearTransform. Evaluation will use the naive approach (single hoisting and no baby-step giant-step). Faster if there is only a few non-zero diagonals but uses more keys.

func (*LinearTransform) Rotations added in v2.4.0

func (LT *LinearTransform) Rotations() (rotations []int)

Rotations returns the list of rotations needed for the evaluation of the linear transform.

type Operand

type Operand interface {
	El() *rlwe.Ciphertext
	Degree() int
	Level() int
	ScalingFactor() float64
	SetScalingFactor(float64)
}

Operand is a common interface for Ciphertext and Plaintext types.

type Parameters

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

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

func NewParameters added in v2.2.0

func NewParameters(rlweParams rlwe.Parameters, logSlot int, defaultScale float64) (p Parameters, err error)

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

func NewParametersFromLiteral added in v2.2.0

func NewParametersFromLiteral(pl ParametersLiteral) (Parameters, error)

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

func (Parameters) CopyNew added in v2.2.0

func (p Parameters) CopyNew() Parameters

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

func (Parameters) DefaultScale added in v2.4.0

func (p Parameters) DefaultScale() float64

DefaultScale returns the default plaintext/ciphertext scale

func (Parameters) Equals

func (p Parameters) Equals(other Parameters) bool

Equals compares two sets of parameters for equality.

func (Parameters) LogQLvl

func (p Parameters) LogQLvl(level int) int

LogQLvl returns the size of the modulus Q in bits at a specific level

func (Parameters) LogSlots

func (p Parameters) LogSlots() int

LogSlots returns the log of the number of slots

func (Parameters) MarshalBinary

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

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

func (Parameters) MarshalBinarySize added in v2.2.0

func (p Parameters) MarshalBinarySize() int

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

func (Parameters) MarshalJSON added in v2.2.0

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

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

func (Parameters) MaxLevel

func (p Parameters) MaxLevel() int

MaxLevel returns the maximum ciphertext level

func (Parameters) MaxLogSlots

func (p Parameters) MaxLogSlots() int

MaxLogSlots returns the log of the maximum number of slots enabled by the parameters

func (Parameters) MaxSlots

func (p Parameters) MaxSlots() int

MaxSlots returns the theoretical maximum of plaintext slots allowed by the ring degree

func (Parameters) QLvl

func (p Parameters) QLvl(level int) *big.Int

QLvl returns the product of the moduli at the given level as a big.Int

func (Parameters) RotationsForInnerSum added in v2.2.0

func (p Parameters) RotationsForInnerSum(batch, n int) (rotations []int)

RotationsForInnerSum generates the rotations that will be performed by the `Evaluator.InnerSum` operation when performed with parameters `batch` and `n`.

func (Parameters) RotationsForInnerSumLog added in v2.2.0

func (p Parameters) RotationsForInnerSumLog(batch, n int) (rotations []int)

RotationsForInnerSumLog generates the rotations that will be performed by the `Evaluator.InnerSumLog` operation when performed with parameters `batch` and `n`.

func (Parameters) RotationsForLinearTransform added in v2.4.0

func (p Parameters) RotationsForLinearTransform(nonZeroDiags interface{}, logSlots int, BSGSratio float64) (rotations []int)

RotationsForLinearTransform generates the list of rotations needed for the evaluation of a linear transform with the provided list of non-zero diagonals, logSlots encoding and BSGSratio. If BSGSratio == 0, then provides the rotations needed for an evaluation without the BSGS approach.

func (Parameters) RotationsForReplicate added in v2.2.0

func (p Parameters) RotationsForReplicate(batch, n int) (rotations []int)

RotationsForReplicate generates the rotations that will be performed by the `Evaluator.Replicate` operation when performed with parameters `batch` and `n`.

func (Parameters) RotationsForReplicateLog added in v2.2.0

func (p Parameters) RotationsForReplicateLog(batch, n int) (rotations []int)

RotationsForReplicateLog generates the rotations that will be performed by the `Evaluator.ReplicateLog` operation when performed with parameters `batch` and `n`.

func (Parameters) RotationsForTrace added in v2.3.0

func (p Parameters) RotationsForTrace(logSlotsStart, logSlotsEnd int) (rotations []int)

RotationsForTrace generates the rotations that will be performed by the `Evaluator.SubSum` operation.

func (Parameters) Slots

func (p Parameters) Slots() int

Slots returns number of available plaintext slots

func (Parameters) StandardParameters added in v2.4.0

func (p Parameters) StandardParameters() (pckks Parameters, err error)

StandardParameters returns the CKKS parameters corresponding to the receiver parameter set. If the receiver is already a standard parameter set (i.e., RingType==Standard), then the method returns the receiver.

func (*Parameters) UnmarshalBinary

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

UnmarshalBinary decodes a []byte into a parameter set struct

func (*Parameters) UnmarshalJSON added in v2.2.0

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 added in v2.2.0

type ParametersLiteral struct {
	LogN         int // Ring degree (power of 2)
	Q            []uint64
	P            []uint64
	LogQ         []int   `json:",omitempty"`
	LogP         []int   `json:",omitempty"`
	Sigma        float64 // Gaussian sampling variance
	LogSlots     int
	DefaultScale float64
	RingType     ring.Type
}

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.

type Plaintext

type Plaintext struct {
	*rlwe.Plaintext
	Scale float64
}

Plaintext is is a Element with only one Poly.

func NewPlaintext

func NewPlaintext(params Parameters, level int, scale float64) *Plaintext

NewPlaintext creates a new Plaintext of level level and scale scale.

func NewPlaintextAtLevelFromPoly added in v2.3.0

func NewPlaintextAtLevelFromPoly(level int, poly *ring.Poly) *Plaintext

NewPlaintextAtLevelFromPoly construct a new Plaintext at a specific level where the message is set to the passed poly. No checks are performed on poly and the returned Plaintext will share its backing array of coefficient.

func (*Plaintext) ScalingFactor added in v2.2.0

func (p *Plaintext) ScalingFactor() float64

ScalingFactor returns the scaling factor of the plaintext

func (*Plaintext) SetScalingFactor added in v2.2.0

func (p *Plaintext) SetScalingFactor(scale float64)

SetScalingFactor sets the scaling factor of the target plaintext

type Polynomial added in v2.3.0

type Polynomial struct {
	MaxDeg int
	Coeffs []complex128
	Lead   bool
	A      float64
	B      float64
	Basis  PolynomialBasis
}

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

func Approximate

func Approximate(function interface{}, a, b float64, degree int) (pol *Polynomial)

Approximate computes a Chebyshev approximation of the input function, for the range [-a, b] of degree degree. function.(type) can be either func(complex128)complex128 or func(float64)float64 To be used in conjunction with the function EvaluateCheby.

func NewPoly

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

NewPoly creates a new Poly from the input coefficients

func (*Polynomial) Degree added in v2.3.0

func (p *Polynomial) Degree() int

Degree returns the degree of the polynomial

func (*Polynomial) Depth added in v2.3.0

func (p *Polynomial) Depth() int

Depth returns the number of levels needed to evaluate the polynomial.

type PolynomialBasis added in v2.3.0

type PolynomialBasis int

PolynomialBasis is a type for the polynomials basis

type PrecisionStats

type PrecisionStats struct {
	MaxDelta        Stats
	MinDelta        Stats
	MaxPrecision    Stats
	MinPrecision    Stats
	MeanDelta       Stats
	MeanPrecision   Stats
	MedianDelta     Stats
	MedianPrecision Stats
	STDFreq         float64
	STDTime         float64

	RealDist, ImagDist, L2Dist []struct {
		Prec  float64
		Count int
	}
	// contains filtered or unexported fields
}

PrecisionStats is a struct storing statistic about the precision of a CKKS plaintext

func GetPrecisionStats

func GetPrecisionStats(params Parameters, encoder Encoder, decryptor Decryptor, vWant, element interface{}, logSlots int, sigma float64) (prec PrecisionStats)

GetPrecisionStats generates a PrecisionStats struct from the reference values and the decrypted values vWant.(type) must be either []complex128 or []float64 element.(type) must be either *Plaintext, *Ciphertext, []complex128 or []float64. If not *Ciphertext, then decryptor can be nil.

func (PrecisionStats) String

func (prec PrecisionStats) String() string

type Stats added in v2.3.0

type Stats struct {
	Real, Imag, L2 float64
}

Stats is a struct storing the real, imaginary and L2 norm (modulus) about the precision of a complex value.

type SwkComplexToReal added in v2.4.0

type SwkComplexToReal struct {
	rlwe.SwitchingKey
}

SwkComplexToReal is a SwitchingKey to switch from the standard domain to the conjugate invariant domain.

type SwkRealToComplex added in v2.4.0

type SwkRealToComplex struct {
	rlwe.SwitchingKey
}

SwkRealToComplex is a SwitchingKey to switch from the conjugate invariant domain to the standard domain.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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