mirror of
https://github.com/tuneinsight/lattigo.git
synced 2025-09-13 03:27:14 +00:00
Replaced some errors when allocating structs or generating keys by panics when irrecoverable
This commit is contained in:
@@ -42,13 +42,13 @@ func NewCiphertext(params Parameters, degree int, level ...int) (ct *rlwe.Cipher
|
||||
|
||||
// NewEncryptor instantiates a new rlwe.Encryptor from the given BFV parameters and
|
||||
// encryption key. This key can be either a *rlwe.SecretKey or a *rlwe.PublicKey.
|
||||
func NewEncryptor(params Parameters, key rlwe.EncryptionKey) (*rlwe.Encryptor, error) {
|
||||
func NewEncryptor(params Parameters, key rlwe.EncryptionKey) *rlwe.Encryptor {
|
||||
return rlwe.NewEncryptor(params, key)
|
||||
}
|
||||
|
||||
// NewDecryptor instantiates a new rlwe.Decryptor from the given BFV parameters and
|
||||
// secret decryption key.
|
||||
func NewDecryptor(params Parameters, key *rlwe.SecretKey) (*rlwe.Decryptor, error) {
|
||||
func NewDecryptor(params Parameters, key *rlwe.SecretKey) *rlwe.Decryptor {
|
||||
return rlwe.NewDecryptor(params, key)
|
||||
}
|
||||
|
||||
|
||||
@@ -103,25 +103,10 @@ func genTestParams(params Parameters) (tc *testContext, err error) {
|
||||
tc.sk, tc.pk = tc.kgen.GenKeyPairNew()
|
||||
tc.encoder = NewEncoder(tc.params)
|
||||
|
||||
if tc.encryptorPk, err = NewEncryptor(tc.params, tc.pk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.encryptorSk, err = NewEncryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.decryptor, err = NewDecryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var rlk *rlwe.RelinearizationKey
|
||||
if rlk, err = tc.kgen.GenRelinearizationKeyNew(tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
evk := rlwe.NewMemEvaluationKeySet(rlk)
|
||||
tc.evaluator = NewEvaluator(tc.params, evk)
|
||||
tc.encryptorPk = NewEncryptor(tc.params, tc.pk)
|
||||
tc.encryptorSk = NewEncryptor(tc.params, tc.sk)
|
||||
tc.decryptor = NewDecryptor(tc.params, tc.sk)
|
||||
tc.evaluator = NewEvaluator(tc.params, rlwe.NewMemEvaluationKeySet(tc.kgen.GenRelinearizationKeyNew(tc.sk)))
|
||||
|
||||
tc.testLevel = []int{0, params.MaxLevel()}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ func NewCiphertext(params Parameters, degree, level int) (ct *rlwe.Ciphertext) {
|
||||
// - key: *rlwe.SecretKey or *rlwe.PublicKey
|
||||
//
|
||||
// output: an rlwe.Encryptor instantiated with the provided key.
|
||||
func NewEncryptor(params Parameters, key rlwe.EncryptionKey) (*rlwe.Encryptor, error) {
|
||||
func NewEncryptor(params Parameters, key rlwe.EncryptionKey) *rlwe.Encryptor {
|
||||
return rlwe.NewEncryptor(params, key)
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ func NewEncryptor(params Parameters, key rlwe.EncryptionKey) (*rlwe.Encryptor, e
|
||||
// - key: *rlwe.SecretKey
|
||||
//
|
||||
// output: an rlwe.Decryptor instantiated with the provided key.
|
||||
func NewDecryptor(params Parameters, key *rlwe.SecretKey) (*rlwe.Decryptor, error) {
|
||||
func NewDecryptor(params Parameters, key *rlwe.SecretKey) *rlwe.Decryptor {
|
||||
return rlwe.NewDecryptor(params, key)
|
||||
}
|
||||
|
||||
|
||||
@@ -111,25 +111,10 @@ func genTestParams(params Parameters) (tc *testContext, err error) {
|
||||
tc.sk, tc.pk = tc.kgen.GenKeyPairNew()
|
||||
tc.encoder = NewEncoder(tc.params)
|
||||
|
||||
if tc.encryptorPk, err = NewEncryptor(tc.params, tc.pk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.encryptorSk, err = NewEncryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.decryptor, err = NewDecryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var rlk *rlwe.RelinearizationKey
|
||||
if rlk, err = tc.kgen.GenRelinearizationKeyNew(tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
evk := rlwe.NewMemEvaluationKeySet(rlk)
|
||||
tc.evaluator = NewEvaluator(tc.params, evk)
|
||||
tc.encryptorPk = NewEncryptor(tc.params, tc.pk)
|
||||
tc.encryptorSk = NewEncryptor(tc.params, tc.sk)
|
||||
tc.decryptor = NewDecryptor(tc.params, tc.sk)
|
||||
tc.evaluator = NewEvaluator(tc.params, rlwe.NewMemEvaluationKeySet(tc.kgen.GenRelinearizationKeyNew(tc.sk)))
|
||||
|
||||
tc.testLevel = []int{0, params.MaxLevel()}
|
||||
|
||||
@@ -144,7 +129,9 @@ func newTestVectorsLvl(level int, scale rlwe.Scale, tc *testContext, encryptor *
|
||||
|
||||
plaintext = NewPlaintext(tc.params, level)
|
||||
plaintext.Scale = scale
|
||||
tc.encoder.Encode(coeffs.Coeffs[0], plaintext)
|
||||
if err := tc.encoder.Encode(coeffs.Coeffs[0], plaintext); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if encryptor != nil {
|
||||
var err error
|
||||
ciphertext, err = encryptor.EncryptNew(plaintext)
|
||||
|
||||
@@ -135,10 +135,7 @@ func testLinearTransformation(tc *testContext, t *testing.T) {
|
||||
|
||||
galEls := GaloisElementsForLinearTransformation(params, ltparams)
|
||||
|
||||
gks, err := tc.kgen.GenGaloisKeysNew(galEls, tc.sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
ltEval := NewEvaluator(tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(nil, gks...)))
|
||||
ltEval := NewEvaluator(tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(nil, tc.kgen.GenGaloisKeysNew(galEls, tc.sk)...)))
|
||||
|
||||
require.NoError(t, ltEval.LinearTransformation(ciphertext, linTransf, ciphertext))
|
||||
|
||||
@@ -207,10 +204,7 @@ func testLinearTransformation(tc *testContext, t *testing.T) {
|
||||
|
||||
galEls := GaloisElementsForLinearTransformation(params, ltparams)
|
||||
|
||||
gks, err := tc.kgen.GenGaloisKeysNew(galEls, tc.sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
ltEval := NewEvaluator(tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(nil, gks...)))
|
||||
ltEval := NewEvaluator(tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(nil, tc.kgen.GenGaloisKeysNew(galEls, tc.sk)...)))
|
||||
|
||||
require.NoError(t, ltEval.LinearTransformation(ciphertext, linTransf, ciphertext))
|
||||
|
||||
@@ -343,25 +337,10 @@ func genTestParams(params bfv.Parameters) (tc *testContext, err error) {
|
||||
tc.sk, tc.pk = tc.kgen.GenKeyPairNew()
|
||||
tc.encoder = bgv.NewEncoder(bgv.Parameters(tc.params.Parameters))
|
||||
|
||||
if tc.encryptorPk, err = bfv.NewEncryptor(tc.params, tc.pk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.encryptorSk, err = bfv.NewEncryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.decryptor, err = bfv.NewDecryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var rlk *rlwe.RelinearizationKey
|
||||
if rlk, err = tc.kgen.GenRelinearizationKeyNew(tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
evk := rlwe.NewMemEvaluationKeySet(rlk)
|
||||
tc.evaluator = bfv.NewEvaluator(tc.params, evk)
|
||||
tc.encryptorPk = bfv.NewEncryptor(tc.params, tc.pk)
|
||||
tc.encryptorSk = bfv.NewEncryptor(tc.params, tc.sk)
|
||||
tc.decryptor = bfv.NewDecryptor(tc.params, tc.sk)
|
||||
tc.evaluator = bfv.NewEvaluator(tc.params, rlwe.NewMemEvaluationKeySet(tc.kgen.GenRelinearizationKeyNew(tc.sk)))
|
||||
|
||||
tc.testLevel = []int{0, params.MaxLevel()}
|
||||
|
||||
|
||||
@@ -127,10 +127,8 @@ func testHomomorphicEncoding(params ckks.Parameters, LogSlots int, t *testing.T)
|
||||
kgen := ckks.NewKeyGenerator(params)
|
||||
sk := kgen.GenSecretKeyNew()
|
||||
encoder := ckks.NewEncoder(params, 90) // Required to force roots.(type) to be []*bignum.Complex instead of []complex128
|
||||
encryptor, err := ckks.NewEncryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
decryptor, err := ckks.NewDecryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
encryptor := ckks.NewEncryptor(params, sk)
|
||||
decryptor := ckks.NewDecryptor(params, sk)
|
||||
|
||||
// Generates the encoding matrices
|
||||
CoeffsToSlotMatrices, err := NewHomomorphicDFTMatrixFromLiteral(params, CoeffsToSlotsParametersLiteral, encoder)
|
||||
@@ -140,11 +138,8 @@ func testHomomorphicEncoding(params ckks.Parameters, LogSlots int, t *testing.T)
|
||||
galEls := append(CoeffsToSlotsParametersLiteral.GaloisElements(params), params.GaloisElementOrderTwoOrthogonalSubgroup())
|
||||
|
||||
// Generates and adds the keys
|
||||
gks, err := kgen.GenGaloisKeysNew(galEls, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Instantiates the EvaluationKeySet
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, gks...)
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, kgen.GenGaloisKeysNew(galEls, sk)...)
|
||||
|
||||
// Creates an evaluator with the rotation keys
|
||||
eval := ckks.NewEvaluator(params, evk)
|
||||
@@ -336,10 +331,8 @@ func testHomomorphicDecoding(params ckks.Parameters, LogSlots int, t *testing.T)
|
||||
kgen := ckks.NewKeyGenerator(params)
|
||||
sk := kgen.GenSecretKeyNew()
|
||||
encoder := ckks.NewEncoder(params)
|
||||
encryptor, err := ckks.NewEncryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
decryptor, err := ckks.NewDecryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
encryptor := ckks.NewEncryptor(params, sk)
|
||||
decryptor := ckks.NewDecryptor(params, sk)
|
||||
|
||||
// Generates the encoding matrices
|
||||
SlotsToCoeffsMatrix, err := NewHomomorphicDFTMatrixFromLiteral(params, SlotsToCoeffsParametersLiteral, encoder)
|
||||
@@ -349,11 +342,8 @@ func testHomomorphicDecoding(params ckks.Parameters, LogSlots int, t *testing.T)
|
||||
galEls := append(SlotsToCoeffsParametersLiteral.GaloisElements(params), params.GaloisElementOrderTwoOrthogonalSubgroup())
|
||||
|
||||
// Generates and adds the keys
|
||||
gks, err := kgen.GenGaloisKeysNew(galEls, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Instantiates the EvaluationKeySet
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, gks...)
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, kgen.GenGaloisKeysNew(galEls, sk)...)
|
||||
|
||||
// Creates an evaluator with the rotation keys
|
||||
eval := ckks.NewEvaluator(params, evk)
|
||||
|
||||
@@ -72,17 +72,9 @@ func testEvalMod(params ckks.Parameters, t *testing.T) {
|
||||
kgen := ckks.NewKeyGenerator(params)
|
||||
sk := kgen.GenSecretKeyNew()
|
||||
encoder := ckks.NewEncoder(params)
|
||||
encryptor, err := ckks.NewEncryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
decryptor, err := ckks.NewDecryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
rlk, err := kgen.GenRelinearizationKeyNew(sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
evk := rlwe.NewMemEvaluationKeySet(rlk)
|
||||
|
||||
eval := ckks.NewEvaluator(params, evk)
|
||||
encryptor := ckks.NewEncryptor(params, sk)
|
||||
decryptor := ckks.NewDecryptor(params, sk)
|
||||
eval := ckks.NewEvaluator(params, rlwe.NewMemEvaluationKeySet(kgen.GenRelinearizationKeyNew(sk)))
|
||||
|
||||
modEval := NewHModEvaluator(eval)
|
||||
|
||||
|
||||
@@ -114,24 +114,10 @@ func genCKKSTestParams(defaultParam ckks.Parameters) (tc *ckksTestContext, err e
|
||||
|
||||
tc.encoder = ckks.NewEncoder(tc.params)
|
||||
|
||||
if tc.encryptorPk, err = ckks.NewEncryptor(tc.params, tc.pk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.encryptorSk, err = ckks.NewEncryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.decryptor, err = ckks.NewDecryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
rlk, err := tc.kgen.GenRelinearizationKeyNew(tc.sk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tc.evaluator = ckks.NewEvaluator(tc.params, rlwe.NewMemEvaluationKeySet(rlk))
|
||||
tc.encryptorPk = ckks.NewEncryptor(tc.params, tc.pk)
|
||||
tc.encryptorSk = ckks.NewEncryptor(tc.params, tc.sk)
|
||||
tc.decryptor = ckks.NewDecryptor(tc.params, tc.sk)
|
||||
tc.evaluator = ckks.NewEvaluator(tc.params, rlwe.NewMemEvaluationKeySet(tc.kgen.GenRelinearizationKeyNew(tc.sk)))
|
||||
|
||||
return tc, nil
|
||||
|
||||
@@ -188,13 +174,9 @@ func testCKKSLinearTransformation(tc *ckksTestContext, t *testing.T) {
|
||||
batch := 1 << logBatch
|
||||
n := slots / batch
|
||||
|
||||
gks, err := tc.kgen.GenGaloisKeysNew(rlwe.GaloisElementsForInnerSum(tc.params, batch, n), tc.sk)
|
||||
require.NoError(t, err)
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, gks...)
|
||||
eval := tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(nil, tc.kgen.GenGaloisKeysNew(rlwe.GaloisElementsForInnerSum(tc.params, batch, n), tc.sk)...))
|
||||
|
||||
eval := tc.evaluator.WithKey(evk)
|
||||
|
||||
eval.Average(ciphertext, logBatch, ciphertext)
|
||||
require.NoError(t, eval.Average(ciphertext, logBatch, ciphertext))
|
||||
|
||||
tmp0 := make([]*bignum.Complex, len(values))
|
||||
for i := range tmp0 {
|
||||
@@ -258,9 +240,7 @@ func testCKKSLinearTransformation(tc *ckksTestContext, t *testing.T) {
|
||||
|
||||
galEls := GaloisElementsForLinearTransformation(params, ltparams)
|
||||
|
||||
gks, err := tc.kgen.GenGaloisKeysNew(galEls, tc.sk)
|
||||
require.NoError(t, err)
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, gks...)
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, tc.kgen.GenGaloisKeysNew(galEls, tc.sk)...)
|
||||
|
||||
ltEval := NewEvaluator(tc.evaluator.WithKey(evk))
|
||||
|
||||
@@ -323,9 +303,7 @@ func testCKKSLinearTransformation(tc *ckksTestContext, t *testing.T) {
|
||||
|
||||
galEls := GaloisElementsForLinearTransformation(params, ltparams)
|
||||
|
||||
gks, err := tc.kgen.GenGaloisKeysNew(galEls, tc.sk)
|
||||
require.NoError(t, err)
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, gks...)
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, tc.kgen.GenGaloisKeysNew(galEls, tc.sk)...)
|
||||
|
||||
ltEval := NewEvaluator(tc.evaluator.WithKey(evk))
|
||||
|
||||
|
||||
@@ -106,25 +106,10 @@ func genBGVTestParams(params bgv.Parameters) (tc *bgvTestContext, err error) {
|
||||
tc.sk, tc.pk = tc.kgen.GenKeyPairNew()
|
||||
tc.encoder = bgv.NewEncoder(tc.params)
|
||||
|
||||
if tc.encryptorPk, err = bgv.NewEncryptor(tc.params, tc.pk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.encryptorSk, err = bgv.NewEncryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.decryptor, err = bgv.NewDecryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var rlk *rlwe.RelinearizationKey
|
||||
if rlk, err = tc.kgen.GenRelinearizationKeyNew(tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
evk := rlwe.NewMemEvaluationKeySet(rlk)
|
||||
tc.evaluator = bgv.NewEvaluator(tc.params, evk)
|
||||
tc.encryptorPk = bgv.NewEncryptor(tc.params, tc.pk)
|
||||
tc.encryptorSk = bgv.NewEncryptor(tc.params, tc.sk)
|
||||
tc.decryptor = bgv.NewDecryptor(tc.params, tc.sk)
|
||||
tc.evaluator = bgv.NewEvaluator(tc.params, rlwe.NewMemEvaluationKeySet(tc.kgen.GenRelinearizationKeyNew(tc.sk)))
|
||||
|
||||
tc.testLevel = []int{0, params.MaxLevel()}
|
||||
|
||||
@@ -230,9 +215,7 @@ func testBGVLinearTransformation(tc *bgvTestContext, t *testing.T) {
|
||||
|
||||
galEls := GaloisElementsForLinearTransformation(params, ltparams)
|
||||
|
||||
gks, err := tc.kgen.GenGaloisKeysNew(galEls, tc.sk)
|
||||
require.NoError(t, err)
|
||||
eval := tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(nil, gks...))
|
||||
eval := tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(nil, tc.kgen.GenGaloisKeysNew(galEls, tc.sk)...))
|
||||
ltEval := NewEvaluator(eval)
|
||||
|
||||
require.NoError(t, ltEval.LinearTransformation(ciphertext, linTransf, ciphertext))
|
||||
@@ -302,9 +285,7 @@ func testBGVLinearTransformation(tc *bgvTestContext, t *testing.T) {
|
||||
|
||||
galEls := GaloisElementsForLinearTransformation(params, ltparams)
|
||||
|
||||
gks, err := tc.kgen.GenGaloisKeysNew(galEls, tc.sk)
|
||||
require.NoError(t, err)
|
||||
eval := tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(nil, gks...))
|
||||
eval := tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(nil, tc.kgen.GenGaloisKeysNew(galEls, tc.sk)...))
|
||||
ltEval := NewEvaluator(eval)
|
||||
|
||||
require.NoError(t, ltEval.LinearTransformation(ciphertext, linTransf, ciphertext))
|
||||
|
||||
@@ -86,35 +86,22 @@ func NewBootstrapper(params ckks.Parameters, btpParams Parameters, btpKeys *Eval
|
||||
// EvaluationKeySet: struct compliant to the interface rlwe.EvaluationKeySetInterface.
|
||||
// EvkDtS: *rlwe.EvaluationKey
|
||||
// EvkStD: *rlwe.EvaluationKey
|
||||
func GenEvaluationKeySetNew(btpParams Parameters, ckksParams ckks.Parameters, sk *rlwe.SecretKey) (*EvaluationKeySet, error) {
|
||||
func GenEvaluationKeySetNew(btpParams Parameters, ckksParams ckks.Parameters, sk *rlwe.SecretKey) *EvaluationKeySet {
|
||||
|
||||
kgen := ckks.NewKeyGenerator(ckksParams)
|
||||
|
||||
gks, err := kgen.GenGaloisKeysNew(append(btpParams.GaloisElements(ckksParams), ckksParams.GaloisElementForComplexConjugation()), sk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
EvkDtS, EvkStD := btpParams.GenEncapsulationEvaluationKeysNew(ckksParams, sk)
|
||||
|
||||
EvkDtS, EvkStD, err := btpParams.GenEncapsulationEvaluationKeysNew(ckksParams, sk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rlk, err := kgen.GenRelinearizationKeyNew(sk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
evk := rlwe.NewMemEvaluationKeySet(rlk, gks...)
|
||||
evk := rlwe.NewMemEvaluationKeySet(kgen.GenRelinearizationKeyNew(sk), kgen.GenGaloisKeysNew(append(btpParams.GaloisElements(ckksParams), ckksParams.GaloisElementForComplexConjugation()), sk)...)
|
||||
return &EvaluationKeySet{
|
||||
MemEvaluationKeySet: evk,
|
||||
EvkDtS: EvkDtS,
|
||||
EvkStD: EvkStD,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// GenEncapsulationEvaluationKeysNew generates the low level encapsulation EvaluationKeys for the bootstrapping.
|
||||
func (p *Parameters) GenEncapsulationEvaluationKeysNew(params ckks.Parameters, skDense *rlwe.SecretKey) (EvkDtS, EvkStD *rlwe.EvaluationKey, err error) {
|
||||
func (p *Parameters) GenEncapsulationEvaluationKeysNew(params ckks.Parameters, skDense *rlwe.SecretKey) (EvkDtS, EvkStD *rlwe.EvaluationKey) {
|
||||
|
||||
if p.EphemeralSecretWeight == 0 {
|
||||
return
|
||||
@@ -130,18 +117,8 @@ func (p *Parameters) GenEncapsulationEvaluationKeysNew(params ckks.Parameters, s
|
||||
kgenDense := rlwe.NewKeyGenerator(params.Parameters)
|
||||
skSparse := kgenSparse.GenSecretKeyWithHammingWeightNew(p.EphemeralSecretWeight)
|
||||
|
||||
EvkDtS, err = kgenDense.GenEvaluationKeyNew(skDense, skSparse)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
EvkStD, err = kgenDense.GenEvaluationKeyNew(skSparse, skDense)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
EvkDtS = kgenDense.GenEvaluationKeyNew(skDense, skSparse)
|
||||
EvkStD = kgenDense.GenEvaluationKeyNew(skSparse, skDense)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,7 @@ func BenchmarkBootstrap(b *testing.B) {
|
||||
kgen := ckks.NewKeyGenerator(params)
|
||||
sk := kgen.GenSecretKeyNew()
|
||||
|
||||
evk, err := GenEvaluationKeySetNew(btpParams, params, sk)
|
||||
require.NoError(b, err)
|
||||
|
||||
btp, err := NewBootstrapper(params, btpParams, evk)
|
||||
btp, err := NewBootstrapper(params, btpParams, GenEvaluationKeySetNew(btpParams, params, sk))
|
||||
require.NoError(b, err)
|
||||
|
||||
b.Run(ParamsToString(params, btpParams.LogMaxDimensions().Cols, "Bootstrap/"), func(b *testing.B) {
|
||||
|
||||
@@ -130,15 +130,9 @@ func testbootstrap(params ckks.Parameters, btpParams Parameters, t *testing.T) {
|
||||
sk := kgen.GenSecretKeyNew()
|
||||
encoder := ckks.NewEncoder(params)
|
||||
|
||||
encryptor, err := ckks.NewEncryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
decryptor, err := ckks.NewDecryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
evk, err := GenEvaluationKeySetNew(btpParams, params, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
encryptor := ckks.NewEncryptor(params, sk)
|
||||
decryptor := ckks.NewDecryptor(params, sk)
|
||||
evk := GenEvaluationKeySetNew(btpParams, params, sk)
|
||||
btp, err := NewBootstrapper(params, btpParams, evk)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ func NewCiphertext(params Parameters, degree, level int) (ct *rlwe.Ciphertext) {
|
||||
// - key: *rlwe.SecretKey or *rlwe.PublicKey
|
||||
//
|
||||
// output: an rlwe.Encryptor instantiated with the provided key.
|
||||
func NewEncryptor(params Parameters, key rlwe.EncryptionKey) (*rlwe.Encryptor, error) {
|
||||
func NewEncryptor(params Parameters, key rlwe.EncryptionKey) *rlwe.Encryptor {
|
||||
return rlwe.NewEncryptor(params, key)
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func NewEncryptor(params Parameters, key rlwe.EncryptionKey) (*rlwe.Encryptor, e
|
||||
// - key: *rlwe.SecretKey
|
||||
//
|
||||
// output: an rlwe.Decryptor instantiated with the provided key.
|
||||
func NewDecryptor(params Parameters, key *rlwe.SecretKey) (*rlwe.Decryptor, error) {
|
||||
func NewDecryptor(params Parameters, key *rlwe.SecretKey) *rlwe.Decryptor {
|
||||
return rlwe.NewDecryptor(params, key)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tuneinsight/lattigo/v4/ring"
|
||||
"github.com/tuneinsight/lattigo/v4/rlwe"
|
||||
"github.com/tuneinsight/lattigo/v4/utils/sampling"
|
||||
@@ -94,10 +92,7 @@ func benchEvaluator(tc *testContext, b *testing.B) {
|
||||
ciphertext2 := rlwe.NewCiphertextRandom(tc.prng, tc.params.Parameters, 1, tc.params.MaxLevel())
|
||||
receiver := rlwe.NewCiphertextRandom(tc.prng, tc.params.Parameters, 2, tc.params.MaxLevel())
|
||||
|
||||
rlk, err := tc.kgen.GenRelinearizationKeyNew(tc.sk)
|
||||
require.NoError(b, err)
|
||||
|
||||
eval := tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(rlk))
|
||||
eval := tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(tc.kgen.GenRelinearizationKeyNew(tc.sk)))
|
||||
|
||||
b.Run(GetTestName(tc.params, "Evaluator/Add/Scalar"), func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
||||
@@ -121,24 +121,13 @@ func genTestParams(defaultParam Parameters) (tc *testContext, err error) {
|
||||
|
||||
tc.encoder = NewEncoder(tc.params)
|
||||
|
||||
if tc.encryptorPk, err = NewEncryptor(tc.params, tc.pk); err != nil {
|
||||
return
|
||||
}
|
||||
tc.encryptorPk = NewEncryptor(tc.params, tc.pk)
|
||||
|
||||
if tc.encryptorSk, err = NewEncryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
tc.encryptorSk = NewEncryptor(tc.params, tc.sk)
|
||||
|
||||
if tc.decryptor, err = NewDecryptor(tc.params, tc.sk); err != nil {
|
||||
return
|
||||
}
|
||||
tc.decryptor = NewDecryptor(tc.params, tc.sk)
|
||||
|
||||
rlk, err := tc.kgen.GenRelinearizationKeyNew(tc.sk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tc.evaluator = NewEvaluator(tc.params, rlwe.NewMemEvaluationKeySet(rlk))
|
||||
tc.evaluator = NewEvaluator(tc.params, rlwe.NewMemEvaluationKeySet(tc.kgen.GenRelinearizationKeyNew(tc.sk)))
|
||||
|
||||
return tc, nil
|
||||
|
||||
@@ -146,8 +135,6 @@ func genTestParams(defaultParam Parameters) (tc *testContext, err error) {
|
||||
|
||||
func newTestVectors(tc *testContext, encryptor *rlwe.Encryptor, a, b complex128, t *testing.T) (values []*bignum.Complex, pt *rlwe.Plaintext, ct *rlwe.Ciphertext) {
|
||||
|
||||
var err error
|
||||
|
||||
prec := tc.encoder.Prec()
|
||||
|
||||
pt = NewPlaintext(tc.params, tc.params.MaxLevel())
|
||||
@@ -176,8 +163,11 @@ func newTestVectors(tc *testContext, encryptor *rlwe.Encryptor, a, b complex128,
|
||||
tc.encoder.Encode(values, pt)
|
||||
|
||||
if encryptor != nil {
|
||||
var err error
|
||||
ct, err = encryptor.EncryptNew(pt)
|
||||
require.NoError(t, err)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return values, pt, ct
|
||||
@@ -793,9 +783,9 @@ func testFunctions(tc *testContext, t *testing.T) {
|
||||
|
||||
logPrec := math.Log2(tc.params.DefaultScale().Float64()) - float64(tc.params.LogN()-1)
|
||||
|
||||
btp, err := NewSecretKeyBootstrapper(tc.params, tc.sk)
|
||||
require.NoError(t, err)
|
||||
btp := NewSecretKeyBootstrapper(tc.params, tc.sk)
|
||||
|
||||
var err error
|
||||
if ciphertext, err = tc.evaluator.GoldschmidtDivisionNew(ciphertext, min, logPrec, btp); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -828,13 +818,11 @@ func testBridge(tc *testContext, t *testing.T) {
|
||||
|
||||
stdKeyGen := NewKeyGenerator(stdParams)
|
||||
stdSK := stdKeyGen.GenSecretKeyNew()
|
||||
stdDecryptor, err := NewDecryptor(stdParams, stdSK)
|
||||
require.NoError(t, err)
|
||||
stdDecryptor := NewDecryptor(stdParams, stdSK)
|
||||
stdEncoder := NewEncoder(stdParams)
|
||||
stdEvaluator := NewEvaluator(stdParams, nil)
|
||||
|
||||
evkCtR, evkRtC, err := stdKeyGen.GenEvaluationKeysForRingSwapNew(stdSK, tc.sk)
|
||||
require.NoError(t, err)
|
||||
evkCtR, evkRtC := stdKeyGen.GenEvaluationKeysForRingSwapNew(stdSK, tc.sk)
|
||||
|
||||
switcher, err := NewDomainSwitcher(stdParams, evkCtR, evkRtC)
|
||||
if err != nil {
|
||||
|
||||
@@ -17,28 +17,15 @@ type SecretKeyBootstrapper struct {
|
||||
Counter int // records the number of bootstrapping
|
||||
}
|
||||
|
||||
func NewSecretKeyBootstrapper(params Parameters, sk *rlwe.SecretKey) (rlwe.Bootstrapper, error) {
|
||||
|
||||
dec, err := NewDecryptor(params, sk)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
enc, err := NewEncryptor(params, sk)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func NewSecretKeyBootstrapper(params Parameters, sk *rlwe.SecretKey) rlwe.Bootstrapper {
|
||||
return &SecretKeyBootstrapper{
|
||||
params,
|
||||
NewEncoder(params),
|
||||
dec,
|
||||
enc,
|
||||
NewDecryptor(params, sk),
|
||||
NewEncryptor(params, sk),
|
||||
sk,
|
||||
make([]*bignum.Complex, params.N()),
|
||||
0}, nil
|
||||
0}
|
||||
}
|
||||
|
||||
func (d *SecretKeyBootstrapper) Bootstrap(ct *rlwe.Ciphertext) (*rlwe.Ciphertext, error) {
|
||||
@@ -53,11 +40,8 @@ func (d *SecretKeyBootstrapper) Bootstrap(ct *rlwe.Ciphertext) (*rlwe.Ciphertext
|
||||
return nil, err
|
||||
}
|
||||
ct.Resize(1, d.MaxLevel())
|
||||
if err := d.Encrypt(pt, ct); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.Counter++
|
||||
return ct, nil
|
||||
return ct, d.Encrypt(pt, ct)
|
||||
}
|
||||
|
||||
func (d SecretKeyBootstrapper) BootstrapMany(cts []*rlwe.Ciphertext) ([]*rlwe.Ciphertext, error) {
|
||||
|
||||
@@ -151,25 +151,11 @@ func gentestContext(nParties int, params bgv.Parameters) (tc *testContext, err e
|
||||
}
|
||||
|
||||
// Publickeys
|
||||
if tc.pk0, err = kgen.GenPublicKeyNew(tc.sk0); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.pk1, err = kgen.GenPublicKeyNew(tc.sk1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.encryptorPk0, err = bgv.NewEncryptor(tc.params, tc.pk0); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.decryptorSk0, err = bgv.NewDecryptor(tc.params, tc.sk0); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.decryptorSk1, err = bgv.NewDecryptor(tc.params, tc.sk1); err != nil {
|
||||
return
|
||||
}
|
||||
tc.pk0 = kgen.GenPublicKeyNew(tc.sk0)
|
||||
tc.pk1 = kgen.GenPublicKeyNew(tc.sk1)
|
||||
tc.encryptorPk0 = bgv.NewEncryptor(tc.params, tc.pk0)
|
||||
tc.decryptorSk0 = bgv.NewDecryptor(tc.params, tc.sk0)
|
||||
tc.decryptorSk1 = bgv.NewDecryptor(tc.params, tc.sk1)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -489,8 +475,7 @@ func testRefreshAndTransformSwitchParams(tc *testContext, t *testing.T) {
|
||||
transform.Func(coeffs)
|
||||
|
||||
coeffsHave := make([]uint64, tc.params.MaxSlots())
|
||||
dec, err := rlwe.NewDecryptor(paramsOut.Parameters, skIdealOut)
|
||||
require.NoError(t, err)
|
||||
dec := rlwe.NewDecryptor(paramsOut.Parameters, skIdealOut)
|
||||
bgv.NewEncoder(paramsOut).Decode(dec.DecryptNew(ciphertext), coeffsHave)
|
||||
|
||||
//Decrypts and compares
|
||||
@@ -501,7 +486,8 @@ func testRefreshAndTransformSwitchParams(tc *testContext, t *testing.T) {
|
||||
|
||||
func newTestVectors(tc *testContext, encryptor *rlwe.Encryptor, t *testing.T) (coeffs []uint64, plaintext *rlwe.Plaintext, ciphertext *rlwe.Ciphertext) {
|
||||
|
||||
prng, _ := sampling.NewPRNG()
|
||||
prng, err := sampling.NewPRNG()
|
||||
require.NoError(t, err)
|
||||
uniformSampler := ring.NewUniformSampler(prng, tc.ringT)
|
||||
coeffsPol := uniformSampler.ReadNew()
|
||||
|
||||
@@ -512,9 +498,10 @@ func newTestVectors(tc *testContext, encryptor *rlwe.Encryptor, t *testing.T) (c
|
||||
plaintext = bgv.NewPlaintext(tc.params, tc.params.MaxLevel())
|
||||
plaintext.Scale = tc.params.NewScale(2)
|
||||
require.NoError(t, tc.encoder.Encode(coeffsPol.Coeffs[0], plaintext))
|
||||
var err error
|
||||
ciphertext, err = encryptor.EncryptNew(plaintext)
|
||||
require.NoError(t, err)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return coeffsPol.Coeffs[0], plaintext, ciphertext
|
||||
}
|
||||
|
||||
|
||||
@@ -140,25 +140,11 @@ func genTestParams(params ckks.Parameters, NParties int) (tc *testContext, err e
|
||||
}
|
||||
|
||||
// Publickeys
|
||||
if tc.pk0, err = kgen.GenPublicKeyNew(tc.sk0); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.pk1, err = kgen.GenPublicKeyNew(tc.sk1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.encryptorPk0, err = ckks.NewEncryptor(tc.params, tc.pk0); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.decryptorSk0, err = ckks.NewDecryptor(tc.params, tc.sk0); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tc.decryptorSk1, err = ckks.NewDecryptor(tc.params, tc.sk1); err != nil {
|
||||
return
|
||||
}
|
||||
tc.pk0 = kgen.GenPublicKeyNew(tc.sk0)
|
||||
tc.pk1 = kgen.GenPublicKeyNew(tc.sk1)
|
||||
tc.encryptorPk0 = ckks.NewEncryptor(tc.params, tc.pk0)
|
||||
tc.decryptorSk0 = ckks.NewDecryptor(tc.params, tc.sk0)
|
||||
tc.decryptorSk1 = ckks.NewDecryptor(tc.params, tc.sk1)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -505,10 +491,7 @@ func testRefreshAndTransformSwitchParams(tc *testContext, t *testing.T) {
|
||||
coeffs[i][1].Mul(coeffs[i][1], bignum.NewFloat(0.7071067811865476, logBound))
|
||||
}
|
||||
|
||||
dec, err := ckks.NewDecryptor(paramsOut, skIdealOut)
|
||||
require.NoError(t, err)
|
||||
|
||||
ckks.VerifyTestVectors(paramsOut, ckks.NewEncoder(paramsOut), dec, coeffs, ciphertext, nil, *printPrecisionStats, t)
|
||||
ckks.VerifyTestVectors(paramsOut, ckks.NewEncoder(paramsOut), ckks.NewDecryptor(paramsOut, skIdealOut), coeffs, ciphertext, nil, *printPrecisionStats, t)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -544,12 +527,13 @@ func newTestVectorsAtScale(tc *testContext, encryptor *rlwe.Encryptor, a, b comp
|
||||
panic("invalid ring type")
|
||||
}
|
||||
|
||||
tc.encoder.Encode(values, pt)
|
||||
if err := tc.encoder.Encode(values, pt); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if encryptor != nil {
|
||||
var err error
|
||||
ct, err = encryptor.EncryptNew(pt)
|
||||
if err != nil {
|
||||
if ct, err = encryptor.EncryptNew(pt); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,10 +355,7 @@ func testKeySwitchProtocol(tc *testContext, levelQ, levelP, bpw2 int, t *testing
|
||||
}
|
||||
|
||||
ct := rlwe.NewCiphertext(params, 1, levelQ)
|
||||
enc2, err := rlwe.NewEncryptor(params, tc.skIdeal)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, enc2.EncryptZero(ct))
|
||||
rlwe.NewEncryptor(params, tc.skIdeal).EncryptZero(ct)
|
||||
|
||||
shares := make([]KeySwitchShare, nbParties)
|
||||
for i := range shares {
|
||||
@@ -377,8 +374,7 @@ func testKeySwitchProtocol(tc *testContext, levelQ, levelP, bpw2 int, t *testing
|
||||
|
||||
ksCt := rlwe.NewCiphertext(params, 1, ct.Level())
|
||||
|
||||
dec, err := rlwe.NewDecryptor(params, skOutIdeal)
|
||||
require.NoError(t, err)
|
||||
dec := rlwe.NewDecryptor(params, skOutIdeal)
|
||||
|
||||
cks[0].KeySwitch(ct, shares[0], ksCt)
|
||||
|
||||
@@ -429,10 +425,7 @@ func testPublicKeySwitchProtocol(tc *testContext, levelQ, levelP, bpw2 int, t *t
|
||||
|
||||
ct := rlwe.NewCiphertext(params, 1, levelQ)
|
||||
|
||||
enc2, err := rlwe.NewEncryptor(params, tc.skIdeal)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, enc2.EncryptZero(ct))
|
||||
rlwe.NewEncryptor(params, tc.skIdeal).EncryptZero(ct)
|
||||
|
||||
shares := make([]PublicKeySwitchShare, nbParties)
|
||||
for i := range shares {
|
||||
@@ -451,8 +444,7 @@ func testPublicKeySwitchProtocol(tc *testContext, levelQ, levelP, bpw2 int, t *t
|
||||
buffer.RequireSerializerCorrect(t, &shares[0])
|
||||
|
||||
ksCt := rlwe.NewCiphertext(params, 1, levelQ)
|
||||
dec, err := rlwe.NewDecryptor(params, skOut)
|
||||
require.NoError(t, err)
|
||||
dec := rlwe.NewDecryptor(params, skOut)
|
||||
|
||||
pcks[0].KeySwitch(ct, shares[0], ksCt)
|
||||
|
||||
|
||||
@@ -41,10 +41,7 @@ func NewPublicKeySwitchProtocol(params rlwe.Parameters, noiseFlooding ring.Distr
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pcks.Encryptor, err = rlwe.NewEncryptor(params, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pcks.Encryptor = rlwe.NewEncryptor(params, nil)
|
||||
|
||||
switch noiseFlooding.(type) {
|
||||
case ring.DiscreteGaussian:
|
||||
@@ -69,17 +66,14 @@ func (pcks PublicKeySwitchProtocol) AllocateShare(levelQ int) (s PublicKeySwitch
|
||||
// ct is the rlwe.Ciphertext to keyswitch. Note that ct.Value[0] is not used by the function and can be nil/zero.
|
||||
//
|
||||
// Expected noise: ctNoise + encFreshPk + smudging
|
||||
func (pcks PublicKeySwitchProtocol) GenShare(sk *rlwe.SecretKey, pk *rlwe.PublicKey, ct *rlwe.Ciphertext, shareOut *PublicKeySwitchShare) (err error) {
|
||||
func (pcks PublicKeySwitchProtocol) GenShare(sk *rlwe.SecretKey, pk *rlwe.PublicKey, ct *rlwe.Ciphertext, shareOut *PublicKeySwitchShare) {
|
||||
|
||||
levelQ := utils.Min(shareOut.Level(), ct.Value[1].Level())
|
||||
|
||||
ringQ := pcks.params.RingQ().AtLevel(levelQ)
|
||||
|
||||
// Encrypt zero
|
||||
enc, err := pcks.Encryptor.WithKey(pk)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot GenShare: %w", err)
|
||||
}
|
||||
enc := pcks.Encryptor.WithKey(pk)
|
||||
|
||||
if err := enc.EncryptZero(&rlwe.Ciphertext{
|
||||
Operand: rlwe.Operand[ring.Poly]{
|
||||
@@ -90,7 +84,7 @@ func (pcks PublicKeySwitchProtocol) GenShare(sk *rlwe.SecretKey, pk *rlwe.Public
|
||||
MetaData: ct.MetaData,
|
||||
},
|
||||
}); err != nil {
|
||||
return fmt.Errorf("cannot GenShare: %w", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Add ct[1] * s and noise
|
||||
@@ -106,8 +100,6 @@ func (pcks PublicKeySwitchProtocol) GenShare(sk *rlwe.SecretKey, pk *rlwe.Public
|
||||
pcks.noiseSampler.ReadAndAdd(pcks.buf)
|
||||
ringQ.Add(shareOut.Value[0], pcks.buf, shareOut.Value[0])
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// AggregateShares is the second part of the first and unique round of the PublicKeySwitchProtocol protocol. Each party upon receiving the j-1 elements from the
|
||||
@@ -155,15 +147,10 @@ func (pcks PublicKeySwitchProtocol) ShallowCopy() PublicKeySwitchProtocol {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
enc, err := rlwe.NewEncryptor(params, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return PublicKeySwitchProtocol{
|
||||
noiseSampler: Xe,
|
||||
noise: pcks.noise,
|
||||
Encryptor: enc,
|
||||
Encryptor: pcks.Encryptor.ShallowCopy(),
|
||||
params: params,
|
||||
buf: params.RingQ().NewPoly(),
|
||||
}
|
||||
|
||||
@@ -75,20 +75,9 @@ func obliviousRiding() {
|
||||
|
||||
riderSk, riderPk := kgen.GenKeyPairNew()
|
||||
|
||||
decryptor, err := bfv.NewDecryptor(params, riderSk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
encryptorRiderPk, err := bfv.NewEncryptor(params, riderPk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
encryptorRiderSk, err := bfv.NewEncryptor(params, riderSk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
decryptor := bfv.NewDecryptor(params, riderSk)
|
||||
encryptorRiderPk := bfv.NewEncryptor(params, riderPk)
|
||||
encryptorRiderSk := bfv.NewEncryptor(params, riderSk)
|
||||
|
||||
evaluator := bfv.NewEvaluator(params, nil)
|
||||
|
||||
|
||||
@@ -132,23 +132,14 @@ func main() {
|
||||
kgenN12 := ckks.NewKeyGenerator(paramsN12)
|
||||
skN12 := kgenN12.GenSecretKeyNew()
|
||||
encoderN12 := ckks.NewEncoder(paramsN12)
|
||||
encryptorN12, err := ckks.NewEncryptor(paramsN12, skN12)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
decryptorN12, err := ckks.NewDecryptor(paramsN12, skN12)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
encryptorN12 := ckks.NewEncryptor(paramsN12, skN12)
|
||||
decryptorN12 := ckks.NewDecryptor(paramsN12, skN12)
|
||||
|
||||
kgenN11 := ckks.NewKeyGenerator(paramsN11)
|
||||
skN11 := kgenN11.GenSecretKeyNew()
|
||||
|
||||
// EvaluationKey RLWEN12 -> RLWEN11
|
||||
evkN12ToN11, err := ckks.NewKeyGenerator(paramsN12).GenEvaluationKeyNew(skN12, skN11)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
evkN12ToN11 := ckks.NewKeyGenerator(paramsN12).GenEvaluationKeyNew(skN12, skN11)
|
||||
|
||||
fmt.Printf("Gen SlotsToCoeffs Matrices... ")
|
||||
now = time.Now()
|
||||
@@ -168,12 +159,7 @@ func main() {
|
||||
galEls = append(galEls, CoeffsToSlotsParameters.GaloisElements(paramsN12)...)
|
||||
galEls = append(galEls, paramsN12.GaloisElementForComplexConjugation())
|
||||
|
||||
gks, err := kgenN12.GenGaloisKeysNew(galEls, skN12)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, gks...)
|
||||
evk := rlwe.NewMemEvaluationKeySet(nil, kgenN12.GenGaloisKeysNew(galEls, skN12)...)
|
||||
|
||||
// LUT Evaluator
|
||||
evalLUT := lut.NewEvaluator(paramsN12.Parameters, paramsN11.Parameters)
|
||||
@@ -184,10 +170,7 @@ func main() {
|
||||
|
||||
fmt.Printf("Encrypting bits of skLWE in RGSW... ")
|
||||
now = time.Now()
|
||||
blindRotateKey, err := lut.GenEvaluationKeyNew(paramsN12.Parameters, skN12, paramsN11.Parameters, skN11, evkParams) // Generate RGSW(sk_i) for all coefficients of sk
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
blindRotateKey := lut.GenEvaluationKeyNew(paramsN12.Parameters, skN12, paramsN11.Parameters, skN11, evkParams) // Generate RGSW(sk_i) for all coefficients of sk
|
||||
fmt.Printf("Done (%s)\n", time.Since(now))
|
||||
|
||||
// Generates the starting plaintext values.
|
||||
@@ -202,6 +185,7 @@ func main() {
|
||||
if err := encoderN12.Encode(values, pt); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ctN12, err := encryptorN12.EncryptNew(pt)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -96,21 +96,12 @@ func main() {
|
||||
sk, pk := kgen.GenKeyPairNew()
|
||||
|
||||
encoder := ckks.NewEncoder(params)
|
||||
decryptor, err := ckks.NewDecryptor(params, sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
encryptor, err := ckks.NewEncryptor(params, pk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
decryptor := ckks.NewDecryptor(params, sk)
|
||||
encryptor := ckks.NewEncryptor(params, pk)
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("Generating bootstrapping keys...")
|
||||
evk, err := bootstrapping.GenEvaluationKeySetNew(btpParams, params, sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
evk := bootstrapping.GenEvaluationKeySetNew(btpParams, params, sk)
|
||||
fmt.Println("Done")
|
||||
|
||||
var btp *bootstrapping.Bootstrapper
|
||||
|
||||
@@ -159,14 +159,8 @@ func main() {
|
||||
// - PublicKey: an encryption of zero, which can be shared and enable anyone to encrypt plaintexts.
|
||||
// - RelinearizationKey: an evaluation key which is used during ciphertext x ciphertext multiplication to ensure ciphertext compactness.
|
||||
sk := kgen.GenSecretKeyNew()
|
||||
pk, err := kgen.GenPublicKeyNew(sk) // Note that we can generate any number of public keys associated to the same Secret Key.
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
rlk, err := kgen.GenRelinearizationKeyNew(sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pk := kgen.GenPublicKeyNew(sk) // Note that we can generate any number of public keys associated to the same Secret Key.
|
||||
rlk := kgen.GenRelinearizationKeyNew(sk)
|
||||
|
||||
// To store and manage the loading of evaluation keys, we instantiate a struct that complies to the `rlwe.EvaluationKeySetInterface` Interface.
|
||||
// The package `rlwe` provides a simple struct that complies to this interface, but a user can design its own struct compliant to the `rlwe.EvaluationKeySetInterface`
|
||||
@@ -218,10 +212,7 @@ func main() {
|
||||
// To generate ciphertexts we need an encryptor.
|
||||
// An encryptor will accept both a secret key or a public key,
|
||||
// in this example we will use the public key.
|
||||
enc, err := ckks.NewEncryptor(params, pk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
enc := ckks.NewEncryptor(params, pk)
|
||||
|
||||
// And we create the ciphertext.
|
||||
// Note that the metadata of the plaintext will be copied on the resulting ciphertext.
|
||||
@@ -229,6 +220,7 @@ func main() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// It is also possible to first allocate the ciphertext the same way it was done
|
||||
// for the plaintext with with `ct := ckks.NewCiphertext(params, 1, pt.Level())`.
|
||||
|
||||
@@ -239,10 +231,7 @@ func main() {
|
||||
// We are able to generate ciphertext from plaintext using the encryptor.
|
||||
// To do the converse, generate plaintexts from ciphertexts, we need to instantiate a decryptor.
|
||||
// Obviously, the decryptor will only accept the secret key.
|
||||
dec, err := ckks.NewDecryptor(params, sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
dec := ckks.NewDecryptor(params, sk)
|
||||
|
||||
// ================
|
||||
// Evaluator Basics
|
||||
@@ -484,13 +473,8 @@ func main() {
|
||||
}
|
||||
|
||||
// We then generate the `rlwe.GaloisKey`s element that corresponds to these galois elements.
|
||||
gks, err := kgen.GenGaloisKeysNew(galEls, sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Then we update the evaluator's `rlwe.EvaluationKeySet` with the new keys.
|
||||
eval = eval.WithKey(rlwe.NewMemEvaluationKeySet(rlk, gks...))
|
||||
// And we update the evaluator's `rlwe.EvaluationKeySet` with the new keys.
|
||||
eval = eval.WithKey(rlwe.NewMemEvaluationKeySet(rlk, kgen.GenGaloisKeysNew(galEls, sk)...))
|
||||
|
||||
// Rotation by 5 positions to the left
|
||||
for i := 0; i < Slots; i++ {
|
||||
@@ -612,12 +596,7 @@ func main() {
|
||||
|
||||
// The innersum operations is carried out with log2(n) + HW(n) automorphisms and we need to
|
||||
// generate the corresponding Galois keys and provide them to the `Evaluator`.
|
||||
gks, err = kgen.GenGaloisKeysNew(params.GaloisElementsForInnerSum(batch, n), sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
eval = eval.WithKey(rlwe.NewMemEvaluationKeySet(rlk, gks...))
|
||||
eval = eval.WithKey(rlwe.NewMemEvaluationKeySet(rlk, kgen.GenGaloisKeysNew(params.GaloisElementsForInnerSum(batch, n), sk)...))
|
||||
|
||||
// Plaintext circuit
|
||||
copy(want, values1)
|
||||
@@ -637,12 +616,7 @@ func main() {
|
||||
fmt.Printf("Innersum %s", ckks.GetPrecisionStats(params, ecd, dec, want, res, nil, false).String())
|
||||
|
||||
// The replicate operation is exactly the same as the innersum operation, but in reverse
|
||||
gks, err = kgen.GenGaloisKeysNew(params.GaloisElementsForReplicate(batch, n), sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
eval = eval.WithKey(rlwe.NewMemEvaluationKeySet(rlk, gks...))
|
||||
eval = eval.WithKey(rlwe.NewMemEvaluationKeySet(rlk, kgen.GenGaloisKeysNew(params.GaloisElementsForReplicate(batch, n), sk)...))
|
||||
|
||||
// Plaintext circuit
|
||||
copy(want, values1)
|
||||
@@ -720,11 +694,8 @@ func main() {
|
||||
// The list of Galois elements can also be obtained with `lt.GaloisElements`
|
||||
// but this requires to have it pre-allocated, which is not always desirable.
|
||||
galEls = circuits.GaloisElementsForLinearTransformation(params, ltparams)
|
||||
gks, err = kgen.GenGaloisKeysNew(galEls, sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ltEval := circuits.NewEvaluator(eval.WithKey(rlwe.NewMemEvaluationKeySet(rlk, gks...)))
|
||||
|
||||
ltEval := circuits.NewEvaluator(eval.WithKey(rlwe.NewMemEvaluationKeySet(rlk, kgen.GenGaloisKeysNew(galEls, sk)...)))
|
||||
|
||||
// And we valuate the linear transform
|
||||
if err := ltEval.LinearTransformation(ct1, lt, res); err != nil {
|
||||
|
||||
@@ -41,24 +41,10 @@ func example() {
|
||||
|
||||
sk := kgen.GenSecretKeyNew()
|
||||
|
||||
encryptor, err := ckks.NewEncryptor(params, sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
decryptor, err := ckks.NewDecryptor(params, sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
encryptor := ckks.NewEncryptor(params, sk)
|
||||
decryptor := ckks.NewDecryptor(params, sk)
|
||||
encoder := ckks.NewEncoder(params)
|
||||
|
||||
rlk, err := kgen.GenRelinearizationKeyNew(sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
evk := rlwe.NewMemEvaluationKeySet(rlk)
|
||||
evk := rlwe.NewMemEvaluationKeySet(kgen.GenRelinearizationKeyNew(sk))
|
||||
evaluator := ckks.NewEvaluator(params, evk)
|
||||
|
||||
fmt.Printf("Done in %s \n", time.Since(start))
|
||||
|
||||
@@ -41,27 +41,13 @@ func chebyshevinterpolation() {
|
||||
sk, pk := kgen.GenKeyPairNew()
|
||||
|
||||
// Encryptor
|
||||
encryptor, err := ckks.NewEncryptor(params, pk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
encryptor := ckks.NewEncryptor(params, pk)
|
||||
|
||||
// Decryptor
|
||||
decryptor, err := ckks.NewDecryptor(params, sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
decryptor := ckks.NewDecryptor(params, sk)
|
||||
|
||||
// Relinearization key
|
||||
rlk, err := kgen.GenRelinearizationKeyNew(sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
evk := rlwe.NewMemEvaluationKeySet(rlk)
|
||||
|
||||
// Evaluator
|
||||
evaluator := ckks.NewEvaluator(params, evk)
|
||||
// Evaluator with relinearization key
|
||||
evaluator := ckks.NewEvaluator(params, rlwe.NewMemEvaluationKeySet(kgen.GenRelinearizationKeyNew(sk)))
|
||||
|
||||
// Values to encrypt
|
||||
slots := params.MaxSlots()
|
||||
|
||||
@@ -164,10 +164,7 @@ func main() {
|
||||
|
||||
// Ciphertexts encrypted under collective public key and stored in the cloud
|
||||
l.Println("> Encrypt Phase")
|
||||
encryptor, err := bfv.NewEncryptor(params, pk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
encryptor := bfv.NewEncryptor(params, pk)
|
||||
pt := bfv.NewPlaintext(params, params.MaxLevel())
|
||||
elapsedEncryptParty := runTimedParty(func() {
|
||||
for i, pi := range P {
|
||||
@@ -194,10 +191,7 @@ func main() {
|
||||
l.Println("> ResulPlaintextModulus:")
|
||||
|
||||
// Decryption by the external party
|
||||
decryptor, err := bfv.NewDecryptor(params, P[0].sk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
decryptor := bfv.NewDecryptor(params, P[0].sk)
|
||||
ptres := bfv.NewPlaintext(params, params.MaxLevel())
|
||||
elapsedDecParty := runTimed(func() {
|
||||
decryptor.Decrypt(encOut, ptres)
|
||||
|
||||
@@ -136,10 +136,7 @@ func main() {
|
||||
|
||||
// Decrypt the result with the target secret key
|
||||
l.Println("> ResulPlaintextModulus:")
|
||||
decryptor, err := bfv.NewDecryptor(params, tsk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
decryptor := bfv.NewDecryptor(params, tsk)
|
||||
ptres := bfv.NewPlaintext(params, params.MaxLevel())
|
||||
elapsedDecParty := runTimed(func() {
|
||||
decryptor.Decrypt(encOut, ptres)
|
||||
@@ -176,10 +173,7 @@ func encPhase(params bfv.Parameters, P []*party, pk *rlwe.PublicKey, encoder *bf
|
||||
|
||||
// Each party encrypts its input vector
|
||||
l.Println("> Encrypt Phase")
|
||||
encryptor, err := bfv.NewEncryptor(params, pk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
encryptor := bfv.NewEncryptor(params, pk)
|
||||
|
||||
pt := bfv.NewPlaintext(params, params.MaxLevel())
|
||||
elapsedEncryptParty = runTimedParty(func() {
|
||||
@@ -329,9 +323,7 @@ func pcksPhase(params bfv.Parameters, tpk *rlwe.PublicKey, encRes *rlwe.Cipherte
|
||||
l.Println("> PublicKeySwitch Phase")
|
||||
elapsedPCKSParty = runTimedParty(func() {
|
||||
for _, pi := range P {
|
||||
if err = pcks.GenShare(pi.sk, tpk, encRes, &pi.pcksShare); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pcks.GenShare(pi.sk, tpk, encRes, &pi.pcksShare)
|
||||
}
|
||||
}, len(P))
|
||||
|
||||
|
||||
@@ -71,10 +71,7 @@ func main() {
|
||||
skLWE := rlwe.NewKeyGenerator(paramsLWE).GenSecretKeyNew()
|
||||
|
||||
// RLWE encryptor for the samples
|
||||
encryptorLWE, err := rlwe.NewEncryptor(paramsLWE, skLWE)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
encryptorLWE := rlwe.NewEncryptor(paramsLWE, skLWE)
|
||||
|
||||
// Values to encrypt in the RLWE sample
|
||||
values := make([]float64, slots)
|
||||
@@ -107,10 +104,7 @@ func main() {
|
||||
skLUT := rlwe.NewKeyGenerator(paramsLUT).GenSecretKeyNew()
|
||||
|
||||
// Collection of RGSW ciphertexts encrypting the bits of skLWE under skLUT
|
||||
blindeRotateKey, err := lut.GenEvaluationKeyNew(paramsLUT, skLUT, paramsLWE, skLWE, evkParams)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
blindeRotateKey := lut.GenEvaluationKeyNew(paramsLUT, skLUT, paramsLWE, skLWE, evkParams)
|
||||
|
||||
// Evaluation of LUT(ctLWE)
|
||||
// Returns one RLWE sample per slot in ctLWE
|
||||
@@ -125,10 +119,7 @@ func main() {
|
||||
// Decrypts, decodes and compares
|
||||
q := paramsLUT.Q()[0]
|
||||
qHalf := q >> 1
|
||||
decryptorLUT, err := rlwe.NewDecryptor(paramsLUT, skLUT)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
decryptorLUT := rlwe.NewDecryptor(paramsLUT, skLUT)
|
||||
ptLUT := rlwe.NewPlaintext(paramsLUT, paramsLUT.MaxLevel())
|
||||
for i := 0; i < slots; i++ {
|
||||
|
||||
|
||||
@@ -18,9 +18,8 @@ type Encryptor struct {
|
||||
|
||||
// NewEncryptor creates a new Encryptor type. Note that only secret-key encryption is
|
||||
// supported at the moment.
|
||||
func NewEncryptor(params rlwe.Parameters, key rlwe.EncryptionKey) (*Encryptor, error) {
|
||||
enc, err := rlwe.NewEncryptor(params, key)
|
||||
return &Encryptor{enc, params, params.RingQP().NewPoly()}, err
|
||||
func NewEncryptor(params rlwe.Parameters, key rlwe.EncryptionKey) *Encryptor {
|
||||
return &Encryptor{rlwe.NewEncryptor(params, key), params, params.RingQP().NewPoly()}
|
||||
}
|
||||
|
||||
// Encrypt encrypts a plaintext pt into a ciphertext ct, which can be a rgsw.Ciphertext
|
||||
@@ -57,14 +56,16 @@ func (enc Encryptor) Encrypt(pt *rlwe.Plaintext, ct interface{}) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
return rlwe.AddPolyTimesGadgetVectorToGadgetCiphertext(
|
||||
if err := rlwe.AddPolyTimesGadgetVectorToGadgetCiphertext(
|
||||
enc.buffQP.Q,
|
||||
[]rlwe.GadgetCiphertext{rgswCt.Value[0], rgswCt.Value[1]},
|
||||
*enc.params.RingQP(),
|
||||
enc.buffQP.Q)
|
||||
enc.buffQP.Q); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncryptZero generates an encryption of zero into a ciphertext ct, which can be a rgsw.Ciphertext
|
||||
@@ -74,7 +75,7 @@ func (enc Encryptor) EncryptZero(ct interface{}) (err error) {
|
||||
var rgswCt *Ciphertext
|
||||
var isRGSW bool
|
||||
if rgswCt, isRGSW = ct.(*Ciphertext); !isRGSW {
|
||||
return enc.Encryptor.EncryptZero(ct)
|
||||
return enc.Encryptor.EncryptZero(rgswCt)
|
||||
}
|
||||
|
||||
BaseRNSDecompositionVectorSize := rgswCt.Value[0].BaseRNSDecompositionVectorSize()
|
||||
@@ -86,18 +87,16 @@ func (enc Encryptor) EncryptZero(ct interface{}) (err error) {
|
||||
|
||||
for i := 0; i < BaseRNSDecompositionVectorSize; i++ {
|
||||
for j := 0; j < BaseTwoDecompositionVectorSize[i]; j++ {
|
||||
|
||||
if err = enc.Encryptor.EncryptZero(rlwe.Operand[ringqp.Poly]{MetaData: metadata, Value: []ringqp.Poly(rgswCt.Value[0].Value[i][j])}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = enc.Encryptor.EncryptZero(rlwe.Operand[ringqp.Poly]{MetaData: metadata, Value: []ringqp.Poly(rgswCt.Value[1].Value[i][j])}); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShallowCopy creates a shallow copy of this Encryptor in which all the read-only data-structures are
|
||||
|
||||
@@ -43,7 +43,7 @@ func (evk MemBlindRotatationEvaluationKeySet) GetEvaluationKeySet() (rlwe.Evalua
|
||||
}
|
||||
|
||||
// GenEvaluationKeyNew generates a new LUT evaluation key
|
||||
func GenEvaluationKeyNew(paramsRLWE rlwe.Parameters, skRLWE *rlwe.SecretKey, paramsLWE rlwe.Parameters, skLWE *rlwe.SecretKey, evkParams ...rlwe.EvaluationKeyParameters) (key MemBlindRotatationEvaluationKeySet, err error) {
|
||||
func GenEvaluationKeyNew(paramsRLWE rlwe.Parameters, skRLWE *rlwe.SecretKey, paramsLWE rlwe.Parameters, skLWE *rlwe.SecretKey, evkParams ...rlwe.EvaluationKeyParameters) (key MemBlindRotatationEvaluationKeySet) {
|
||||
|
||||
skLWECopy := skLWE.CopyNew()
|
||||
paramsLWE.RingQ().AtLevel(0).INTT(skLWECopy.Value.Q, skLWECopy.Value.Q)
|
||||
@@ -54,10 +54,7 @@ func GenEvaluationKeyNew(paramsRLWE rlwe.Parameters, skRLWE *rlwe.SecretKey, par
|
||||
}
|
||||
paramsLWE.RingQ().AtLevel(0).PolyToBigintCentered(skLWECopy.Value.Q, 1, sk)
|
||||
|
||||
encryptor, err := rgsw.NewEncryptor(paramsRLWE, skRLWE)
|
||||
if err != nil {
|
||||
return key, err
|
||||
}
|
||||
encryptor := rgsw.NewEncryptor(paramsRLWE, skRLWE)
|
||||
|
||||
levelQ, levelP, BaseTwoDecomposition := rlwe.ResolveEvaluationKeyParameters(paramsRLWE, evkParams)
|
||||
|
||||
@@ -82,8 +79,8 @@ func GenEvaluationKeyNew(paramsRLWE rlwe.Parameters, skRLWE *rlwe.SecretKey, par
|
||||
|
||||
skiRGSW[i] = rgsw.NewCiphertext(paramsRLWE, levelQ, levelP, BaseTwoDecomposition)
|
||||
|
||||
if err = encryptor.Encrypt(ptXi[siInt], skiRGSW[i]); err != nil {
|
||||
return
|
||||
if err := encryptor.Encrypt(ptXi[siInt], skiRGSW[i]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,15 +93,11 @@ func GenEvaluationKeyNew(paramsRLWE rlwe.Parameters, skRLWE *rlwe.SecretKey, par
|
||||
|
||||
galEls = append(galEls, paramsRLWE.RingQ().NthRoot()-ring.GaloisGen)
|
||||
|
||||
gks, err := kgen.GenGaloisKeysNew(galEls, skRLWE, rlwe.EvaluationKeyParameters{
|
||||
gks := kgen.GenGaloisKeysNew(galEls, skRLWE, rlwe.EvaluationKeyParameters{
|
||||
LevelQ: utils.Pointy(levelQ),
|
||||
LevelP: utils.Pointy(levelP),
|
||||
BaseTwoDecomposition: utils.Pointy(BaseTwoDecomposition),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return MemBlindRotatationEvaluationKeySet{}, err
|
||||
}
|
||||
|
||||
return MemBlindRotatationEvaluationKeySet{BlindRotationKeys: skiRGSW, AutomorphismKeys: gks}, nil
|
||||
return MemBlindRotatationEvaluationKeySet{BlindRotationKeys: skiRGSW, AutomorphismKeys: gks}
|
||||
}
|
||||
|
||||
@@ -94,8 +94,7 @@ func testLUT(t *testing.T) {
|
||||
skLWE := rlwe.NewKeyGenerator(paramsLWE).GenSecretKeyNew()
|
||||
|
||||
// RLWE encryptor for the samples
|
||||
encryptorLWE, err := rlwe.NewEncryptor(paramsLWE, skLWE)
|
||||
require.NoError(t, err)
|
||||
encryptorLWE := rlwe.NewEncryptor(paramsLWE, skLWE)
|
||||
|
||||
// Values to encrypt in the RLWE sample
|
||||
values := make([]float64, slots)
|
||||
@@ -129,8 +128,7 @@ func testLUT(t *testing.T) {
|
||||
skLUT := rlwe.NewKeyGenerator(paramsLUT).GenSecretKeyNew()
|
||||
|
||||
// Collection of RGSW ciphertexts encrypting the bits of skLWE under skLUT
|
||||
btpKey, err := GenEvaluationKeyNew(paramsLUT, skLUT, paramsLWE, skLWE, evkParams)
|
||||
require.NoError(t, err)
|
||||
btpKey := GenEvaluationKeyNew(paramsLUT, skLUT, paramsLWE, skLWE, evkParams)
|
||||
|
||||
// Evaluation of LUT(ctLWE)
|
||||
// Returns one RLWE sample per slot in ctLWE
|
||||
@@ -140,8 +138,7 @@ func testLUT(t *testing.T) {
|
||||
// Decrypts, decodes and compares
|
||||
q := paramsLUT.Q()[0]
|
||||
qHalf := q >> 1
|
||||
decryptorLUT, err := rlwe.NewDecryptor(paramsLUT, skLUT)
|
||||
require.NoError(t, err)
|
||||
decryptorLUT := rlwe.NewDecryptor(paramsLUT, skLUT)
|
||||
ptLUT := rlwe.NewPlaintext(paramsLUT, paramsLUT.MaxLevel())
|
||||
for i := 0; i < slots; i++ {
|
||||
|
||||
|
||||
@@ -38,10 +38,7 @@ func TestRGSW(t *testing.T) {
|
||||
|
||||
ct := NewCiphertext(params, params.MaxLevelQ(), params.MaxLevelP(), 0)
|
||||
|
||||
enc, err := NewEncryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
enc.Encrypt(pt, ct)
|
||||
NewEncryptor(params, sk).Encrypt(pt, ct)
|
||||
|
||||
left, right := NoiseRGSWCiphertext(ct, pt.Value, sk, params)
|
||||
|
||||
@@ -53,10 +50,7 @@ func TestRGSW(t *testing.T) {
|
||||
|
||||
ct := NewCiphertext(params, params.MaxLevelQ(), params.MaxLevelP(), 0)
|
||||
|
||||
enc, err := NewEncryptor(params, pk)
|
||||
require.NoError(t, err)
|
||||
|
||||
enc.Encrypt(pt, ct)
|
||||
NewEncryptor(params, pk).Encrypt(pt, ct)
|
||||
|
||||
left, right := NoiseRGSWCiphertext(ct, pt.Value, sk, params)
|
||||
|
||||
@@ -83,23 +77,13 @@ func TestRGSW(t *testing.T) {
|
||||
ctRGSW := NewCiphertext(params, params.MaxLevelQ(), params.MaxLevelP(), 0)
|
||||
ctRLWE := rlwe.NewCiphertext(params, 1, params.MaxLevelQ())
|
||||
|
||||
rgswEnc, err := NewEncryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
rgswEnc.Encrypt(ptRGSW, ctRGSW)
|
||||
|
||||
rlweEnc, err := rlwe.NewEncryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
rlweEnc.Encrypt(ptRLWE, ctRLWE)
|
||||
NewEncryptor(params, sk).Encrypt(ptRGSW, ctRGSW)
|
||||
rlwe.NewEncryptor(params, sk).Encrypt(ptRLWE, ctRLWE)
|
||||
|
||||
// X^{k0} * Scale * X^{k1}
|
||||
NewEvaluator(params, nil).ExternalProduct(ctRLWE, ctRGSW, ctRLWE)
|
||||
|
||||
dec, err := rlwe.NewDecryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
ptHave := dec.DecryptNew(ctRLWE)
|
||||
ptHave := rlwe.NewDecryptor(params, sk).DecryptNew(ctRLWE)
|
||||
|
||||
params.RingQ().INTT(ptHave.Value, ptHave.Value)
|
||||
|
||||
@@ -130,9 +114,7 @@ func TestRGSW(t *testing.T) {
|
||||
|
||||
t.Run("WriteAndRead", func(t *testing.T) {
|
||||
ct := NewCiphertext(params, params.MaxLevelQ(), params.MaxLevelP(), 0)
|
||||
enc, err := NewEncryptor(params, pk)
|
||||
require.NoError(t, err)
|
||||
enc.Encrypt(nil, ct)
|
||||
NewEncryptor(params, pk).Encrypt(nil, ct)
|
||||
buffer.RequireSerializerCorrect(t, ct)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@ type Decryptor struct {
|
||||
}
|
||||
|
||||
// NewDecryptor instantiates a new generic RLWE Decryptor.
|
||||
func NewDecryptor(params ParameterProvider, sk *SecretKey) (*Decryptor, error) {
|
||||
func NewDecryptor(params ParameterProvider, sk *SecretKey) *Decryptor {
|
||||
|
||||
p := params.GetRLWEParameters()
|
||||
|
||||
if sk.Value.Q.N() != p.N() {
|
||||
return nil, fmt.Errorf("cannot NewDecryptor: secret_key ring degree does not match parameters ring degree")
|
||||
panic(fmt.Errorf("cannot NewDecryptor: secret_key ring degree does not match parameters ring degree"))
|
||||
}
|
||||
|
||||
return &Decryptor{
|
||||
@@ -29,7 +29,7 @@ func NewDecryptor(params ParameterProvider, sk *SecretKey) (*Decryptor, error) {
|
||||
ringQ: p.RingQ(),
|
||||
buff: p.RingQ().NewPoly(),
|
||||
sk: sk,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// DecryptNew decrypts the Ciphertext and returns the result in a new Plaintext.
|
||||
|
||||
@@ -17,7 +17,7 @@ type EncryptionKey interface {
|
||||
}
|
||||
|
||||
// NewEncryptor creates a new Encryptor from either a public key or a private key.
|
||||
func NewEncryptor(params ParameterProvider, key EncryptionKey) (*Encryptor, error) {
|
||||
func NewEncryptor(params ParameterProvider, key EncryptionKey) *Encryptor {
|
||||
|
||||
p := *params.GetRLWEParameters()
|
||||
|
||||
@@ -29,15 +29,15 @@ func NewEncryptor(params ParameterProvider, key EncryptionKey) (*Encryptor, erro
|
||||
case *SecretKey:
|
||||
err = enc.checkSk(key)
|
||||
case nil:
|
||||
return newEncryptor(p), nil
|
||||
return newEncryptor(p)
|
||||
default:
|
||||
return nil, fmt.Errorf("key must be either *rlwe.PublicKey, *rlwe.SecretKey or nil but have %T", key)
|
||||
panic(fmt.Errorf("key must be either *rlwe.PublicKey, *rlwe.SecretKey or nil but have %T", key))
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("key is not correct: %w", err)
|
||||
panic(fmt.Errorf("key is not correct: %w", err))
|
||||
}
|
||||
enc.encKey = key
|
||||
return enc, nil
|
||||
return enc
|
||||
}
|
||||
|
||||
type Encryptor struct {
|
||||
@@ -439,27 +439,26 @@ func (enc Encryptor) WithPRNG(prng sampling.PRNG) *Encryptor {
|
||||
}
|
||||
|
||||
func (enc Encryptor) ShallowCopy() *Encryptor {
|
||||
encSh, _ := NewEncryptor(enc.params, enc.encKey)
|
||||
return encSh
|
||||
return NewEncryptor(enc.params, enc.encKey)
|
||||
}
|
||||
|
||||
func (enc Encryptor) WithKey(key EncryptionKey) (*Encryptor, error) {
|
||||
func (enc Encryptor) WithKey(key EncryptionKey) *Encryptor {
|
||||
switch key := key.(type) {
|
||||
case *SecretKey:
|
||||
if err := enc.checkSk(key); err != nil {
|
||||
return nil, fmt.Errorf("cannot WithKey: %w", err)
|
||||
panic(fmt.Errorf("cannot WithKey: %w", err))
|
||||
}
|
||||
case *PublicKey:
|
||||
if err := enc.checkPk(key); err != nil {
|
||||
return nil, fmt.Errorf("cannot WithKey: %w", err)
|
||||
panic(fmt.Errorf("cannot WithKey: %w", err))
|
||||
}
|
||||
case nil:
|
||||
return &enc, nil
|
||||
return &enc
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid key type, want *rlwe.SecretKey, *rlwe.PublicKey or nil but have %T", key)
|
||||
panic(fmt.Errorf("invalid key type, want *rlwe.SecretKey, *rlwe.PublicKey or nil but have %T", key))
|
||||
}
|
||||
enc.encKey = key
|
||||
return &enc, nil
|
||||
return &enc
|
||||
}
|
||||
|
||||
// checkPk checks that a given pk is correct for the parameters.
|
||||
|
||||
@@ -16,12 +16,8 @@ type KeyGenerator struct {
|
||||
|
||||
// NewKeyGenerator creates a new KeyGenerator, from which the secret and public keys, as well as EvaluationKeys.
|
||||
func NewKeyGenerator(params ParameterProvider) *KeyGenerator {
|
||||
enc, err := NewEncryptor(params, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &KeyGenerator{
|
||||
Encryptor: enc,
|
||||
Encryptor: NewEncryptor(params, nil),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,60 +66,58 @@ func (kgen KeyGenerator) genSecretKeyFromSampler(sampler ring.Sampler, sk *Secre
|
||||
}
|
||||
|
||||
// GenPublicKeyNew generates a new public key from the provided SecretKey.
|
||||
func (kgen KeyGenerator) GenPublicKeyNew(sk *SecretKey) (pk *PublicKey, err error) {
|
||||
func (kgen KeyGenerator) GenPublicKeyNew(sk *SecretKey) (pk *PublicKey) {
|
||||
pk = NewPublicKey(kgen.params)
|
||||
return pk, kgen.GenPublicKey(sk, pk)
|
||||
kgen.GenPublicKey(sk, pk)
|
||||
return
|
||||
}
|
||||
|
||||
// GenPublicKey generates a public key from the provided SecretKey.
|
||||
func (kgen KeyGenerator) GenPublicKey(sk *SecretKey, pk *PublicKey) (err error) {
|
||||
enc, err := kgen.WithKey(sk)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot GenPublicKey: %w", err)
|
||||
}
|
||||
|
||||
return enc.EncryptZero(Operand[ringqp.Poly]{
|
||||
func (kgen KeyGenerator) GenPublicKey(sk *SecretKey, pk *PublicKey) {
|
||||
if err := kgen.WithKey(sk).EncryptZero(Operand[ringqp.Poly]{
|
||||
MetaData: &MetaData{CiphertextMetaData: CiphertextMetaData{IsNTT: true, IsMontgomery: true}},
|
||||
Value: []ringqp.Poly(pk.Value)})
|
||||
Value: []ringqp.Poly(pk.Value),
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// GenKeyPairNew generates a new SecretKey and a corresponding public key.
|
||||
// Distribution is of the SecretKey set according to `rlwe.Parameters.HammingWeight()`.
|
||||
func (kgen KeyGenerator) GenKeyPairNew() (sk *SecretKey, pk *PublicKey) {
|
||||
sk = kgen.GenSecretKeyNew()
|
||||
var err error
|
||||
if pk, err = kgen.GenPublicKeyNew(sk); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pk = kgen.GenPublicKeyNew(sk)
|
||||
return
|
||||
}
|
||||
|
||||
// GenRelinearizationKeyNew generates a new EvaluationKey that will be used to relinearize Ciphertexts during multiplication.
|
||||
func (kgen KeyGenerator) GenRelinearizationKeyNew(sk *SecretKey, evkParams ...EvaluationKeyParameters) (rlk *RelinearizationKey, err error) {
|
||||
func (kgen KeyGenerator) GenRelinearizationKeyNew(sk *SecretKey, evkParams ...EvaluationKeyParameters) (rlk *RelinearizationKey) {
|
||||
levelQ, levelP, BaseTwoDecomposition := ResolveEvaluationKeyParameters(kgen.params, evkParams)
|
||||
rlk = &RelinearizationKey{EvaluationKey: EvaluationKey{GadgetCiphertext: *NewGadgetCiphertext(kgen.params, 1, levelQ, levelP, BaseTwoDecomposition)}}
|
||||
return rlk, kgen.GenRelinearizationKey(sk, rlk)
|
||||
kgen.GenRelinearizationKey(sk, rlk)
|
||||
return
|
||||
}
|
||||
|
||||
// GenRelinearizationKey generates an EvaluationKey that will be used to relinearize Ciphertexts during multiplication.
|
||||
func (kgen KeyGenerator) GenRelinearizationKey(sk *SecretKey, rlk *RelinearizationKey) (err error) {
|
||||
func (kgen KeyGenerator) GenRelinearizationKey(sk *SecretKey, rlk *RelinearizationKey) {
|
||||
kgen.buffQP.Q.CopyValues(sk.Value.Q)
|
||||
kgen.params.RingQ().AtLevel(rlk.LevelQ()).MulCoeffsMontgomery(kgen.buffQP.Q, sk.Value.Q, kgen.buffQP.Q)
|
||||
return kgen.genEvaluationKey(kgen.buffQP.Q, sk.Value, &rlk.EvaluationKey)
|
||||
kgen.genEvaluationKey(kgen.buffQP.Q, sk.Value, &rlk.EvaluationKey)
|
||||
}
|
||||
|
||||
// GenGaloisKeyNew generates a new GaloisKey, enabling the automorphism X^{i} -> X^{i * galEl}.
|
||||
func (kgen KeyGenerator) GenGaloisKeyNew(galEl uint64, sk *SecretKey, evkParams ...EvaluationKeyParameters) (gk *GaloisKey, err error) {
|
||||
func (kgen KeyGenerator) GenGaloisKeyNew(galEl uint64, sk *SecretKey, evkParams ...EvaluationKeyParameters) (gk *GaloisKey) {
|
||||
levelQ, levelP, BaseTwoDecomposition := ResolveEvaluationKeyParameters(kgen.params, evkParams)
|
||||
gk = &GaloisKey{
|
||||
EvaluationKey: EvaluationKey{GadgetCiphertext: *NewGadgetCiphertext(kgen.params, 1, levelQ, levelP, BaseTwoDecomposition)},
|
||||
NthRoot: kgen.params.GetRLWEParameters().RingQ().NthRoot(),
|
||||
}
|
||||
return gk, kgen.GenGaloisKey(galEl, sk, gk)
|
||||
kgen.GenGaloisKey(galEl, sk, gk)
|
||||
return
|
||||
}
|
||||
|
||||
// GenGaloisKey generates a GaloisKey, enabling the automorphism X^{i} -> X^{i * galEl}.
|
||||
func (kgen KeyGenerator) GenGaloisKey(galEl uint64, sk *SecretKey, gk *GaloisKey) (err error) {
|
||||
func (kgen KeyGenerator) GenGaloisKey(galEl uint64, sk *SecretKey, gk *GaloisKey) {
|
||||
|
||||
skIn := sk.Value
|
||||
skOut := kgen.buffQP
|
||||
@@ -151,55 +145,42 @@ func (kgen KeyGenerator) GenGaloisKey(galEl uint64, sk *SecretKey, gk *GaloisKey
|
||||
ringP.AutomorphismNTTWithIndex(skIn.P, index, skOut.P)
|
||||
}
|
||||
|
||||
if err = kgen.genEvaluationKey(skIn.Q, skOut, &gk.EvaluationKey); err != nil {
|
||||
return fmt.Errorf("cannot GenGaloisKey: %w", err)
|
||||
}
|
||||
kgen.genEvaluationKey(skIn.Q, skOut, &gk.EvaluationKey)
|
||||
|
||||
gk.GaloisElement = galEl
|
||||
gk.NthRoot = ringQ.NthRoot()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GenGaloisKeys generates the GaloisKey objects for all galois elements in galEls, and stores
|
||||
// the resulting key for galois element i in gks[i].
|
||||
// The galEls and gks parameters must have the same length.
|
||||
func (kgen KeyGenerator) GenGaloisKeys(galEls []uint64, sk *SecretKey, gks []*GaloisKey) (err error) {
|
||||
func (kgen KeyGenerator) GenGaloisKeys(galEls []uint64, sk *SecretKey, gks []*GaloisKey) {
|
||||
if len(galEls) != len(gks) {
|
||||
return fmt.Errorf("galEls and gks must have the same length")
|
||||
panic(fmt.Errorf("galEls and gks must have the same length"))
|
||||
}
|
||||
for i, galEl := range galEls {
|
||||
if gks[i] == nil {
|
||||
if gks[i], err = kgen.GenGaloisKeyNew(galEl, sk); err != nil {
|
||||
return
|
||||
}
|
||||
gks[i] = kgen.GenGaloisKeyNew(galEl, sk)
|
||||
} else {
|
||||
return kgen.GenGaloisKey(galEl, sk, gks[i])
|
||||
kgen.GenGaloisKey(galEl, sk, gks[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenGaloisKeysNew generates the GaloisKey objects for all galois elements in galEls, and
|
||||
// returns the resulting keys in a newly allocated []*GaloisKey.
|
||||
func (kgen KeyGenerator) GenGaloisKeysNew(galEls []uint64, sk *SecretKey, evkParams ...EvaluationKeyParameters) (gks []*GaloisKey, err error) {
|
||||
|
||||
func (kgen KeyGenerator) GenGaloisKeysNew(galEls []uint64, sk *SecretKey, evkParams ...EvaluationKeyParameters) (gks []*GaloisKey) {
|
||||
levelQ, levelP, BaseTwoDecomposition := ResolveEvaluationKeyParameters(kgen.params, evkParams)
|
||||
|
||||
gks = make([]*GaloisKey, len(galEls))
|
||||
for i, galEl := range galEls {
|
||||
|
||||
gks[i] = newGaloisKey(kgen.params, levelQ, levelP, BaseTwoDecomposition)
|
||||
|
||||
if err = kgen.GenGaloisKey(galEl, sk, gks[i]); err != nil {
|
||||
return
|
||||
}
|
||||
kgen.GenGaloisKey(galEl, sk, gks[i])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GenEvaluationKeysForRingSwapNew generates the necessary EvaluationKeys to switch from a standard ring to to a conjugate invariant ring and vice-versa.
|
||||
func (kgen KeyGenerator) GenEvaluationKeysForRingSwapNew(skStd, skConjugateInvariant *SecretKey, evkParams ...EvaluationKeyParameters) (stdToci, ciToStd *EvaluationKey, err error) {
|
||||
func (kgen KeyGenerator) GenEvaluationKeysForRingSwapNew(skStd, skConjugateInvariant *SecretKey, evkParams ...EvaluationKeyParameters) (stdToci, ciToStd *EvaluationKey) {
|
||||
|
||||
levelQ := utils.Min(skStd.Value.Q.Level(), skConjugateInvariant.Value.Q.Level())
|
||||
|
||||
@@ -213,14 +194,10 @@ func (kgen KeyGenerator) GenEvaluationKeysForRingSwapNew(skStd, skConjugateInvar
|
||||
levelQ, levelP, BaseTwoDecomposition := ResolveEvaluationKeyParameters(kgen.params, evkParams)
|
||||
|
||||
stdToci = newEvaluationKey(kgen.params, levelQ, levelP, BaseTwoDecomposition)
|
||||
if err = kgen.GenEvaluationKey(skStd, skCIMappedToStandard, stdToci); err != nil {
|
||||
return
|
||||
}
|
||||
kgen.GenEvaluationKey(skStd, skCIMappedToStandard, stdToci)
|
||||
|
||||
ciToStd = newEvaluationKey(kgen.params, levelQ, levelP, BaseTwoDecomposition)
|
||||
if err = kgen.GenEvaluationKey(skCIMappedToStandard, skStd, ciToStd); err != nil {
|
||||
return
|
||||
}
|
||||
kgen.GenEvaluationKey(skCIMappedToStandard, skStd, ciToStd)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -234,10 +211,11 @@ func (kgen KeyGenerator) GenEvaluationKeysForRingSwapNew(skStd, skConjugateInvar
|
||||
// using SwitchCiphertextRingDegreeNTT(ctSmallDim, nil, ctLargeDim).
|
||||
// When re-encrypting a Ciphertext from X^{N} to Y^{N/n}, the output of the re-encryption is in still X^{N} and
|
||||
// must be mapped Y^{N/n} using SwitchCiphertextRingDegreeNTT(ctLargeDim, ringQLargeDim, ctSmallDim).
|
||||
func (kgen KeyGenerator) GenEvaluationKeyNew(skInput, skOutput *SecretKey, evkParams ...EvaluationKeyParameters) (evk *EvaluationKey, err error) {
|
||||
func (kgen KeyGenerator) GenEvaluationKeyNew(skInput, skOutput *SecretKey, evkParams ...EvaluationKeyParameters) (evk *EvaluationKey) {
|
||||
levelQ, levelP, BaseTwoDecomposition := ResolveEvaluationKeyParameters(kgen.params, evkParams)
|
||||
evk = newEvaluationKey(kgen.params, levelQ, levelP, BaseTwoDecomposition)
|
||||
return evk, kgen.GenEvaluationKey(skInput, skOutput, evk)
|
||||
kgen.GenEvaluationKey(skInput, skOutput, evk)
|
||||
return
|
||||
}
|
||||
|
||||
// GenEvaluationKey generates an EvaluationKey, that will re-encrypt a Ciphertext encrypted under the input key into the output key.
|
||||
@@ -249,7 +227,7 @@ func (kgen KeyGenerator) GenEvaluationKeyNew(skInput, skOutput *SecretKey, evkPa
|
||||
// using SwitchCiphertextRingDegreeNTT(ctSmallDim, nil, ctLargeDim).
|
||||
// When re-encrypting a Ciphertext from X^{N} to Y^{N/n}, the output of the re-encryption is in still X^{N} and
|
||||
// must be mapped Y^{N/n} using SwitchCiphertextRingDegreeNTT(ctLargeDim, ringQLargeDim, ctSmallDim).
|
||||
func (kgen KeyGenerator) GenEvaluationKey(skInput, skOutput *SecretKey, evk *EvaluationKey) (err error) {
|
||||
func (kgen KeyGenerator) GenEvaluationKey(skInput, skOutput *SecretKey, evk *EvaluationKey) {
|
||||
|
||||
ringQ := kgen.params.RingQ()
|
||||
ringP := kgen.params.RingP()
|
||||
@@ -266,7 +244,7 @@ func (kgen KeyGenerator) GenEvaluationKey(skInput, skOutput *SecretKey, evk *Eva
|
||||
ring.MapSmallDimensionToLargerDimensionNTT(skInput.Value.Q, kgen.buffQ[0])
|
||||
kgen.extendQ2P(ringQ, ringQ.AtLevel(skOutput.Value.Q.Level()), kgen.buffQ[0], kgen.buffQ[1], kgen.buffQ[0])
|
||||
|
||||
return kgen.genEvaluationKey(kgen.buffQ[0], kgen.buffQP, evk)
|
||||
kgen.genEvaluationKey(kgen.buffQ[0], kgen.buffQP, evk)
|
||||
}
|
||||
|
||||
func (kgen KeyGenerator) extendQ2P2(levelP int, polQ, buff, polP ring.Poly) {
|
||||
@@ -340,21 +318,21 @@ func (kgen KeyGenerator) extendQ2P(rQ, rP *ring.Ring, polQ, buff, polP ring.Poly
|
||||
rP.MForm(polP, polP)
|
||||
}
|
||||
|
||||
func (kgen KeyGenerator) genEvaluationKey(skIn ring.Poly, skOut ringqp.Poly, evk *EvaluationKey) (err error) {
|
||||
func (kgen KeyGenerator) genEvaluationKey(skIn ring.Poly, skOut ringqp.Poly, evk *EvaluationKey) {
|
||||
|
||||
enc := kgen.WithKey(&SecretKey{Value: skOut})
|
||||
|
||||
enc, err := kgen.WithKey(&SecretKey{Value: skOut})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Samples an encryption of zero for each element of the EvaluationKey.
|
||||
for i := 0; i < len(evk.Value); i++ {
|
||||
for j := 0; j < len(evk.Value[i]); j++ {
|
||||
if err = enc.EncryptZero(Operand[ringqp.Poly]{MetaData: &MetaData{CiphertextMetaData: CiphertextMetaData{IsNTT: true, IsMontgomery: true}}, Value: []ringqp.Poly(evk.Value[i][j])}); err != nil {
|
||||
return
|
||||
if err := enc.EncryptZero(Operand[ringqp.Poly]{MetaData: &MetaData{CiphertextMetaData: CiphertextMetaData{IsNTT: true, IsMontgomery: true}}, Value: []ringqp.Poly(evk.Value[i][j])}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adds the plaintext (input-key) to the EvaluationKey.
|
||||
return AddPolyTimesGadgetVectorToGadgetCiphertext(skIn, []GadgetCiphertext{evk.GadgetCiphertext}, *kgen.params.RingQP(), kgen.buffQ[0])
|
||||
if err := AddPolyTimesGadgetVectorToGadgetCiphertext(skIn, []GadgetCiphertext{evk.GadgetCiphertext}, *kgen.params.RingQP(), kgen.buffQ[0]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,10 +82,7 @@ func benchEncryptor(tc *TestContext, bpw2 int, b *testing.B) {
|
||||
|
||||
b.Run(testString(params, params.MaxLevelQ(), params.MaxLevelP(), bpw2, "Encryptor/EncryptZero/SecretKey"), func(b *testing.B) {
|
||||
ct := NewCiphertext(params, 1, params.MaxLevel())
|
||||
enc, err := tc.enc.WithKey(tc.sk)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
enc := tc.enc.WithKey(tc.sk)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
enc.EncryptZero(ct)
|
||||
@@ -95,10 +92,7 @@ func benchEncryptor(tc *TestContext, bpw2 int, b *testing.B) {
|
||||
|
||||
b.Run(testString(params, params.MaxLevelQ(), params.MaxLevelP(), bpw2, "Encryptor/EncryptZero/PublicKey"), func(b *testing.B) {
|
||||
ct := NewCiphertext(params, 1, params.MaxLevel())
|
||||
enc, err := tc.enc.WithKey(tc.pk)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
enc := tc.enc.WithKey(tc.pk)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
enc.EncryptZero(ct)
|
||||
@@ -130,19 +124,11 @@ func benchEvaluator(tc *TestContext, bpw2 int, b *testing.B) {
|
||||
|
||||
b.Run(testString(params, params.MaxLevelQ(), params.MaxLevelP(), bpw2, "Evaluator/GadgetProduct"), func(b *testing.B) {
|
||||
|
||||
enc, err := NewEncryptor(params, sk)
|
||||
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
enc := NewEncryptor(params, sk)
|
||||
|
||||
ct := enc.EncryptZeroNew(params.MaxLevel())
|
||||
|
||||
evk, err := kgen.GenEvaluationKeyNew(sk, kgen.GenSecretKeyNew())
|
||||
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
evk := kgen.GenEvaluationKeyNew(sk, kgen.GenSecretKeyNew())
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
@@ -155,11 +141,7 @@ func benchMarshalling(tc *TestContext, bpw2 int, b *testing.B) {
|
||||
params := tc.params
|
||||
sk := tc.sk
|
||||
|
||||
enc, err := NewEncryptor(params, sk)
|
||||
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
enc := NewEncryptor(params, sk)
|
||||
|
||||
ctf := enc.EncryptZeroNew(params.MaxLevel())
|
||||
|
||||
|
||||
@@ -155,22 +155,13 @@ func NewTestContext(params Parameters) (tc *TestContext, err error) {
|
||||
kgen := NewKeyGenerator(params)
|
||||
sk := kgen.GenSecretKeyNew()
|
||||
|
||||
pk, err := kgen.GenPublicKeyNew(sk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pk := kgen.GenPublicKeyNew(sk)
|
||||
|
||||
eval := NewEvaluator(params, nil)
|
||||
|
||||
enc, err := NewEncryptor(params, sk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
enc := NewEncryptor(params, sk)
|
||||
|
||||
dec, err := NewDecryptor(params, sk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dec := NewDecryptor(params, sk)
|
||||
|
||||
return &TestContext{
|
||||
params: params,
|
||||
@@ -378,12 +369,7 @@ func testEncryptor(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
pt := NewPlaintext(params, level)
|
||||
ct := NewCiphertext(params, 1, level)
|
||||
|
||||
encPk, err := enc.WithKey(pk)
|
||||
|
||||
//encPk, err := enc.WithKey(pk)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, encPk.Encrypt(pt, ct))
|
||||
enc.WithKey(pk).Encrypt(pt, ct)
|
||||
|
||||
dec.Decrypt(ct, pt)
|
||||
|
||||
@@ -397,8 +383,7 @@ func testEncryptor(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run(testString(params, level, params.MaxLevelP(), bpw2, "Encryptor/Encrypt/Pk/ShallowCopy"), func(t *testing.T) {
|
||||
pkEnc1, err := enc.WithKey(pk)
|
||||
require.NoError(t, err)
|
||||
pkEnc1 := enc.WithKey(pk)
|
||||
pkEnc2 := pkEnc1.ShallowCopy()
|
||||
require.True(t, pkEnc1.params.Equal(pkEnc2.params))
|
||||
require.True(t, pkEnc1.encKey == pkEnc2.encKey)
|
||||
@@ -428,8 +413,7 @@ func testEncryptor(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
|
||||
pt := NewPlaintext(params, level)
|
||||
|
||||
enc, err := NewEncryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
enc := NewEncryptor(params, sk)
|
||||
|
||||
ct := NewCiphertext(params, 1, level)
|
||||
|
||||
@@ -452,8 +436,7 @@ func testEncryptor(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run(testString(params, level, params.MaxLevelP(), bpw2, "Encrypt/Sk/ShallowCopy"), func(t *testing.T) {
|
||||
skEnc1, err := NewEncryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
skEnc1 := NewEncryptor(params, sk)
|
||||
skEnc2 := skEnc1.ShallowCopy()
|
||||
|
||||
require.True(t, skEnc1.params.Equal(skEnc2.params))
|
||||
@@ -466,11 +449,8 @@ func testEncryptor(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
|
||||
t.Run(testString(params, level, params.MaxLevelP(), bpw2, "Encrypt/WithKey/Sk->Sk"), func(t *testing.T) {
|
||||
sk2 := kgen.GenSecretKeyNew()
|
||||
skEnc1, err := NewEncryptor(params, sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
skEnc2, err := skEnc1.WithKey(sk2)
|
||||
require.NoError(t, err)
|
||||
skEnc1 := NewEncryptor(params, sk)
|
||||
skEnc2 := skEnc1.WithKey(sk2)
|
||||
require.True(t, skEnc1.params.Equal(skEnc2.params))
|
||||
require.True(t, skEnc1.encKey == sk)
|
||||
require.True(t, skEnc2.encKey == sk2)
|
||||
@@ -519,14 +499,13 @@ func testGadgetProduct(tc *TestContext, levelQ, bpw2 int, t *testing.T) {
|
||||
evk := NewEvaluationKey(params, evkParams)
|
||||
|
||||
// Generate the evaluationkey [-bs1 + s1, b]
|
||||
require.NoError(t, kgen.GenEvaluationKey(sk, skOut, evk))
|
||||
kgen.GenEvaluationKey(sk, skOut, evk)
|
||||
|
||||
// Gadget product: ct = [-cs1 + as0 , c]
|
||||
eval.GadgetProduct(levelQ, a, &evk.GadgetCiphertext, ct)
|
||||
|
||||
// pt = as0
|
||||
dec, err := NewDecryptor(params, skOut)
|
||||
require.NoError(t, err)
|
||||
dec := NewDecryptor(params, skOut)
|
||||
|
||||
pt := dec.DecryptNew(ct)
|
||||
|
||||
@@ -574,10 +553,7 @@ func testGadgetProduct(tc *TestContext, levelQ, bpw2 int, t *testing.T) {
|
||||
eval.GadgetProductHoisted(levelQ, eval.BuffDecompQP, &evk.GadgetCiphertext, ct)
|
||||
|
||||
// pt = as0
|
||||
dec, err := NewDecryptor(params, skOut)
|
||||
require.NoError(t, err)
|
||||
|
||||
pt := dec.DecryptNew(ct)
|
||||
pt := NewDecryptor(params, skOut).DecryptNew(ct)
|
||||
|
||||
ringQ := params.RingQ().AtLevel(levelQ)
|
||||
|
||||
@@ -619,15 +595,9 @@ func testApplyEvaluationKey(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
enc.Encrypt(pt, ct)
|
||||
|
||||
// Test that Dec(KS(Enc(ct, sk), skOut), skOut) has a small norm
|
||||
evk, err := kgen.GenEvaluationKeyNew(sk, skOut, evkParams)
|
||||
require.NoError(t, err)
|
||||
eval.ApplyEvaluationKey(ct, kgen.GenEvaluationKeyNew(sk, skOut, evkParams), ct)
|
||||
|
||||
eval.ApplyEvaluationKey(ct, evk, ct)
|
||||
|
||||
dec, err := NewDecryptor(params, skOut)
|
||||
require.NoError(t, err)
|
||||
|
||||
dec.Decrypt(ct, pt)
|
||||
NewDecryptor(params, skOut).Decrypt(ct, pt)
|
||||
|
||||
ringQ := params.RingQ().AtLevel(level)
|
||||
|
||||
@@ -656,11 +626,9 @@ func testApplyEvaluationKey(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
kgenSmallDim := NewKeyGenerator(paramsSmallDim)
|
||||
skSmallDim := kgenSmallDim.GenSecretKeyNew()
|
||||
|
||||
evk, err := kgenLargeDim.GenEvaluationKeyNew(skLargeDim, skSmallDim, evkParams)
|
||||
require.NoError(t, err)
|
||||
evk := kgenLargeDim.GenEvaluationKeyNew(skLargeDim, skSmallDim, evkParams)
|
||||
|
||||
enc, err := NewEncryptor(paramsLargeDim, skLargeDim)
|
||||
require.NoError(t, err)
|
||||
enc := NewEncryptor(paramsLargeDim, skLargeDim)
|
||||
|
||||
ctLargeDim := enc.EncryptZeroNew(level)
|
||||
|
||||
@@ -670,8 +638,7 @@ func testApplyEvaluationKey(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
eval.ApplyEvaluationKey(ctLargeDim, evk, ctSmallDim)
|
||||
|
||||
// Decrypts with smaller dimension key
|
||||
dec, err := NewDecryptor(paramsSmallDim, skSmallDim)
|
||||
require.NoError(t, err)
|
||||
dec := NewDecryptor(paramsSmallDim, skSmallDim)
|
||||
|
||||
ptSmallDim := dec.DecryptNew(ctSmallDim)
|
||||
|
||||
@@ -701,13 +668,9 @@ func testApplyEvaluationKey(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
kgenSmallDim := NewKeyGenerator(paramsSmallDim)
|
||||
skSmallDim := kgenSmallDim.GenSecretKeyNew()
|
||||
|
||||
evk, err := kgenLargeDim.GenEvaluationKeyNew(skSmallDim, skLargeDim, evkParams)
|
||||
require.NoError(t, err)
|
||||
evk := kgenLargeDim.GenEvaluationKeyNew(skSmallDim, skLargeDim, evkParams)
|
||||
|
||||
enc, err := NewEncryptor(paramsSmallDim, skSmallDim)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctSmallDim := enc.EncryptZeroNew(level)
|
||||
ctSmallDim := NewEncryptor(paramsSmallDim, skSmallDim).EncryptZeroNew(level)
|
||||
|
||||
ctLargeDim := NewCiphertext(paramsLargeDim, 1, level)
|
||||
|
||||
@@ -753,12 +716,8 @@ func testAutomorphism(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
// Chooses a Galois Element (must be coprime with 2N)
|
||||
galEl := params.GaloisElement(-1)
|
||||
|
||||
// Generate the GaloisKey
|
||||
gk, err := kgen.GenGaloisKeyNew(galEl, sk, evkParams)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Allocate a new EvaluationKeySet and adds the GaloisKey
|
||||
evk := NewMemEvaluationKeySet(nil, gk)
|
||||
evk := NewMemEvaluationKeySet(nil, kgen.GenGaloisKeyNew(galEl, sk, evkParams))
|
||||
|
||||
// Evaluate the automorphism
|
||||
eval.WithKey(evk).Automorphism(ct, galEl, ct)
|
||||
@@ -804,12 +763,8 @@ func testAutomorphism(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
// Chooses a Galois Element (must be coprime with 2N)
|
||||
galEl := params.GaloisElement(-1)
|
||||
|
||||
// Generate the GaloisKey
|
||||
gk, err := kgen.GenGaloisKeyNew(galEl, sk, evkParams)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Allocate a new EvaluationKeySet and adds the GaloisKey
|
||||
evk := NewMemEvaluationKeySet(nil, gk)
|
||||
evk := NewMemEvaluationKeySet(nil, kgen.GenGaloisKeyNew(galEl, sk, evkParams))
|
||||
|
||||
//Decompose the ciphertext
|
||||
eval.DecomposeNTT(level, params.MaxLevelP(), params.MaxLevelP()+1, ct.Value[1], ct.IsNTT, eval.BuffDecompQP)
|
||||
@@ -858,12 +813,8 @@ func testAutomorphism(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
// Chooses a Galois Element (must be coprime with 2N)
|
||||
galEl := params.GaloisElement(-1)
|
||||
|
||||
// Generate the GaloisKey
|
||||
gk, err := kgen.GenGaloisKeyNew(galEl, sk, evkParams)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Allocate a new EvaluationKeySet and adds the GaloisKey
|
||||
evk := NewMemEvaluationKeySet(nil, gk)
|
||||
evk := NewMemEvaluationKeySet(nil, kgen.GenGaloisKeyNew(galEl, sk, evkParams))
|
||||
|
||||
//Decompose the ciphertext
|
||||
eval.DecomposeNTT(level, params.MaxLevelP(), params.MaxLevelP()+1, ct.Value[1], ct.IsNTT, eval.BuffDecompQP)
|
||||
@@ -945,10 +896,7 @@ func testSlotOperations(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
enc.Encrypt(pt, ctIn)
|
||||
|
||||
// GaloisKeys
|
||||
var gks, err = kgen.GenGaloisKeysNew(GaloisElementsForExpand(params, logN), sk, evkParams)
|
||||
require.NoError(t, err)
|
||||
|
||||
evk := NewMemEvaluationKeySet(nil, gks...)
|
||||
evk := NewMemEvaluationKeySet(nil, kgen.GenGaloisKeysNew(GaloisElementsForExpand(params, logN), sk, evkParams)...)
|
||||
|
||||
eval := NewEvaluator(params, evk)
|
||||
|
||||
@@ -1016,10 +964,7 @@ func testSlotOperations(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
}
|
||||
|
||||
// Galois Keys
|
||||
gks, err := kgen.GenGaloisKeysNew(GaloisElementsForPack(params, params.LogN()), sk, evkParams)
|
||||
require.NoError(t, err)
|
||||
|
||||
evk := NewMemEvaluationKeySet(nil, gks...)
|
||||
evk := NewMemEvaluationKeySet(nil, kgen.GenGaloisKeysNew(GaloisElementsForPack(params, params.LogN()), sk, evkParams)...)
|
||||
|
||||
ct, err := eval.WithKey(evk).Pack(ciphertexts, params.LogN(), false)
|
||||
require.NoError(t, err)
|
||||
@@ -1091,10 +1036,7 @@ func testSlotOperations(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
}
|
||||
|
||||
// Galois Keys
|
||||
gks, err := kgen.GenGaloisKeysNew(GaloisElementsForPack(params, params.LogN()-1), sk, evkParams)
|
||||
require.NoError(t, err)
|
||||
|
||||
evk := NewMemEvaluationKeySet(nil, gks...)
|
||||
evk := NewMemEvaluationKeySet(nil, kgen.GenGaloisKeysNew(GaloisElementsForPack(params, params.LogN()-1), sk, evkParams)...)
|
||||
|
||||
ct, err := eval.WithKey(evk).Pack(ciphertexts, params.LogN()-1, true)
|
||||
require.NoError(t, err)
|
||||
@@ -1134,12 +1076,9 @@ func testSlotOperations(tc *TestContext, level, bpw2 int, t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Galois Keys
|
||||
gks, err := kgen.GenGaloisKeysNew(GaloisElementsForInnerSum(params, batch, n), sk)
|
||||
require.NoError(t, err)
|
||||
evk := NewMemEvaluationKeySet(nil, kgen.GenGaloisKeysNew(GaloisElementsForInnerSum(params, batch, n), sk)...)
|
||||
|
||||
evk := NewMemEvaluationKeySet(nil, gks...)
|
||||
|
||||
eval.WithKey(evk).InnerSum(ct, batch, n, ct)
|
||||
require.NoError(t, eval.WithKey(evk).InnerSum(ct, batch, n, ct))
|
||||
|
||||
dec.Decrypt(ct, pt)
|
||||
|
||||
@@ -1275,34 +1214,22 @@ func testWriteAndRead(tc *TestContext, bpw2 int, t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run(testString(params, levelQ, levelP, bpw2, "WriteAndRead/EvaluationKey"), func(t *testing.T) {
|
||||
evk, err := tc.kgen.GenEvaluationKeyNew(sk, sk)
|
||||
require.NoError(t, err)
|
||||
buffer.RequireSerializerCorrect(t, evk)
|
||||
buffer.RequireSerializerCorrect(t, tc.kgen.GenEvaluationKeyNew(sk, sk))
|
||||
})
|
||||
|
||||
t.Run(testString(params, levelQ, levelP, bpw2, "WriteAndRead/RelinearizationKey"), func(t *testing.T) {
|
||||
rlk, err := tc.kgen.GenRelinearizationKeyNew(tc.sk)
|
||||
require.NoError(t, err)
|
||||
buffer.RequireSerializerCorrect(t, rlk)
|
||||
buffer.RequireSerializerCorrect(t, tc.kgen.GenRelinearizationKeyNew(tc.sk))
|
||||
})
|
||||
|
||||
t.Run(testString(params, levelQ, levelP, bpw2, "WriteAndRead/GaloisKey"), func(t *testing.T) {
|
||||
gk, err := tc.kgen.GenGaloisKeyNew(5, tc.sk)
|
||||
require.NoError(t, err)
|
||||
buffer.RequireSerializerCorrect(t, gk)
|
||||
buffer.RequireSerializerCorrect(t, tc.kgen.GenGaloisKeyNew(5, tc.sk))
|
||||
})
|
||||
|
||||
t.Run(testString(params, levelQ, levelP, bpw2, "WriteAndRead/EvaluationKeySet"), func(t *testing.T) {
|
||||
|
||||
rlk, err := tc.kgen.GenRelinearizationKeyNew(tc.sk)
|
||||
require.NoError(t, err)
|
||||
galEl := uint64(5)
|
||||
gk, err := tc.kgen.GenGaloisKeyNew(galEl, tc.sk)
|
||||
require.NoError(t, err)
|
||||
|
||||
buffer.RequireSerializerCorrect(t, &MemEvaluationKeySet{
|
||||
Rlk: rlk,
|
||||
Gks: map[uint64]*GaloisKey{galEl: gk},
|
||||
Rlk: tc.kgen.GenRelinearizationKeyNew(tc.sk),
|
||||
Gks: map[uint64]*GaloisKey{galEl: tc.kgen.GenGaloisKeyNew(galEl, tc.sk)},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user