Files
lattice/circuits/bgv/polynomial/polynomial_evaluator_test.go
zeekay eaf864890e feat: release v7.0.0 with GPU acceleration and module update
- Update module path to github.com/luxfi/lattice/v7
- Add GPU acceleration with Metal (macOS) and CUDA backends
- Enhance threshold FHE operations
- Revert to vanilla Apache 2.0 license (remove tfhe)
- Update Go version to 1.25.5
- Merge upstream lattigo improvements
2025-12-30 15:37:37 -08:00

107 lines
2.8 KiB
Go

package polynomial
import (
"encoding/json"
"flag"
"runtime"
"testing"
"github.com/stretchr/testify/require"
"github.com/luxfi/lattice/v7/ring"
"github.com/luxfi/lattice/v7/schemes/bgv"
"github.com/luxfi/lattice/v7/utils/bignum"
)
var flagParamString = flag.String("params", "", "specify the test cryptographic parameters as a JSON string. Overrides -short.")
func TestPolynomialEvaluator(t *testing.T) {
var err error
paramsLiterals := testParams
if *flagParamString != "" {
var jsonParams bgv.ParametersLiteral
if err = json.Unmarshal([]byte(*flagParamString), &jsonParams); err != nil {
t.Fatal(err)
}
paramsLiterals = []bgv.ParametersLiteral{jsonParams} // the custom test suite reads the parameters from the -params flag
}
for _, p := range paramsLiterals[:] {
for _, plaintextModulus := range testPlaintextModulus[:] {
p.PlaintextModulus = plaintextModulus
tc := bgv.NewTestContext(p, false)
for _, testSet := range []func(tc *bgv.TestContext, t *testing.T){
run,
} {
testSet(tc, t)
runtime.GC()
}
}
}
}
func run(tc *bgv.TestContext, t *testing.T) {
t.Run("Single", func(t *testing.T) {
// Test all level configurations - removed skip
if tc.Params.MaxLevel() < 4 {
t.Logf("Running modified test for low MaxLevel() < 4")
}
values, _, ciphertext := bgv.NewTestVector(tc.Params, tc.Ecd, tc.Enc, tc.Params.MaxLevel(), tc.Params.DefaultScale(), true)
coeffs := []uint64{0, 0, 1}
T := tc.Params.PlaintextModulus()
for i := range values {
values[i] = ring.EvalPolyModP(values[i], coeffs, T)
}
poly := bignum.NewPolynomial(bignum.Monomial, coeffs, nil)
t.Run("Standard"+tc.String(), func(t *testing.T) {
polyEval := NewEvaluator(tc.Params, tc.Evl)
res, err := polyEval.Evaluate(ciphertext, poly, tc.Params.DefaultScale())
require.NoError(t, err)
require.Equal(t, res.Scale.Cmp(tc.Params.DefaultScale()), 0)
bgv.VerifyTestVectors(tc.Params, tc.Ecd, tc.Dec, res, values, true, t)
})
t.Run("Invariant"+tc.String(), func(t *testing.T) {
tc.Evl.ScaleInvariant = true
polyEval := NewEvaluator(tc.Params, tc.Evl)
res, err := polyEval.Evaluate(ciphertext, poly, tc.Params.DefaultScale())
require.NoError(t, err)
require.Equal(t, res.Level(), ciphertext.Level())
require.Equal(t, res.Scale.Cmp(tc.Params.DefaultScale()), 0)
bgv.VerifyTestVectors(tc.Params, tc.Ecd, tc.Dec, res, values, true, t)
})
})
}
var (
// testInsecure are insecure parameters used for the sole purpose of fast testing.
testInsecure = bgv.ParametersLiteral{
LogN: 10,
Q: []uint64{0x3fffffa8001, 0x1000090001, 0x10000c8001, 0x10000f0001, 0xffff00001},
P: []uint64{0x7fffffd8001},
}
testPlaintextModulus = []uint64{0x101, 0xffc001}
testParams = []bgv.ParametersLiteral{testInsecure}
)