mirror of
https://github.com/tuneinsight/lattigo.git
synced 2025-09-13 03:27:14 +00:00
Merge branch 'main' into serialization-compressed-keys
This commit is contained in:
@@ -99,6 +99,29 @@ func newEncryptor(params Parameters) *Encryptor {
|
||||
}
|
||||
}
|
||||
|
||||
// NewTestEncryptorWithPRNG creates a new [Encryptor] that uses the provided prng for randomness.
|
||||
// CAUTION: THIS FUNCTION SHOULD BE USED FOR TESTING PURPOSES ONLY.
|
||||
func NewTestEncryptorWithPRNG(params ParameterProvider, key EncryptionKey, prng sampling.PRNG) *Encryptor {
|
||||
p := *params.GetRLWEParameters()
|
||||
|
||||
enc := NewEncryptor(params, key)
|
||||
xeSampler, err := ring.NewSampler(prng, p.RingQ(), p.Xe(), false)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("NewEncryptorWithPRNG: cannot create xeSampler %w", err))
|
||||
}
|
||||
xsSampler, err := ring.NewSampler(prng, p.RingQ(), p.Xs(), false)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("NewEncryptorWithPRNG: cannot create xsSampler %w", err))
|
||||
}
|
||||
uniformSampler := ringqp.NewUniformSampler(prng, *p.RingQP())
|
||||
enc.prng = prng
|
||||
enc.xeSampler = xeSampler
|
||||
enc.xsSampler = xsSampler
|
||||
enc.uniformSampler = uniformSampler
|
||||
|
||||
return enc
|
||||
}
|
||||
|
||||
type encryptorBuffers struct {
|
||||
buffQP [3]ringqp.Poly
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package rlwe
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -8,6 +9,8 @@ import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/blake2b"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tuneinsight/lattigo/v6/ring"
|
||||
@@ -31,6 +34,86 @@ func testString(params Parameters, levelQ, levelP, bpw2 int, opname string) stri
|
||||
params.RingType())
|
||||
}
|
||||
|
||||
// TestRLWEConstSerialization test detects (fails) if the serialization of
|
||||
// [PublicKey], [SecretKey], [Ciphertext], [GaloisKey], [MemEvaluationKeySet] has changed.
|
||||
// If such a modification is intended, this test must be updated and users notified s.t.
|
||||
// old serialized objects can be converted to the new format.
|
||||
func TestRLWEConstSerialization(t *testing.T) {
|
||||
// Note: changing nbIteration will change the expected value
|
||||
const nbIteration = 10
|
||||
const expected = "XRdlwx5vEX9qdGY3CeeAxzGHa0gbXghzpLhV0eIgVk8="
|
||||
var err error
|
||||
defaultParamsLiteral := testInsecure
|
||||
seedKeyGen := []byte{'l', 'a', 't'}
|
||||
seedEnc := []byte{'t', 'i', 'g', 'o'}
|
||||
hash, err := blake2b.New(32, nil)
|
||||
require.Nil(t, err)
|
||||
|
||||
for _, paramsLit := range defaultParamsLiteral[:] {
|
||||
|
||||
for _, NTTFlag := range []bool{true, false}[:] {
|
||||
|
||||
for _, RingType := range []ring.Type{ring.Standard, ring.ConjugateInvariant}[:] {
|
||||
|
||||
paramsLit.NTTFlag = NTTFlag
|
||||
paramsLit.RingType = RingType
|
||||
|
||||
var params Parameters
|
||||
if params, err = NewParametersFromLiteral(paramsLit.ParametersLiteral); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
detTC, err := NewDeterministicTestContext(params, seedKeyGen, seedEnc)
|
||||
require.Nil(t, err)
|
||||
for i := 0; i < nbIteration; i++ {
|
||||
// Add marshalled (sk, pk) to the hash input
|
||||
sk, pk := detTC.kgen.GenKeyPairNew()
|
||||
skBytes, err := sk.MarshalBinary()
|
||||
hash.Write(skBytes)
|
||||
require.Nil(t, err)
|
||||
|
||||
pkBytes, err := pk.MarshalBinary()
|
||||
require.Nil(t, err)
|
||||
hash.Write(pkBytes)
|
||||
|
||||
// Add marshalled GaloisKey to the hash input
|
||||
galEl := params.GaloisElement(-1)
|
||||
galEl2 := params.GaloisElement(3)
|
||||
galKey := detTC.kgen.GenGaloisKeysNew([]uint64{galEl, galEl2}, sk)
|
||||
galKeyBytes, err := galKey[0].MarshalBinary()
|
||||
require.Nil(t, err)
|
||||
hash.Write(galKeyBytes)
|
||||
|
||||
// Add marshalled MemEvaluationKeySet to the hash input
|
||||
relinKey := detTC.kgen.GenRelinearizationKeyNew(sk)
|
||||
evk := NewMemEvaluationKeySet(relinKey, galKey...)
|
||||
evkBytes, err := evk.MarshalBinary()
|
||||
require.Nil(t, err)
|
||||
hash.Write(evkBytes)
|
||||
|
||||
// Add marshalled MemEvaluationKeySet to the hash input
|
||||
ct := NewCiphertext(params, 1, params.MaxLevel())
|
||||
pt := genPlaintext(params, params.MaxLevel(), (1<<int(params.LogQ()))-1)
|
||||
detTC.enc.Encrypt(pt, ct)
|
||||
ctBytes, err := ct.MarshalBinary()
|
||||
require.Nil(t, err)
|
||||
hash.Write(ctBytes)
|
||||
ctJSON, err := ct.MarshalJSON()
|
||||
require.Nil(t, err)
|
||||
hash.Write(ctJSON)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
digest := base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
||||
|
||||
// In case the value expected must be updated, uncomment to print the new expected value:
|
||||
// fmt.Println(digest)
|
||||
|
||||
require.Equal(t, expected, digest)
|
||||
}
|
||||
|
||||
func TestRLWE(t *testing.T) {
|
||||
|
||||
var err error
|
||||
@@ -219,6 +302,40 @@ func testUserDefinedParameters(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func NewDeterministicTestContext(params Parameters, seedKeyGen, seedEnc []byte) (tc *TestContext, err error) {
|
||||
prngKGen, err := sampling.NewKeyedPRNG(seedKeyGen)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("NewDeterministicTestContext: failed to make prngKGen %w", err))
|
||||
}
|
||||
prngEnc, err := sampling.NewKeyedPRNG(seedEnc)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("NewDeterministicTestContext: failed to make prngEnc %w", err))
|
||||
}
|
||||
kgen := NewKeyGenerator(params)
|
||||
kgenEncryptor := NewTestEncryptorWithPRNG(params, nil, prngKGen)
|
||||
kgen.Encryptor = kgenEncryptor
|
||||
|
||||
sk := kgen.GenSecretKeyNew()
|
||||
|
||||
pk := kgen.GenPublicKeyNew(sk)
|
||||
|
||||
eval := NewEvaluator(params, nil)
|
||||
|
||||
enc := NewTestEncryptorWithPRNG(params, sk, prngEnc)
|
||||
|
||||
dec := NewDecryptor(params, sk)
|
||||
|
||||
return &TestContext{
|
||||
params: params,
|
||||
kgen: kgen,
|
||||
sk: sk,
|
||||
pk: pk,
|
||||
enc: enc,
|
||||
dec: dec,
|
||||
eval: eval,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewTestContext(params Parameters) (tc *TestContext, err error) {
|
||||
kgen := NewKeyGenerator(params)
|
||||
sk := kgen.GenSecretKeyNew()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package bgv
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/blake2b"
|
||||
|
||||
"github.com/tuneinsight/lattigo/v6/core/rlwe"
|
||||
"github.com/tuneinsight/lattigo/v6/ring"
|
||||
@@ -871,6 +873,49 @@ func testEvaluatorBfv(tc *TestContext, t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// TestBGVParamsConstSerialization test detects (fails) if the serialization of [Parameters] has changed.
|
||||
// If such a modification is intended, this test must be updated and users notified s.t.
|
||||
// old serialized parameters can be converted to the new format.
|
||||
func TestBGVParamsConstSerialization(t *testing.T) {
|
||||
const expected = "7aw0pU3xCs2Hu8zHKqkPRUpltHC0+P+UxzMSqKJwSFs="
|
||||
var err error
|
||||
distribs := []ring.DistributionParameters{rlwe.DefaultXe, rlwe.DefaultXs, ring.Ternary{H: 192}}
|
||||
hash, err := blake2b.New(32, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Test with different CKKS params, including different plaintext moduli and distributions
|
||||
for _, paramsLit := range []ParametersLiteral{ExampleParameters128BitLogN14LogQP438, testInsecure}[:] {
|
||||
for _, ptMod := range testPlaintextModulus[:] {
|
||||
for _, distXe := range distribs {
|
||||
for _, distXs := range distribs {
|
||||
|
||||
paramsLit.Xe = distXe
|
||||
paramsLit.Xs = distXs
|
||||
paramsLit.PlaintextModulus = ptMod
|
||||
var params Parameters
|
||||
if params, err = NewParametersFromLiteral(paramsLit); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
paramsBytes, err := params.MarshalBinary()
|
||||
require.Nil(t, err)
|
||||
hash.Write(paramsBytes)
|
||||
paramsBytes, err = params.MarshalJSON()
|
||||
require.Nil(t, err)
|
||||
hash.Write(paramsBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
digest := base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
||||
|
||||
// In case the value expected must be updated, uncomment to print the new expected value:
|
||||
// fmt.Println(digest)
|
||||
|
||||
require.Equal(t, expected, digest)
|
||||
}
|
||||
|
||||
var (
|
||||
// testInsecure are insecure parameters used for the sole purpose of fast testing.
|
||||
testInsecure = ParametersLiteral{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package ckks
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/blake2b"
|
||||
|
||||
"github.com/tuneinsight/lattigo/v6/core/rlwe"
|
||||
"github.com/tuneinsight/lattigo/v6/ring"
|
||||
@@ -798,6 +800,49 @@ func testBridge(tc *TestContext, t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// TestCKKSParamsConstSerialization test detects (fails) if the serialization of [Parameters] has changed.
|
||||
// If such a modification is intended, this test must be updated and users notified s.t.
|
||||
// old serialized parameters can be converted to the new format.
|
||||
func TestCKKSParamsConstSerialization(t *testing.T) {
|
||||
const expected = "Bo962QjkASlly6oMAojaEYOIGTh5v0nhzWvu93XgVRk="
|
||||
var err error
|
||||
distribs := []ring.DistributionParameters{rlwe.DefaultXe, rlwe.DefaultXs, ring.Ternary{H: 192}}
|
||||
hash, err := blake2b.New(32, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Test with different CKKS params, including different ringtypes and distributions
|
||||
for _, paramsLit := range testParametersLiteral[:] {
|
||||
for _, ringType := range []ring.Type{ring.Standard, ring.ConjugateInvariant}[:] {
|
||||
for _, distXe := range distribs {
|
||||
for _, distXs := range distribs {
|
||||
|
||||
paramsLit.RingType = ringType
|
||||
paramsLit.Xe = distXe
|
||||
paramsLit.Xs = distXs
|
||||
var params Parameters
|
||||
if params, err = NewParametersFromLiteral(paramsLit); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
paramsBytes, err := params.MarshalBinary()
|
||||
require.Nil(t, err)
|
||||
hash.Write(paramsBytes)
|
||||
paramsBytes, err = params.MarshalJSON()
|
||||
require.Nil(t, err)
|
||||
hash.Write(paramsBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
digest := base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
||||
|
||||
// In case the value expected must be updated, uncomment to print the new expected value:
|
||||
// fmt.Println(digest)
|
||||
|
||||
require.Equal(t, expected, digest)
|
||||
}
|
||||
|
||||
func name(opname string, tc *TestContext) string {
|
||||
|
||||
var precMode string
|
||||
|
||||
Reference in New Issue
Block a user