Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug/Regression [<package>]: Limited number of levels supported by BFV/BGV #517

Open
carblu opened this issue Nov 22, 2024 · 0 comments
Open
Labels
bug Something isn't working

Comments

@carblu
Copy link

carblu commented Nov 22, 2024

What version of Lattigo are you using?

v6.0.0

Does this issue persist with the latest release?

Yes

What were you trying to do?

In bfv/bgv, I was trying to use as many levels as possible. It seems that loqQ can be formed by at most 32 sizes of primes. Indeed, the following parameters do not work.

bgv.ParametersLiteral{
LogN: 16,
LogQ: []int{56, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
LogP: []int{60, 60, 60, 60, 60},
PlaintextModulus: 0xc0001,
}

See discussion #516

What were you expecting to happen?

What actually happened?

I can encrypt and decrypt, but when decoding the plaintext obtained as a result of the decryption, I got the runtime error "index out of range [32] with length 32" raised by ring.reconstructRNS.

Reproducibility

package main

import (
"fmt"
"math/rand"
"slices"

    "github.com/tuneinsight/lattigo/v6/core/rlwe"
    "github.com/tuneinsight/lattigo/v6/schemes/bgv"

)

func main() {
var err error
var params bgv.Parameters

    if params, err = bgv.NewParametersFromLiteral(
        bgv.ParametersLiteral{
            LogN:            16,
            LogQ:            []int{56, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
            LogP:            []int{60, 60, 60, 60, 60},
            PlaintextModulus: 0xc0001,       // It must be a prime number congruent to 1 modulo 2 * poly_modulus_degree
        }); err != nil {
            panic(err)
    }

    Slots := params.MaxSlots()

    fmt.Printf("(LogN, L): (%d, %d)\n",  params.LogN(), params.MaxLevel())
    fmt.Printf("Maximum number of slots: %d\n",  Slots)

    // Key Generator
    kgen := rlwe.NewKeyGenerator(params)

    // Generate a secret key (sk) and a corresponding public key (pk)
    sk := kgen.GenSecretKeyNew()
    pk := kgen.GenPublicKeyNew(sk)

    // Generate a relinearizaton key from the secret key (sk)
    rlk := kgen.GenRelinearizationKeyNew(sk)

    // Generate an evaluation key from the relinearizaton key (rlk)
    evk := rlwe.NewMemEvaluationKeySet(rlk)

    fmt.Printf("Secret Key Size:          %d\n", sk.BinarySize())
    fmt.Printf("Public Key Size:          %d\n", pk.BinarySize())
    fmt.Printf("Relinearization Key Size: %d\n", rlk.BinarySize())
    fmt.Printf("Evaluation Key Size:      %d\n", evk.BinarySize())

    // Encoder
    encoder := bgv.NewEncoder(params)

    // Encryptor-Decryptor
    encryptor := rlwe.NewEncryptor(params, sk)
    decryptor := rlwe.NewDecryptor(params, sk)

    // Vector of plaintext values
    values := make([]uint64, Slots)

    // Populates the vector of plaintext values
    r := rand.New(rand.NewSource(0))
    T := params.PlaintextModulus()
    for i := range values {
            values[i] = r.Uint64() % T
    }

    // Allocates a vector for the reference values
    want := make([]uint64, Slots)
    copy(want, values)

    // Allocates a plaintext at the max level.
    plaintext := bgv.NewPlaintext(params, params.MaxLevel())
    fmt.Printf("Plaintext Size: %d\n", plaintext.BinarySize())

    // Encodes the vector of plaintext values
    if err = encoder.Encode(values, plaintext); err != nil {
            panic(err)
    }

    // Encrypts the vector of plaintext values
    var ciphertext *rlwe.Ciphertext
    if ciphertext, err = encryptor.EncryptNew(plaintext); err != nil {
            panic(err)
    }
    fmt.Printf("Ciphertext Size:         %d\n", ciphertext.BinarySize())

    // Decrypts the vector of plaintext values
    plaintext = decryptor.DecryptNew(ciphertext)

    // Decodes the plaintext
    have := make([]uint64, Slots)
    if err = encoder.Decode(plaintext, have); err != nil {
            panic(err)
    }

    // Check correct decryption
    fmt.Printf("\tChecking decryption...")
    if !slices.Equal(want, have) {
            fmt.Printf("\t Wrong result\n")
    } else {
            fmt.Printf("\t No errors\n" )
    }

}

@carblu carblu added the bug Something isn't working label Nov 22, 2024
@carblu carblu changed the title Bug/Regression [<package>]: Bug/Regression [<package>]: Limited number of levels supported by BFV/BGV Nov 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant