-
To enable bootstrapping, I set So, how can I properly perform bootstrapping when the number of slots of a ciphertext is less than N/2? package main
import (
"fmt"
"math"
"github.com/tuneinsight/lattigo/v6/core/rlwe"
"github.com/tuneinsight/lattigo/v6/schemes/ckks"
"github.com/tuneinsight/lattigo/v6/utils"
"github.com/tuneinsight/lattigo/v6/circuits/ckks/bootstrapping"
"github.com/tuneinsight/lattigo/v6/ring"
"github.com/tuneinsight/lattigo/v6/utils/sampling"
)
func main() {
var err error
var params ckks.Parameters
multiplicativeDepth := 24
firstModSize := 60
scalingModSize := 40
LogN := 16
LogQ := make([]int, multiplicativeDepth+1)
LogQ[0] = firstModSize
for i := 1; i < (1 + multiplicativeDepth); i++ {
LogQ[i] = scalingModSize
}
alpha := 3
LogP := make([]int, alpha)
for i := 0; i < alpha; i++ {
LogP[i] = 61
}
var LogSlots int = 14
rlweParametersLit := ckks.ParametersLiteral{
LogN: LogN,
LogQ: LogQ,
LogP: LogP,
LogDefaultScale: scalingModSize,
Xs: ring.Ternary{H: 192},
}
if params, err = ckks.NewParametersFromLiteral(rlweParametersLit); err != nil {
panic(err)
} else {
fmt.Printf("rlwe parameters: %v\n", rlweParametersLit)
fmt.Printf("Q: %v\n", params.Q())
}
prec := params.EncodingPrecision()
fmt.Printf("prec: %v\n", prec)
LogMessageRatio := 8
btpParametersLit := bootstrapping.ParametersLiteral{
LogN: utils.Pointy(LogN),
LogP: LogP,
Xs: params.Xs(),
LogMessageRatio: &LogMessageRatio,
LogSlots: &LogSlots,
}
btpParams, err := bootstrapping.NewParametersFromLiteral(params, btpParametersLit)
if err != nil {
panic(err)
}
fmt.Printf("Residual parameters: logN=%d, logSlots=%d, H=%d, sigma=%f, logQP=%f, levels=%d, scale=2^%d\n",
btpParams.ResidualParameters.LogN(),
btpParams.ResidualParameters.LogMaxSlots(),
btpParams.ResidualParameters.XsHammingWeight(),
btpParams.ResidualParameters.Xe(), params.LogQP(),
btpParams.ResidualParameters.MaxLevel(),
btpParams.ResidualParameters.LogDefaultScale())
fmt.Printf("Bootstrapping parameters: logN=%d, logSlots=%d, H(%d; %d), sigma=%f, logQP=%f, levels=%d, scale=2^%d, levels=%v\n",
btpParams.BootstrappingParameters.LogN(),
btpParams.BootstrappingParameters.LogMaxSlots(),
btpParams.BootstrappingParameters.XsHammingWeight(),
btpParams.EphemeralSecretWeight,
btpParams.BootstrappingParameters.Xe(),
btpParams.BootstrappingParameters.LogQP(),
btpParams.BootstrappingParameters.QCount(),
btpParams.BootstrappingParameters.LogDefaultScale(),
btpParams.BootstrappingParameters.MaxLevel(),
)
kgen := rlwe.NewKeyGenerator(params)
sk, pk := kgen.GenKeyPairNew()
encoder := ckks.NewEncoder(params)
decryptor := rlwe.NewDecryptor(params, sk)
encryptor := rlwe.NewEncryptor(params, pk)
fmt.Println()
fmt.Println("Generating bootstrapping evaluation keys...")
evk, _, err := btpParams.GenEvaluationKeys(sk)
if err != nil {
panic(err)
}
var eval *bootstrapping.Evaluator
if eval, err = bootstrapping.NewEvaluator(btpParams, evk); err != nil {
panic(err)
}
valuesWant := make([]float64, (1<<14))
for i := range valuesWant {
valuesWant[i] = sampling.RandFloat64(0, 1)
}
plaintext := ckks.NewPlaintext(params, 0)
if err := encoder.Encode(valuesWant, plaintext); err != nil {
panic(err)
}
ciphertext1, err := encryptor.EncryptNew(plaintext)
if err != nil {
panic(err)
}
fmt.Println()
fmt.Println("Precision of values vs. ciphertext")
valuesTest1 := printDebug(params, ciphertext1, valuesWant, decryptor, encoder)
fmt.Println("Bootstrapping...")
ciphertext2, err := eval.Bootstrap(ciphertext1)
if err != nil {
panic(err)
}
fmt.Println("Done")
fmt.Println()
fmt.Println("Precision of ciphertext vs. Bootstrap(ciphertext)")
printDebug(params, ciphertext2, valuesTest1, decryptor, encoder)
}
func printDebug(params ckks.Parameters, ciphertext *rlwe.Ciphertext, valuesWant []float64, decryptor *rlwe.Decryptor, encoder *ckks.Encoder) (valuesTest []float64) {
valuesTest = make([]float64, ciphertext.Slots())
if err := encoder.Decode(decryptor.DecryptNew(ciphertext), valuesTest); err != nil {
panic(err)
}
fmt.Println()
fmt.Printf("Level: %d (logQ = %d)\n", ciphertext.Level(), params.LogQLvl(ciphertext.Level()))
fmt.Printf("Scale: 2^%f\n", math.Log2(ciphertext.Scale.Float64()))
fmt.Printf("ValuesTest: %6.10f %6.10f %6.10f %6.10f...\n", valuesTest[0], valuesTest[1], valuesTest[2], valuesTest[3])
fmt.Printf("ValuesWant: %6.10f %6.10f %6.10f %6.10f...\n", valuesWant[0], valuesWant[1], valuesWant[2], valuesWant[3])
precStats := ckks.GetPrecisionStats(params, encoder, nil, valuesWant, valuesTest, 0, false)
fmt.Println(precStats.String())
fmt.Println()
return
} The output is:
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hi! This is linked to a bug that is fixed in this PR #506 that is yet to be merged. plaintext := ckks.NewPlaintext(params, 0)
plaintext.LogDimensions = ring.Dimensions{Rows: 0, Cols: LogSlots} |
Beta Was this translation helpful? Give feedback.
Hi!
This is linked to a bug that is fixed in this PR #506 that is yet to be merged.
If you want to try your example with the corresponding branch, don't forget to set the dimension of the plaintext according to
LogSlots
: