From 80da8ff3c7a9e1f0a00eb63fcacd44256b17feb7 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bossuat Date: Tue, 19 Sep 2023 22:38:32 +0200 Subject: [PATCH] [circuits/float]: tweeks --- .../float/bootstrapper/sk_bootstrapper.go | 24 +++++++-------- circuits/float/comparisons_test.go | 30 +++++-------------- .../float/minimax_composite_polynomial.go | 10 +++++++ utils/bignum/polynomial.go | 6 +++- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/circuits/float/bootstrapper/sk_bootstrapper.go b/circuits/float/bootstrapper/sk_bootstrapper.go index 3bed2686..c5653857 100644 --- a/circuits/float/bootstrapper/sk_bootstrapper.go +++ b/circuits/float/bootstrapper/sk_bootstrapper.go @@ -13,20 +13,20 @@ type SecretKeyBootstrapper struct { *ckks.Encoder *rlwe.Decryptor *rlwe.Encryptor - sk *rlwe.SecretKey - Values []*bignum.Complex - Counter int // records the number of bootstrapping + sk *rlwe.SecretKey + Values []*bignum.Complex + Counter int // records the number of bootstrapping + MinLevel int } -func NewSecretKeyBootstrapper(params ckks.Parameters, sk *rlwe.SecretKey) rlwe.Bootstrapper { +func NewSecretKeyBootstrapper(params ckks.Parameters, sk *rlwe.SecretKey) *SecretKeyBootstrapper { return &SecretKeyBootstrapper{ - params, - ckks.NewEncoder(params), - ckks.NewDecryptor(params, sk), - ckks.NewEncryptor(params, sk), - sk, - make([]*bignum.Complex, params.N()), - 0} + Parameters: params, + Encoder: ckks.NewEncoder(params), + Decryptor: ckks.NewDecryptor(params, sk), + Encryptor: ckks.NewEncryptor(params, sk), + sk: sk, + Values: make([]*bignum.Complex, params.N())} } func (d *SecretKeyBootstrapper) Bootstrap(ct *rlwe.Ciphertext) (*rlwe.Ciphertext, error) { @@ -57,7 +57,7 @@ func (d SecretKeyBootstrapper) Depth() int { } func (d SecretKeyBootstrapper) MinimumInputLevel() int { - return 0 + return d.MinLevel } func (d SecretKeyBootstrapper) OutputLevel() int { diff --git a/circuits/float/comparisons_test.go b/circuits/float/comparisons_test.go index f6e95a7a..37c0dd4c 100644 --- a/circuits/float/comparisons_test.go +++ b/circuits/float/comparisons_test.go @@ -1,7 +1,6 @@ package float_test import ( - "math" "math/big" "testing" @@ -10,7 +9,6 @@ import ( "github.com/tuneinsight/lattigo/v4/ckks" "github.com/tuneinsight/lattigo/v4/ring" "github.com/tuneinsight/lattigo/v4/rlwe" - "github.com/tuneinsight/lattigo/v4/utils/bignum" "github.com/stretchr/testify/require" ) @@ -71,13 +69,11 @@ func TestComparisons(t *testing.T) { eval := tc.evaluator.WithKey(rlwe.NewMemEvaluationKeySet(kgen.GenRelinearizationKeyNew(sk), galKeys...)) polyEval := float.NewPolynomialEvaluator(params, eval) - PWFEval := float.NewMinimaxCompositePolynomialEvaluator(params, eval, polyEval, btp) + MCPEval := float.NewMinimaxCompositePolynomialEvaluator(params, eval, polyEval, btp) polys := float.NewMinimaxCompositePolynomial(CoeffsMinimaxCompositePolynomialSignAlpha30Err35Prec20x4Cheby) - CmpEval := float.NewComparisonEvaluator(PWFEval, polys) - - threshold := bignum.NewFloat(math.Exp2(-30), params.EncodingPrecision()) + CmpEval := float.NewComparisonEvaluator(MCPEval, polys) t.Run(GetTestName(params, "Sign"), func(t *testing.T) { @@ -94,14 +90,7 @@ func TestComparisons(t *testing.T) { want := make([]*big.Float, params.MaxSlots()) for i := range have { - - if new(big.Float).Abs(values[i][0]).Cmp(threshold) == -1 { - want[i] = new(big.Float).Set(values[i][0]) - } else if values[i][0].Cmp(new(big.Float)) == -1 { - want[i] = bignum.NewFloat(-1, params.EncodingPrecision()) - } else { - want[i] = bignum.NewFloat(1, params.EncodingPrecision()) - } + want[i] = polys.Evaluate(values[i])[0] } ckks.VerifyTestVectors(params, ecd, nil, want, have, params.LogDefaultScale(), nil, *printPrecisionStats, t) @@ -121,15 +110,12 @@ func TestComparisons(t *testing.T) { want := make([]*big.Float, params.MaxSlots()) - for i := range have { + half := new(big.Float).SetFloat64(0.5) - if new(big.Float).Abs(values[i][0]).Cmp(threshold) == -1 { - want[i] = new(big.Float).Set(values[i][0]) - } else if values[i][0].Cmp(new(big.Float)) == -1 { - want[i] = bignum.NewFloat(0, params.EncodingPrecision()) - } else { - want[i] = bignum.NewFloat(1, params.EncodingPrecision()) - } + for i := range have { + want[i] = polys.Evaluate(values[i])[0] + want[i].Mul(want[i], half) + want[i].Add(want[i], half) } ckks.VerifyTestVectors(params, ecd, nil, want, have, params.LogDefaultScale(), nil, *printPrecisionStats, t) diff --git a/circuits/float/minimax_composite_polynomial.go b/circuits/float/minimax_composite_polynomial.go index f302ffeb..9089559d 100644 --- a/circuits/float/minimax_composite_polynomial.go +++ b/circuits/float/minimax_composite_polynomial.go @@ -43,6 +43,16 @@ func (mcp MinimaxCompositePolynomial) MaxDepth() (depth int) { return } +func (mcp MinimaxCompositePolynomial) Evaluate(x interface{}) (y *bignum.Complex) { + y = mcp[0].Evaluate(x) + + for _, p := range mcp[1:] { + y = p.Evaluate(y) + } + + return +} + // CoeffsSignX2Cheby (from https://eprint.iacr.org/2019/1234.pdf) are the coefficients // of 1.5*x - 0.5*x^3 in Chebyshev basis. // Evaluating this polynomial on values already close to -1, or 1 ~doubles the number of diff --git a/utils/bignum/polynomial.go b/utils/bignum/polynomial.go index 8f376ee2..d2654548 100644 --- a/utils/bignum/polynomial.go +++ b/utils/bignum/polynomial.go @@ -179,8 +179,12 @@ func (p *Polynomial) Evaluate(x interface{}) (y *Complex) { xcmplx = ToComplex(x, x.Prec()) case *Complex: xcmplx = ToComplex(x, x.Prec()) + case complex128: + xcmplx = ToComplex(x, 64) + case float64: + xcmplx = ToComplex(x, 64) default: - panic(fmt.Errorf("cannot Evaluate: accepted x.(type) are *big.Float and *Complex but x is %T", x)) + panic(fmt.Errorf("cannot Evaluate: accepted x.(type) are *big.Float, *Complex, float64 and complex128 but x is %T", x)) } coeffs := p.Coeffs