diff --git a/.github/actions/default_builder/action.yml b/.github/actions/default_builder/action.yml deleted file mode 100644 index f411edee1..000000000 --- a/.github/actions/default_builder/action.yml +++ /dev/null @@ -1,195 +0,0 @@ -name: 'Default Builder' -description: 'A custom GitHub actions pipeline that wrappedup build, unit_test, benchmark and extract stages' - -inputs: - module_name: - description: 'Name of the module' - required: true - default: 'default' - cmake_args: - description: 'Argument for cmake command' - required: true - default: '' - native_backend: - description: 'Size of NativeInteger [32|64|128]' - required: false - default: '64' - mathbackend: - description: 'Multiprecision backend for large-words [2|4|6]' - required: false - with_debug: - description: 'Compile with debug' - type: boolean - default: false - required: false - with_tcm: - description: 'Run tcm stages' - type: boolean - default: false - required: false - run_extras: - description: 'Run allextras stages' - type: boolean - default: false - required: false - with_nativeopts: - description: 'Enables compiler to use native optimizations' - type: boolean - default: false - required: false - run_benchmark: - description: 'Run Benchmark stages' - type: boolean - default: false - required: false - -runs: - # - using: "composite" - steps: - - # -- cmake configuration - - name: '${{ inputs.module_name }}_cmake' - shell: bash - run: | - echo "${{ inputs.module_name }}_cmake" - - whoami - - # Create the correct cmake arg string - cmake_args="-DNATIVE_SIZE=${{ inputs.native_backend }}" - - # Debugging use only - echo "Input values for ${{inputs.module_name}} - cmake_args=${{inputs.cmake_args}} - native_backend=${{inputs.native_backend}} - mathbackend=${{inputs.mathbackend}} - with_debug=${{inputs.with_debug}} - with_tcm=${{inputs.with_tcm}} - run_extras=${{inputs.run_extras}} - with_nativeopts=${{inputs.with_nativeopts}} - run_benchmark=${{inputs.run_benchmark}} - " - - # Append options based on inputs - [[ "${{inputs.with_tcm}}" != "false" ]] && cmake_args="${cmake_args} -DWITH_TCM=ON" - [[ "${{inputs.run_extras}}" != "false" ]] && cmake_args="${cmake_args} -DBUILD_EXTRAS=ON" - [[ "${{inputs.with_nativeopts}}" != "false" ]] && cmake_args="${cmake_args} -DWITH_NATIVEOPT=ON" - [[ "${{inputs.with_debug}}" != "false" ]] && cmake_args="${cmake_args} -DCMAKE_BUILD_TYPE=Debug" - [[ "${{inputs.mathbackend}}" != "" ]] && cmake_args="${cmake_args} -DMATHBACKEND=${{ inputs.mathbackend }}" - [[ "${{inputs.mathbackend}}" == "6" ]] && cmake_args="${cmake_args} -DWITH_NTL=ON" - - # Append manual pushed in cmake args from the input, this needs to be after the inputs - # So that the input can override defaults - make_args="${cmake_args} ${{ inputs.cmake_args }}" - - echo "CMAKE ARGS: ${cmake_args}" - - cmake -S . -B build ${cmake_args} - - # -- build - - name: '${{ inputs.module_name }}_build' - shell: bash - run: | - echo "${{ inputs.module_name }}_build" - - cd build - - # run only if with_tcm input is set - if [[ "${{inputs.with_tcm}}" == "true" ]]; then - make tcm -j $(nproc) - fi - - # Build the code base - make -j $(nproc) all - - # run only if run_extra input is set - if [[ "${{inputs.run_extras}}" == "true" ]]; then - make -j $(nproc) allextras - fi - - # -- binfhe - - name: '${{ inputs.module_name }}_test_binfhe' - shell: bash - run: | - echo "${{ inputs.module_name }}_test_binfhe" - pwd - echo "LD_LIBRARY_PATH = ${LD_LIBRARY_PATH}" - build/unittest/binfhe_tests --gtest_output=xml - - # -- test_core - - name: '${{ inputs.module_name }}_test_core' - shell: bash - run: | - echo "${{ inputs.module_name }}_test_core" - pwd - echo "LD_LIBRARY_PATH = ${LD_LIBRARY_PATH}" - build/unittest/core_tests --gtest_output=xml - - # -- test_pke - - name: '${{ inputs.module_name }}_test_pke' - shell: bash - run: | - echo "${{ inputs.module_name }}_test_pke" - pwd - echo "LD_LIBRARY_PATH = ${LD_LIBRARY_PATH}" - build/unittest/pke_tests --gtest_output=xml - - # -- benchmark - - name: ${{ inputs.module_name }}_benchmark - shell: bash - if: ${{ inputs.run_benchmark == 'true' }} - run: | - echo "${{ inputs.module_name }}_benchmark" - # Double guard - if [[ "${{ inputs.run_benchmark }}" == "true" ]]; then - export OMP_NUM_THREADS=1 - build/bin/benchmark/binfhe-ginx --benchmark_out="binfhe-ginx_${{ github.sha }}.csv" --benchmark_out_format=csv - build/bin/benchmark/lib-benchmark --benchmark_out="lib-benchmark_${{ github.sha }}.csv" --benchmark_out_format=csv - build/bin/benchmark/poly-benchmark-1k --benchmark_out="poly-benchmark-1k_${{ github.sha }}.csv" --benchmark_out_format=csv - build/bin/benchmark/poly-benchmark-4k --benchmark_out="poly-benchmark-4k_${{ github.sha }}.csv" --benchmark_out_format=csv - build/bin/benchmark/poly-benchmark-16k --benchmark_out="poly-benchmark-16k_${{ github.sha }}.csv" --benchmark_out_format=csv - - # Skipping these for time resource reasons. - # build/bin/benchmark/binfhe-ap --benchmark_out="binfhe-ap_${{ github.sha }}.csv" --benchmark_out_format=csv - # build/bin/benchmark/basic_test --benchmark_out="basic_test_${{ github.sha }}.csv" --benchmark_out_format=csv - # build/bin/benchmark/Encoding --benchmark_out="Encoding_${{ github.sha }}.csv" --benchmark_out_format=csv - # build/bin/benchmark/IntegerMath --benchmark_out="IntegerMath_${{ github.sha }}.csv" --benchmark_out_format=csv - # build/bin/benchmark/Lattice --benchmark_out="Lattice_${{ github.sha }}.csv" --benchmark_out_format=csv - # build/bin/benchmark/NbTheory --benchmark_out="NbTheory_${{ github.sha }}.csv" --benchmark_out_format=csv - # build/bin/benchmark/VectorMath --benchmark_out="VectorMath_${{ github.sha }}.csv" --benchmark_out_format=csv - unset OMP_NUM_THREADS - fi - - # -- upload benchmark results, NOTE - this list needs to be maintained with the above output files - - name: upload_benchmark_artifacts - if: ${{ inputs.run_benchmark == 'true' }} - uses: actions/upload-artifact@v2 - with: - name: benchmark_vectormath-artifact - path: | - binfhe-ginx_${{ github.sha }}.csv - lib-benchmark_${{ github.sha }}.csv - poly-benchmark-1k_${{ github.sha }}.csv - poly-benchmark-4k_${{ github.sha }}.csv - poly-benchmark-16k_${{ github.sha }}.csv - retention-days: 30 - - # -- extract - - name: '${{ inputs.module_name }}_extras_core' - shell: bash - if: ${{ inputs.run_extras == 'true' }} - run: | - echo "${{ inputs.module_name }}_extras_core" - # Double guard - if [[ "${{ inputs.run_extras }}" == "true" ]]; then - ./build/bin/extras/core/dft - ./build/bin/extras/core/math - ./build/bin/extras/core/ntt1 - ./build/bin/extras/core/ntt2 - fi - - # -- cleanup - - name: '${{ inputs.module_name }}_cleanup' - shell: bash - run: rm -rf build \ No newline at end of file diff --git a/.github/workflows/custom.yml b/.github/workflows/custom.yml deleted file mode 100644 index 40c3b3e54..000000000 --- a/.github/workflows/custom.yml +++ /dev/null @@ -1,103 +0,0 @@ -name: Custom - -on: - workflow_dispatch: - inputs: - # Selelects the compiler to use, this will be used in the COMPILERS_MAP as the key to - # retrieve the corresponding cmake compiler options to pass to the action - compiler: - type: choice - description: 'Compiler Type [GCC|CLANG]-Version' - options: - - 'GCC-9' - - 'GCC-10' - - 'CLANG-10' - - 'CLANG-11' - required: true - default: 'GCC-9' - native_backend: - description: 'Size of NativeInteger [32|64|128]' - type: choice - options: - - '32' - - '64' - - '128' - required: true - default: '64' - mathbackend: - type: choice - description: 'Multiprecision mathbackend (Fixed=2, Dynamic=4, NTL=6)' - options: - - 'Fixed' - - 'Dynamic' - - 'NTL' - required: true - default: 'Fixed' - with_debug: - description: 'Build type Debug' - type: boolean - required: true - default: false - with_tcm: - description: 'Build with TCMalloc (TCM)' - type: boolean - required: true - default: false - run_extras: - description: 'Run build and run extras' - type: boolean - required: true - default: false - with_nativeopts: - description: 'Build with native optimizations' - type: boolean - required: true - default: false - run_benchmark: - description: 'Run benchmarks' - type: boolean - required: true - default: false - -env: - # JSON map to convert input Compiler Type to correct cmake args, key is the input.compiler and the value is the cmake string to set the compiler for C and C++ - COMPILERS_MAP: >- - { - "GCC-9" : "-DCMAKE_CXX_COMPILER=/usr/bin/g++-9 -DCMAKE_C_COMPILER=/usr/bin/gcc-9", - "CLANG-10" : "-DCMAKE_CXX_COMPILER=/usr/bin/clang++-10 -DCMAKE_C_COMPILER=/usr/bin/clang-10", - "GCC-10" : "-DCMAKE_CXX_COMPILER=/usr/bin/g++-10 -DCMAKE_C_COMPILER=/usr/bin/gcc-10", - "CLANG-11" : "-DCMAKE_CXX_COMPILER=/usr/bin/clang++-11 -DCMAKE_C_COMPILER=/usr/bin/clang-11", - } - # The key for this map is the input.mathbackend and the value is the integer value needed for cmake's MATHBACKEND variable. - MATHBACKEND_MAP: >- - { - "Fixed" : "2", - "Dynamic" : "4", - "NTL" : "6" - } - -jobs: - - ############################################### - # - # default jobs starts here - # - ############################################### - default: - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: default - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: custom_build - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} - native_backend: ${{ github.event.inputs.native_backend }} - mathbackend: ${{ fromJson(env.MATHBACKEND_MAP)[github.event.inputs.mathbackend] }} - with_debug: ${{ github.event.inputs.with_debug }} - with_tcm: ${{ github.event.inputs.with_tcm }} - run_extras: ${{ github.event.inputs.run_extras }} - with_nativeopts: ${{ github.event.inputs.with_nativeopts }} - run_benchmark: ${{ github.event.inputs.run_benchmark }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 28c6e9833..833db9720 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,50 +4,56 @@ on: push: branches: - main - - github-ci jobs: - - call: - uses: openfheorg/openfhe-development/.github/workflows/reuseable_workflow.yml@github-ci + call_with_gcc: + uses: openfheorg/openfhe-development/.github/workflows/generic_workflow.yml@github-ci with: - mb2_debug: true - mb2_tcm: true - mb4_noflag: true - mb4_debug: true - mb4_tcm: true - mb6_ntl_noflag: true - mb6_ntl_debug_tcm: true - mb6_ntl_tcm: true + runner: ${{ vars.RUNNER }} + compiler: "GCC-11" + native_backend: "all" + mb2_jobs: "all" + mb4_jobs: "all" + mb6_jobs: "all" + # cmake_args_map holds job specific additional cmake options. compiler flags, native_backend flag and + # OpenMP flag are set in generic_workflow.yml + cmake_args_map: '{ + "default" : "-DBUILD_EXTRAS=ON", + "mb2" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2", + "mb2_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2 -DWITH_TCM=ON", + "mb2_debug" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2 -DCMAKE_BUILD_TYPE=Debug", + "mb4" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4", + "mb4_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4 -DWITH_TCM=ON", + "mb4_debug" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4 -DCMAKE_BUILD_TYPE=Debug", + "mb6_ntl" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON", + "mb6_ntl_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON -DWITH_TCM=ON", + "mb6_ntl_debug_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON -DWITH_TCM=ON -DCMAKE_BUILD_TYPE=Debug", + }' - mb2_128: - needs: call - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb2_128 - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb2_128 - native_backend: 128 - mathbackend: 2 - run_extras: true - - mb2_clang: - needs: call - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb2_clang - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb4_tcm - cmake_args: "-DCMAKE_CXX_COMPILER=/usr/bin/clang++-10 -DCMAKE_C_COMPILER=/usr/bin/clang-10" - run_extras: true + call_with_clang: + needs: call_with_gcc + uses: openfheorg/openfhe-development/.github/workflows/generic_workflow.yml@github-ci + with: + runner: ${{ vars.RUNNER }} + compiler: "CLANG-14" + native_backend: "all" + mb2_jobs: "all" + mb4_jobs: "all" + mb6_jobs: "all" + # cmake_args_map holds job specific additional cmake options. compiler flags, native_backend flag and + # OpenMP flag are set in generic_workflow.yml + cmake_args_map: '{ + "default" : "-DBUILD_EXTRAS=ON", + "mb2" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2", + "mb2_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2 -DWITH_TCM=ON", + "mb2_debug" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2 -DCMAKE_BUILD_TYPE=Debug", + "mb4" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4", + "mb4_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4 -DWITH_TCM=ON", + "mb4_debug" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4 -DCMAKE_BUILD_TYPE=Debug", + "mb6_ntl" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON", + "mb6_ntl_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON -DWITH_TCM=ON", + "mb6_ntl_debug_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON -DWITH_TCM=ON -DCMAKE_BUILD_TYPE=Debug", + }' ############################################### @@ -56,13 +62,13 @@ jobs: # ############################################### pages: - needs: mb2_clang - runs-on: [self-hosted, Linux, X64] + needs: call_with_clang + runs-on: ${{ vars.RUNNER }} env: GIT_SUBMODULE_STRATEGY: recursive steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: build_docs run: | diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index 3128eaa03..20d5fd83c 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -1,276 +1,126 @@ name: Manual +# the workflow_call block was added to this manual workflow (on workflow_dispatch:) because +# it has to be included if a reuseable workflow is called. +# The changes from the workflow_dispatch inputs to the workflow_call inputs are: +# - "type: choice" is replaced with "type: string" +# - all "options:" are removed +# The variable/tag for the runner (var.RUNNER) is defined on the "Actions secrets and variables" page, tab "Variables": +# https://github.com/openfheorg/openfhe-development/settings/variables/actions on: + workflow_call: + inputs: + compiler: + description: 'Compiler type' + type: string + required: true + default: 'CLANG-14' + native_backend: + description: 'Size of NativeInteger' + type: string + required: true + default: '64' + mb2_jobs: + description: 'MATHBACKEND2 jobs' + type: string + required: true + default: 'none' + mb4_jobs: + description: 'MATHBACKEND4 jobs' + type: string + required: true + default: 'none' + mb6_jobs: + description: 'MATHBACKEND6 jobs' + type: string + required: true + default: 'none' + workflow_dispatch: inputs: - # Selelects the compiler to use, this will be used in the COMPILERS_MAP as the key to - # retrieve the corresponding cmake compiler options to pass to the action + # # Selects the compiler to use, this choice will be used in the COMPILERS_MAP as the key to + # # retrieve the corresponding cmake compiler options to pass to the action compiler: + description: 'Compiler type' type: choice - description: 'Compiler Type [GCC|CLANG]' options: - 'GCC-9' - 'GCC-10' - - 'CLANG-10' - - 'CLANG-11' + - 'GCC-11' + - 'GCC-12' + - 'CLANG-12 (WITH_OPENMP=OFF)' + - 'CLANG-13 (WITH_OPENMP=OFF)' + - 'CLANG-14' + - 'CLANG-15 (WITH_OPENMP=OFF)' required: true - default: 'GCC-9' + default: 'CLANG-14' native_backend: - description: 'Size of NativeInteger [32|64|128]' + description: 'Size of NativeInteger' type: choice options: - '32' - '64' - '128' + - 'all' required: true default: '64' - mb2_debug: - description: 'Run mb2_debug' - type: boolean - required: true - default: true - mb2_tcm: - description: 'Run mb2_tcm' - type: boolean - required: true - default: true - mb4_noflag: - description: 'Run mb4_noflag' - type: boolean - required: true - default: true - mb4_debug: - description: 'Run mb4_debug' - type: boolean - required: true - default: true - mb4_tcm: - description: 'Run mb4_tcm' - type: boolean - required: true - default: true - mb6_ntl_noflag: - description: 'Run mb6_ntl_noflag' - type: boolean + mb2_jobs: + description: 'MATHBACKEND2 jobs' + type: choice + options: + - 'mb2' + - 'mb2_tcm' + - 'mb2_debug' + - 'all' + - 'none' required: true - default: true - mb6_ntl_debug_tcm: - description: 'Run mb6_ntl_debug_tcm' - type: boolean + default: 'none' + mb4_jobs: + description: 'MATHBACKEND4 jobs' + type: choice + options: + - 'mb4' + - 'mb4_tcm' + - 'mb4_debug' + - 'all' + - 'none' required: true - default: true - mb6_ntl_tcm: - description: 'Run mb6_ntl_tcm' - type: boolean + default: 'none' + mb6_jobs: + description: 'MATHBACKEND6 jobs' + type: choice + options: + - 'mb6_ntl' + - 'mb6_ntl_tcm' + - 'mb6_ntl_debug_tcm' + - 'all' + - 'none' required: true - default: true - -env: - # JSON map to convert input Compiler Type to correct cmake args, key is the input.compiler and the value is the cmake string to set the compiler for C and C++ - COMPILERS_MAP: >- - { - "GCC-9" : "-DCMAKE_CXX_COMPILER=/usr/bin/g++-9 -DCMAKE_C_COMPILER=/usr/bin/gcc-9", - "CLANG-10" : "-DCMAKE_CXX_COMPILER=/usr/bin/clang++-10 -DCMAKE_C_COMPILER=/usr/bin/clang-10", - "GCC-10" : "-DCMAKE_CXX_COMPILER=/usr/bin/g++-10 -DCMAKE_C_COMPILER=/usr/bin/gcc-10", - "CLANG-11" : "-DCMAKE_CXX_COMPILER=/usr/bin/clang++-11 -DCMAKE_C_COMPILER=/usr/bin/clang-11", - } + default: 'none' jobs: + call: + uses: openfheorg/openfhe-development/.github/workflows/generic_workflow.yml@github-ci + with: + runner: ${{ vars.RUNNER }} + compiler: "${{ inputs.compiler }}" + native_backend: "${{ inputs.native_backend }}" + mb2_jobs: "${{ inputs.mb2_jobs }}" + mb4_jobs: "${{ inputs.mb4_jobs }}" + mb6_jobs: "${{ inputs.mb6_jobs }}" + # cmake_args_map holds job specific additional cmake options. compiler flags, native_backend flag and + # OpenMP flag are set in generic_workflow.yml + cmake_args_map: '{ + "default" : "-DBUILD_EXTRAS=ON", + "mb2" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2", + "mb2_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2 -DWITH_TCM=ON", + "mb2_debug" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2 -DCMAKE_BUILD_TYPE=Debug", + "mb4" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4", + "mb4_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4 -DWITH_TCM=ON", + "mb4_debug" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4 -DCMAKE_BUILD_TYPE=Debug", + "mb6_ntl" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON", + "mb6_ntl_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON -DWITH_TCM=ON", + "mb6_ntl_debug_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON -DWITH_TCM=ON -DCMAKE_BUILD_TYPE=Debug", + }' + - ############################################### - # - # default jobs starts here - # - ############################################### - default: - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: default - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: default - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} - native_backend: ${{ github.event.inputs.native_backend }} - - - ############################################### - # - # mb2_debug jobs starts here - # - ############################################### - mb2_debug: - needs: default - if: ${{ github.event.inputs.mb2_debug == 'true' }} - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb2_debug - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb2_debug - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} -DBUILD_EXTRAS=ON -DCMAKE_BUILD_TYPE=Debug -DMATHBACKEND=2 - run_extras: true - native_backend: ${{ github.event.inputs.native_backend }} - - - ############################################### - # - # mb2_tcm jobs starts here - # - ############################################### - mb2_tcm: - needs: default - if: ${{ github.event.inputs.mb2_tcm == 'true' }} - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb2_tcm - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb2_tcm - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} -DBUILD_EXTRAS=ON -DWITH_TCM=ON -DMATHBACKEND=2 - with_tcm: true - run_extras: true - native_backend: ${{ github.event.inputs.native_backend }} - - - ############################################### - # - # mb4_noflag jobs starts here - # - ############################################### - mb4_noflag: - needs: default - if: ${{ github.event.inputs.mb4_noflag == 'true' }} - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb4_noflag - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb4_noflag - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} -DBUILD_EXTRAS=ON -DMATHBACKEND=4 - run_extras: true - native_backend: ${{ github.event.inputs.native_backend }} - - - ############################################### - # - # mb4_debug jobs starts here - # - ############################################### - mb4_debug: - needs: default - if: ${{ github.event.inputs.mb4_debug == 'true' }} - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb4_debug - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb4_debug - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} -DBUILD_EXTRAS=ON -DCMAKE_BUILD_TYPE=Debug -DMATHBACKEND=4 - run_extras: true - native_backend: ${{ github.event.inputs.native_backend }} - - - ############################################### - # - # mb4_tcm jobs starts here - # - ############################################### - mb4_tcm: - needs: default - if: ${{ github.event.inputs.mb4_tcm == 'true' }} - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb4_tcm - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb4_tcm - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} -DBUILD_EXTRAS=ON -DWITH_TCM=ON -DMATHBACKEND=4 - with_tcm: true - run_extras: true - native_backend: ${{ github.event.inputs.native_backend }} - - - ############################################### - # - # mb6_ntl_noflag jobs starts here - # - ############################################### - mb6_ntl_noflag: - needs: default - if: ${{ github.event.inputs.mb6_ntl_noflag == 'true' }} - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb6_ntl_noflag - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb6_ntl_noflag - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} -DBUILD_EXTRAS=ON -DWITH_NTL=ON -DMATHBACKEND=6 - run_extras: true - native_backend: ${{ github.event.inputs.native_backend }} - - - ############################################### - # - # mb6_ntl_tcm jobs starts here - # - ############################################### - mb6_ntl_tcm: - needs: default - if: ${{ github.event.inputs.mb6_ntl_tcm == 'true' }} - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb6_ntl_tcm - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb6_ntl_tcm - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} -DBUILD_EXTRAS=ON -DWITH_NTL=ON -DWITH_TCM=ON -DMATHBACKEND=6 - with_tcm: true - run_extras: true - native_backend: ${{ github.event.inputs.native_backend }} - - - ############################################### - # - # mb6_ntl_debug_tcm jobs starts here - # - ############################################### - mb6_ntl_debug_tcm: - needs: default - if: ${{ github.event.inputs.mb6_ntl_debug_tcm == 'true' }} - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb6_ntl_debug_tcm - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb6_ntl_debug_tcm - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} -DBUILD_EXTRAS=ON -DCMAKE_BUILD_TYPE=Debug -DWITH_NTL=ON -DWITH_TCM=ON -DMATHBACKEND=6 - with_tcm: true - run_extras: true - native_backend: ${{ github.event.inputs.native_backend }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 39aab3605..3bcb44a01 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -5,19 +5,28 @@ on: branches: - main -env: - CMAKE_ARGS: "-DCMAKE_CXX_COMPILER=/usr/bin/g++-9 -DCMAKE_C_COMPILER=/usr/bin/gcc-9" - jobs: - call: - uses: openfheorg/openfhe-development/.github/workflows/reuseable_workflow.yml@github-ci + uses: openfheorg/openfhe-development/.github/workflows/generic_workflow.yml@github-ci with: - mb2_debug: true - mb2_tcm: true - mb4_noflag: true - mb4_debug: true - mb4_tcm: true - mb6_ntl_noflag: true - mb6_ntl_debug_tcm: true - mb6_ntl_tcm: true + runner: ${{ vars.RUNNER }} + compiler: "GCC-11" + native_backend: "64" + mb2_jobs: "all" + mb4_jobs: "all" + mb6_jobs: "all" + # cmake_args_map holds job specific additional cmake options. compiler flags, native_backend flag and + # OpenMP flag are set in generic_workflow.yml + cmake_args_map: '{ + "default" : "-DBUILD_EXTRAS=ON", + "mb2" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2", + "mb2_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2 -DWITH_TCM=ON", + "mb2_debug" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2 -DCMAKE_BUILD_TYPE=Debug", + "mb4" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4", + "mb4_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4 -DWITH_TCM=ON", + "mb4_debug" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=4 -DCMAKE_BUILD_TYPE=Debug", + "mb6_ntl" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON", + "mb6_ntl_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON -DWITH_TCM=ON", + "mb6_ntl_debug_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON -DWITH_TCM=ON -DCMAKE_BUILD_TYPE=Debug", + }' + diff --git a/.github/workflows/reuseable_workflow.yml b/.github/workflows/reuseable_workflow.yml deleted file mode 100644 index e77b1d010..000000000 --- a/.github/workflows/reuseable_workflow.yml +++ /dev/null @@ -1,266 +0,0 @@ -name: Reuseable Workflow - -on: - workflow_call: - inputs: - cmake_args: - description: 'Custom cmake arguments' - type: string - required: false - default: '' - mb2_debug: - description: 'Run mb2_debug' - type: boolean - required: false - default: false - mb2_tcm: - description: 'Run mb2_tcm' - type: boolean - required: false - default: false - mb4_noflag: - description: 'Run mb4_noflag' - type: boolean - required: false - default: false - mb4_debug: - description: 'Run mb4_debug' - type: boolean - required: false - default: false - mb4_tcm: - description: 'Run mb4_tcm' - type: boolean - required: false - default: false - mb6_ntl_noflag: - description: 'Run mb6_ntl_noflag' - type: boolean - required: false - default: false - mb6_ntl_debug_tcm: - description: 'Run mb6_ntl_debug_tcm' - type: boolean - required: false - default: false - mb6_ntl_tcm: - description: 'Run mb6_ntl_tcm' - type: boolean - required: false - default: false - -jobs: - - ############################################### - # - # default jobs starts here - # - ############################################### - default: - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: default - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: default - - - ############################################### - # - # mb2_tcm jobs starts here - # - ############################################### - mb2_tcm: - needs: [default, mb4_noflag, mb6_ntl_noflag] - runs-on: [self-hosted, Linux, X64] - if: inputs.mb2_tcm - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb2_tcm - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb2_tcm - mathbackend: 2 - with_tcm: true - run_extras: true - - - ############################################### - # - # mb2_debug jobs starts here - # - ############################################### - mb2_debug: - needs: [default, mb4_noflag, mb6_ntl_noflag] - runs-on: [self-hosted, Linux, X64] - if: inputs.mb2_debug - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb2_debug - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb2_debug - mathbackend: 2 - with_debug: true - run_extras: true - - - ############################################### - # - # mb4_noflag jobs starts here - # - ############################################### - mb4_noflag: - needs: default - runs-on: [self-hosted, Linux, X64] - if: inputs.mb4_noflag - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb4_noflag - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb4_noflag - mathbackend: 4 - run_extras: true - - - ############################################### - # - # mb4_tcm jobs starts here - # - ############################################### - mb4_tcm: - needs: [default, mb4_noflag, mb6_ntl_noflag] - runs-on: [self-hosted, Linux, X64] - if: inputs.mb4_tcm - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb4_tcm - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb4_tcm - mathbackend: 4 - with_tcm: true - run_extras: true - - - ############################################### - # - # mb4_debug jobs starts here - # - ############################################### - mb4_debug: - needs: [default, mb4_noflag, mb6_ntl_noflag] - runs-on: [self-hosted, Linux, X64] - if: inputs.mb4_debug - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb4_debug - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb4_debug - mathbackend: 4 - with_debug: true - run_extras: true - - - ############################################### - # - # mb6_ntl_noflag jobs starts here - # - ############################################### - mb6_ntl_noflag: - needs: default - runs-on: [self-hosted, Linux, X64] - if: inputs.mb6_ntl_noflag - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb6_ntl_noflag - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb6_ntl_noflag - mathbackend: 6 - run_extras: true - - - ############################################### - # - # mb6_ntl_tcm jobs starts here - # - ############################################### - mb6_ntl_tcm: - needs: [default, mb4_noflag, mb6_ntl_noflag] - runs-on: [self-hosted, Linux, X64] - if: inputs.mb6_ntl_tcm - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb6_ntl_tcm - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb6_ntl_tcm - mathbackend: 6 - with_tcm: true - run_extras: true - - - ############################################### - # - # mb6_ntl_debug_tcm jobs starts here - # - ############################################### - mb6_ntl_debug_tcm: - needs: [default, mb4_noflag, mb6_ntl_noflag] - runs-on: [self-hosted, Linux, X64] - if: inputs.mb6_ntl_debug_tcm - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb6_ntl_debug_tcm - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb6_ntl_debug_tcm - mathbackend: 6 - with_debug: true - with_tcm: true - run_extras: true - - ############################################### - # - # mb2_natopt jobs starts here - # - ############################################### - mb2_natopt: - needs: [default, mb2_debug, mb2_tcm, mb4_noflag, mb4_debug, mb4_tcm, mb6_ntl_noflag, mb6_ntl_debug_tcm, mb6_ntl_tcm] - runs-on: [self-hosted, Linux, X64] - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb2_natopt - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb2_natopt - mathbackend: 2 - with_debug: false - with_nativeopts: true - with_tcm: false - run_extras: false - run_benchmark: true diff --git a/CMakeLists.txt b/CMakeLists.txt index 94ff74584..0f72d76ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,8 +26,8 @@ endif() project (OpenFHE C CXX) set(OPENFHE_VERSION_MAJOR 1) -set(OPENFHE_VERSION_MINOR 1) -set(OPENFHE_VERSION_PATCH 4) +set(OPENFHE_VERSION_MINOR 2) +set(OPENFHE_VERSION_PATCH 0) set(OPENFHE_VERSION ${OPENFHE_VERSION_MAJOR}.${OPENFHE_VERSION_MINOR}.${OPENFHE_VERSION_PATCH}) set(CMAKE_CXX_STANDARD 17) diff --git a/OpenFHEConfig.cmake.in b/OpenFHEConfig.cmake.in index 635342974..35914ecef 100644 --- a/OpenFHEConfig.cmake.in +++ b/OpenFHEConfig.cmake.in @@ -18,17 +18,12 @@ set(OpenFHE_STATIC_LIBRARIES @OpenFHE_STATIC_LIBS@ @THIRDPARTYLIBS@ @OpenMP_CXX_ set(OpenFHE_SHARED_LIBRARIES @OpenFHE_SHARED_LIBS@ @THIRDPARTYLIBS@ @OpenMP_CXX_FLAGS@) set(BASE_OPENFHE_VERSION @OPENFHE_VERSION@) -set(OPENMP_INCLUDES "@OPENMP_INCLUDES@" ) -set(OPENMP_LIBRARIES "@OPENMP_LIBRARIES@" ) +set(OPENMP_INCLUDES "@OPENMP_INCLUDES@") +set(OPENMP_LIBRARIES "@OPENMP_LIBRARIES@") set(OpenFHE_CXX_FLAGS "@CMAKE_CXX_FLAGS@") set(OpenFHE_C_FLAGS "@CMAKE_C_FLAGS@") -if( "@WITH_NTL@" STREQUAL "Y" ) - set(OpenFHE_CXX_FLAGS "${OpenFHE_CXX_FLAGS} -DWITH_NTL" ) - set(OpenFHE_C_FLAGS "${OpenFHE_C_FLAGS} -DWITH_NTL") -endif() - set (OpenFHE_EXE_LINKER_FLAGS "@CMAKE_EXE_LINKER_FLAGS@") # CXX info diff --git a/PreLoad.cmake b/PreLoad.cmake index 37029bd67..10a8501bf 100644 --- a/PreLoad.cmake +++ b/PreLoad.cmake @@ -1 +1,5 @@ -set (CMAKE_GENERATOR "Unix Makefiles" CACHE INTERNAL "" FORCE) +# if(WIN32) +if($ENV{MSYSTEM} MATCHES "MINGW") + # message(WARNING "======================= Linking for MINGW") + set(CMAKE_GENERATOR "Unix Makefiles" CACHE INTERNAL "" FORCE) +endif() diff --git a/README.md b/README.md index 498cb21ef..2a21aef26 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ To get familiar with the main API of OpenFHE, we recommend looking at the code o ## Main API - [PKE CryptoContext API (BGV/BFV/CKKS)](https://openfhe-development.readthedocs.io/en/latest/api/classlbcrypto_1_1CryptoContextImpl.html) +- [Description of CryptoContext Parameters for BGV, BFV, and CKKS](https://github.com/openfheorg/openfhe-development/blob/main/src/pke/examples#description-of-the-cryptocontext-parameters-and-their-restrictions) - [BinFHE Context API (FHEW/TFHE)](https://openfhe-development.readthedocs.io/en/latest/api/classlbcrypto_1_1BinFHEContext.html) @@ -110,19 +111,19 @@ We welcome all contributions including but not limited to: ## How to Cite OpenFHE -To cite OpenFHE in academic papers, please use the following BibTeX entry +To cite OpenFHE in academic papers, please use the following BibTeX entry (updated version) ``` @misc{OpenFHE, - author = {Ahmad Al Badawi and Jack Bates and Flavio Bergamaschi and David Bruce Cousins and Saroja Erabelli and Nicholas Genise and Shai Halevi and Hamish Hunt and Andrey Kim and Yongwoo Lee and Zeyu Liu and Daniele Micciancio and Ian Quah and Yuriy Polyakov and Saraswathy R.V. and Kurt Rohloff and Jonathan Saylor and Dmitriy Suponitsky and Matthew Triplett and Vinod Vaikuntanathan and Vincent Zucca}, - title = {OpenFHE: Open-Source Fully Homomorphic Encryption Library}, + author = {Ahmad Al Badawi and Andreea Alexandru and Jack Bates and Flavio Bergamaschi and David Bruce Cousins and Saroja Erabelli and Nicholas Genise and Shai Halevi and Hamish Hunt and Andrey Kim and Yongwoo Lee and Zeyu Liu and Daniele Micciancio and Carlo Pascoe and Yuriy Polyakov and Ian Quah and Saraswathy R.V. and Kurt Rohloff and Jonathan Saylor and Dmitriy Suponitsky and Matthew Triplett and Vinod Vaikuntanathan and Vincent Zucca}, + title = {{OpenFHE}: Open-Source Fully Homomorphic Encryption Library}, howpublished = {Cryptology ePrint Archive, Paper 2022/915}, year = {2022}, note = {\url{https://eprint.iacr.org/2022/915}}, url = {https://eprint.iacr.org/2022/915} } ``` -or, alternatively (WAHC@CCS'22 version), +or, alternatively (original WAHC@CCS'22 version), ``` @inproceedings{10.1145/3560827.3563379, author = {Al Badawi, Ahmad and Bates, Jack and Bergamaschi, Flavio and Cousins, David Bruce and Erabelli, Saroja and Genise, Nicholas and Halevi, Shai and Hunt, Hamish and Kim, Andrey and Lee, Yongwoo and Liu, Zeyu and Micciancio, Daniele and Quah, Ian and Polyakov, Yuriy and R.V., Saraswathy and Rohloff, Kurt and Saylor, Jonathan and Suponitsky, Dmitriy and Triplett, Matthew and Vaikuntanathan, Vinod and Zucca, Vincent}, diff --git a/benchmark/src/binfhe-paramsets.cpp b/benchmark/src/binfhe-paramsets.cpp new file mode 100644 index 000000000..85d54a320 --- /dev/null +++ b/benchmark/src/binfhe-paramsets.cpp @@ -0,0 +1,148 @@ +//================================================================================== +// BSD 2-Clause License +// +// Copyright (c) 2014-2024, NJIT, Duality Technologies Inc. and other contributors +// +// All rights reserved. +// +// Author TPOC: contact@openfhe.org +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//================================================================================== + +#include "benchmark/benchmark.h" +#include "binfhecontext.h" + +#include + +using namespace lbcrypto; + +[[maybe_unused]] static void FHEW_BTKEYGEN(benchmark::State& state, BINFHE_PARAMSET s, BINFHE_METHOD m) { + auto cc = BinFHEContext(); + cc.GenerateBinFHEContext(s, m); + for (auto _ : state) + cc.BTKeyGen(cc.KeyGen()); +} + +[[maybe_unused]] static void FHEW_ENCRYPT(benchmark::State& state, BINFHE_PARAMSET s, BINFHE_METHOD m) { + auto cc = BinFHEContext(); + cc.GenerateBinFHEContext(s, m); + auto sk = cc.KeyGen(); + auto x = std::bind(std::uniform_int_distribution(0, 1), std::default_random_engine()); + for (auto _ : state) + auto ct = cc.Encrypt(sk, x()); +} + +[[maybe_unused]] static void FHEW_NOT(benchmark::State& state, BINFHE_PARAMSET s, BINFHE_METHOD m) { + auto cc = BinFHEContext(); + cc.GenerateBinFHEContext(s, m); + auto sk = cc.KeyGen(); + auto x = std::bind(std::uniform_int_distribution(0, 1), std::default_random_engine()); + for (auto _ : state) + auto ct = cc.EvalNOT(cc.Encrypt(sk, x())); +} + +[[maybe_unused]] static void FHEW_BINGATE2(benchmark::State& state, BINFHE_PARAMSET s, BINFHE_METHOD m, BINGATE g) { + auto cc = BinFHEContext(); + cc.GenerateBinFHEContext(s, m); + auto sk = cc.KeyGen(); + cc.BTKeyGen(sk); + auto x = std::bind(std::uniform_int_distribution(0, 1), std::default_random_engine()); + for (auto _ : state) + auto ct = cc.EvalBinGate(g, cc.Encrypt(sk, x(), SMALL_DIM, 4), cc.Encrypt(sk, x(), SMALL_DIM, 4)); +} + +[[maybe_unused]] static void FHEW_BINGATE3(benchmark::State& state, BINFHE_PARAMSET s, BINFHE_METHOD m, BINGATE g) { + auto cc = BinFHEContext(); + cc.GenerateBinFHEContext(s, m); + auto sk = cc.KeyGen(); + cc.BTKeyGen(sk); + auto x = std::bind(std::uniform_int_distribution(0, 1), std::default_random_engine()); + for (auto _ : state) + auto ct = cc.EvalBinGate( + g, std::vector{cc.Encrypt(sk, x(), SMALL_DIM, 6), cc.Encrypt(sk, x(), SMALL_DIM, 6), + cc.Encrypt(sk, x(), SMALL_DIM, 6)}); +} + +[[maybe_unused]] static void FHEW_BINGATE4(benchmark::State& state, BINFHE_PARAMSET s, BINFHE_METHOD m, BINGATE g) { + auto cc = BinFHEContext(); + cc.GenerateBinFHEContext(s, m); + auto sk = cc.KeyGen(); + cc.BTKeyGen(sk); + auto x = std::bind(std::uniform_int_distribution(0, 1), std::default_random_engine()); + for (auto _ : state) + auto ct = cc.EvalBinGate( + g, std::vector{cc.Encrypt(sk, x(), SMALL_DIM, 8), cc.Encrypt(sk, x(), SMALL_DIM, 8), + cc.Encrypt(sk, x(), SMALL_DIM, 8), cc.Encrypt(sk, x(), SMALL_DIM, 8)}); +} + +// clang-format off +BENCHMARK_CAPTURE(FHEW_BINGATE2, TOY_2_GINX_OR, TOY, GINX, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, MEDIUM_2_GINX_OR, MEDIUM, GINX, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD128_2_AP_OR, STD128_AP, AP, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD128_2_GINX_OR, STD128, GINX, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD128_3_GINX_OR, STD128_3, GINX, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD128_4_GINX_OR, STD128_4, GINX, OR4)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD128Q_2_GINX_OR, STD128Q, GINX, OR)->Unit(benchmark::kMillisecond); +#if NATIVEINT >= 64 +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD128Q_3_GINX_OR, STD128Q_3, GINX, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD128Q_4_GINX_OR, STD128Q_4, GINX, OR4)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD192_2_GINX_OR, STD192, GINX, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD192_3_GINX_OR, STD192_3, GINX, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD192_4_GINX_OR, STD192_4, GINX, OR4)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD192Q_2_GINX_OR, STD192Q, GINX, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD192Q_3_GINX_OR, STD192Q_3, GINX, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD192Q_4_GINX_OR, STD192Q_4, GINX, OR4)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD256_2_GINX_OR, STD256, GINX, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD256_3_GINX_OR, STD256_3, GINX, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD256_4_GINX_OR, STD256_4, GINX, OR4)->Unit(benchmark::kMillisecond); +#endif +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD256Q_2_GINX_OR, STD256Q, GINX, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD256Q_3_GINX_OR, STD256Q_3, GINX, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD256Q_4_GINX_OR, STD256Q_4, GINX, OR4)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD128_2_LMKCDEY_OR, STD128_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD128_3_LMKCDEY_OR, STD128_3_LMKCDEY, LMKCDEY, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD128_4_LMKCDEY_OR, STD128_4_LMKCDEY, LMKCDEY, OR4)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD128Q_2_LMKCDEY_OR, STD128Q_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD128Q_3_LMKCDEY_OR, STD128Q_3_LMKCDEY, LMKCDEY, OR3)->Unit(benchmark::kMillisecond); +#if NATIVEINT >= 64 +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD128Q_4_LMKCDEY_OR, STD128Q_4_LMKCDEY, LMKCDEY, OR4)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD192_2_LMKCDEY_OR, STD192_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD192_3_LMKCDEY_OR, STD192_3_LMKCDEY, LMKCDEY, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD192_4_LMKCDEY_OR, STD192_4_LMKCDEY, LMKCDEY, OR4)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD192Q_2_LMKCDEY_OR, STD192Q_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD192Q_3_LMKCDEY_OR, STD192Q_3_LMKCDEY, LMKCDEY, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD192Q_4_LMKCDEY_OR, STD192Q_4_LMKCDEY, LMKCDEY, OR4)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD256_2_LMKCDEY_OR, STD256_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD256_3_LMKCDEY_OR, STD256_3_LMKCDEY, LMKCDEY, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD256_4_LMKCDEY_OR, STD256_4_LMKCDEY, LMKCDEY, OR4)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, STD256Q_2_LMKCDEY_OR, STD256Q_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE3, STD256Q_3_LMKCDEY_OR, STD256Q_3_LMKCDEY, LMKCDEY, OR3)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE4, STD256Q_4_LMKCDEY_OR, STD256Q_4_LMKCDEY, LMKCDEY, OR4)->Unit(benchmark::kMillisecond); +#endif +BENCHMARK_CAPTURE(FHEW_BINGATE2, LPF_STD128_2_GINX_OR, LPF_STD128, GINX, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, LPF_STD128Q_2_GINX_OR, LPF_STD128Q, GINX, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, LPF_STD128_2_LMKCDEY_OR, LPF_STD128_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond); +BENCHMARK_CAPTURE(FHEW_BINGATE2, LPF_STD128Q_2_LMKCDEY_OR, LPF_STD128Q_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond); +// clang-format on + +BENCHMARK_MAIN(); diff --git a/docs/requirements.txt b/docs/requirements.txt index 141eb8aac..46b35955d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -5,7 +5,7 @@ certifi>=2023.7.22 charset-normalizer==2.0.12 docutils==0.17.1 exhale>=0.3.0 -idna==3.3 +idna>=3.7 imagesize==1.3.0 importlib-metadata>=4.0.0 jinja2>=3.1.3 diff --git a/docs/sphinx_rsts/contributing/ci_cd_assets/github_openfhe_custom_workflow_options.png b/docs/sphinx_rsts/contributing/ci_cd_assets/github_openfhe_custom_workflow_options.png deleted file mode 100644 index d06425774..000000000 Binary files a/docs/sphinx_rsts/contributing/ci_cd_assets/github_openfhe_custom_workflow_options.png and /dev/null differ diff --git a/docs/sphinx_rsts/contributing/ci_cd_assets/main_workflow_diagram.png b/docs/sphinx_rsts/contributing/ci_cd_assets/main_workflow_diagram.png deleted file mode 100644 index 9b309422c..000000000 Binary files a/docs/sphinx_rsts/contributing/ci_cd_assets/main_workflow_diagram.png and /dev/null differ diff --git a/docs/sphinx_rsts/contributing/ci_cd_assets/manual_workflow_diagram.png b/docs/sphinx_rsts/contributing/ci_cd_assets/manual_workflow_diagram.png deleted file mode 100644 index fb44bfa6f..000000000 Binary files a/docs/sphinx_rsts/contributing/ci_cd_assets/manual_workflow_diagram.png and /dev/null differ diff --git a/docs/sphinx_rsts/contributing/ci_cd_assets/manual_workflow_options.png b/docs/sphinx_rsts/contributing/ci_cd_assets/manual_workflow_options.png index 67886b8db..143b2762d 100644 Binary files a/docs/sphinx_rsts/contributing/ci_cd_assets/manual_workflow_options.png and b/docs/sphinx_rsts/contributing/ci_cd_assets/manual_workflow_options.png differ diff --git a/docs/sphinx_rsts/contributing/ci_cd_assets/pull_request_workflow_diagram.png b/docs/sphinx_rsts/contributing/ci_cd_assets/pull_request_workflow_diagram.png deleted file mode 100644 index 9f436be1c..000000000 Binary files a/docs/sphinx_rsts/contributing/ci_cd_assets/pull_request_workflow_diagram.png and /dev/null differ diff --git a/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step2.png b/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step2.png index 9426bacd9..baa18d5b5 100644 Binary files a/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step2.png and b/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step2.png differ diff --git a/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step3.png b/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step3.png index 7fb013b44..eecb20aa1 100644 Binary files a/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step3.png and b/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step3.png differ diff --git a/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step5.png b/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step5.png index e2d479625..39eb831b4 100644 Binary files a/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step5.png and b/docs/sphinx_rsts/contributing/ci_cd_assets/run_manual_workflow_step5.png differ diff --git a/docs/sphinx_rsts/contributing/developer_ci_cd_docs.rst b/docs/sphinx_rsts/contributing/developer_ci_cd_docs.rst index f18ca2b9e..2bb33d14c 100644 --- a/docs/sphinx_rsts/contributing/developer_ci_cd_docs.rst +++ b/docs/sphinx_rsts/contributing/developer_ci_cd_docs.rst @@ -8,9 +8,16 @@ In order to make modifications to reuseable workflow or actions the CI/CD changes must be made to the [``github-ci``][5] branch. This branch is specially protected, and the OpenFHE repository uses references to the branch for reuseable workflows and actions. +:: + + ├── .github + │ ├── actions <-- Custom GitHub actions + │ │ └─ generic_workflow_builder <-- Custom GitHub actions to bootstrap the build + │ │ └── action.yml <-- Custom action file, defines the steps for a given configuration, cmake -> build -> unittest + │ ├── workflows <-- GitHub workflows(pipelines) + │ └── generic_workflow.yml <-- A reuseable workflow that handles the default builds and tests the important configurations, uses generic_workflow_builder/action.yml For changes to what happens for the -`Custom `_, `Main `_, `Manual `_, or @@ -22,15 +29,10 @@ branch. :: ├── .github - │ ├── actions <-- Custom GitHub actions - │ │ └─ default_builder <-- Custom GitHub actions to bootstrap the build - │ │ └── action.yml <-- Custom action file, defines the steps for a given configuration, cmake -> build -> unittest -> benchmark -> extras │ ├── workflows <-- GitHub workflows(pipelines) - │ ├── custom.yml <-- Runs on-demand a single build of a custom configuration (this can turn all the knobs) - │ ├── main.yml <-- Runs when a branch is merged to main, uses reusable_workflow - │ ├── manual.yml <-- Runs on-demand with parameters - │ ├── pull-request.yml <-- Runs when a pull-request is created, uses reusable_workflow - │ └── reusable_workflow.yml <-- A workflow that handles the default builds and tests the important configurations, uses default_builder/action.yml + │ ├── main.yml <-- Runs when a branch is merged to main, uses generic_workflow + │ ├── manual.yml <-- Runs on-demand with parameters, uses generic_workflow + │ ├── pull-request.yml <-- Runs when a pull-request to main is created, uses generic_workflow Actions ------- @@ -39,25 +41,22 @@ GitHub Actions are used to create function like abilities to the CI/CD. Thus reducing the scripting, lines of code, and complexity of the `workflows <#workflows>`__. There is currently a single action to help build and test a given configuration -`.github/actions/default_builder/action.yml `_. +`.github/actions/generic_workflow_builder/action.yml `_. -Default Builder +Generic Workflow Builder ~~~~~~~~~~~~~~~ -The default builder handles the setup, build, and running of binaries -(such as unittests and benchmarking) for a single configuration. The -flow of the ``Default Builder`` actions is: +This builder handles the setup, build, and running of binaries +(such as unittests) for a single configuration. The flow of +the ``Generic Workflow Builder`` actions is: 1. Cmake configuration based on *inputs* 2. Build the configuration 3. Run unittests on the configuration -4. If benchmarking is requested via *inputs* run the benchmarks (takes a - long time) -5. If extras are requested via *inputs* run the extra binaries The actions are flexible as when can pass ``inputs`` which can be seen in first section of the -`.github/actions/default_builder/action.yml `_. +`.github/actions/generic_workflow_builder/action.yml `_. These inputs can be used throughout the action.yml to change behaviour. .. note:: @@ -74,27 +73,19 @@ Current Action Inputs We currently have the following inputs supported: - **module_name** - friendly string identifier for the configuration -- **cmake_args** - fully customizeable string to override all other - arguments -- **native_backend** - sets the NATIVE_SIZE -- **mathbackend** - set the MATHBACKEND -- **with_debug** - enables the Debug build type -- **with_tcm** - enables TC malloc -- **run_extras** - enables the build and executation of extras. -- **with_nativeopts** - enables native optimizations -- **run_benchmark** - runs benchmarking +- **cmake_args** - string with all arguments set up in the calling workflow Adding New Inputs ~~~~~~~~~~~~~~~~~ To add a new input to the action it will need to be added to the ``inputs`` section in the -`.github/actions/default_builder/action.yml `__. +`.github/actions/generic_workflow_builder/action.yml `__. There is a constraint of 10 inputs, so care needs to be taking when selecting inputs. Select that the type of the input for your input and choose a default value that will not alter the previous behavior of the important `workflows <#workflows>`__ After adding the parameter to -`action.yml `__ +`action.yml `__ you must set it using the ``with`` field, shown below, in any workflow that you want to use the new parameter. @@ -102,7 +93,7 @@ that you want to use the new parameter. .. code:: yaml - name: 'Default Builder' + name: 'Generic Workflow Builder' inputs: my_new_input: @@ -114,33 +105,29 @@ that you want to use the new parameter. .. code:: yaml - uses: ./.github/actions/default_builder + uses: ./.github/actions/generic_workflow_builder with: - module_name: mb4_tcm - mathbackend: 4 - with_tcm: true - run_extras: true + module_name: ${{ github.job }} + # ... my_new_input: 'Do something new!' *Using the input value in the action procedure* .. code:: yaml - runs: - ... - run: | - echo "New input has value: ${{inputs.my_new_input}}" + runs: + # ... + run: | + echo "New input has value: ${{inputs.my_new_input}}" The ``${{}}`` is how the procedure can access the passed in value Workflows --------- -When designing the `our -workflows `__ for -OpenFHE we took the approach of bundling multiple configurations -together. This influenced how the -`action.yml `__ +When designing the `workflows <#workflows>`__ for OpenFHE we took the approach +of bundling multiple configurations together. This influenced how the +`action.yml `__ was designed, as we want to have the server configure, build, and run outputs without needing to pass artifacts around. Previously we had done all the builds for every configuration, then ran all the unittests for @@ -148,92 +135,62 @@ all the configurations, etc. This required over 20GB of artifacts be passed around. This means that each conifguration must build and pass all tests before another build can be evaluated. +Currently the default build always runs, and the other builds depend on it. Even when the other workflow jobs are off. + .. note:: For more general information on GitHub Workflows please visit `Using Workflows `__ -There are 5 total Workflows: - -- `Custom <#Custom-Workflow>`_ - Used to kick off a single build and test that can turn all the knobs. +There are 3 custom and one reuseable workflows: -- `Main <#Main-Workflow>`_ - Used to extensively test pushes to the main branch and publish docs. +- `Main <#main-workflow>`__ - To extensively test pushes to the main branch and publish docs. - - This also runs if pushes are made to the `github-ci `__ branch to allow testing and development of the CI. - +- `Manual <#manual-workflow>`__ - To do a batch of builds with a control over compilers, native size, configurations. -- `Manual <#manual-workflow>`_ - Used to do a batch of builds with a control over compilers, native size, configurations +- `Pull-Request <#pull-request-workflow>`__ - To test any pull-requests generated, this tests a healthy number of configurations but is not as extensive as **Main**. -- `Pull-Request <#pull-request-workflow>`__ - Used to test any pull-requests generated, this tests a healthy number of configurations but is not as extensive as **Main**. +- `Generic/Reuseable Workflow <#generic-reuseable-workflow>`__ - To be called by any custom workflow. -- `Reuseable Workflow `__ - This is not run from the GitHub UI, but instead is used to allow ``pull-request`` and ``main`` workflows to use a large portion of shared code. - -Custom Workflow -~~~~~~~~~~~~~~~ - -The custom workflow allows to select a number of options that are -supported and worth testing on a server. See the diagram below for the -options. All the options are created in the -`.github/workflows/custom.yml `__ -file under the ``on.workflow_dispatch.inputs`` property. The ``jobs`` -property is short and sweet for this workflow as it is only going to -kickoff a single ``default_builder`` action with the corresponding -option values. This workflow essentially gives the UI direct access to -the ``default_builder``. +They all allow to select a number of options that are supported and worth testing on a server. +NOTE: ALL the options for Manual must exist in both properties ``on.workflow_call.inputs`` and ``on.workflow_dispatch.inputs``. +It is necessary as Manual calls a reuseable workflow. +As Main and Pull-Request are kicked off automatically and all their input options are hardcoded +in the ``job`` section under the ``with`` property. .. note:: There is a limit of 10 inputs. JSON Maps ^^^^^^^^^ -There are two important JSON maps in the `Custom -Workflow <#custom-workflow>`__ to map the string input options, as the -key, to a corresponding cmake/action string value to pass onward. The -value for each map pair is corresponds to the lower level requirements, -thus whatever the option is driving is what the map’s value is derived -from. This is why the ``MATHBACKEND`` is a number value and the -``COMPILER`` is a direct cmake argument string. Currently to (and for -simplicity this will likely remain) set the compiler the ``cmake_arg`` -override argument is used to set the desired compiler. For more info on -the compiler map visit section `Compiler -Selection <#compiler-selection>`__ +There are two important JSON maps used in the workflows: -.. warning:: Before adding new compiler options developers must ensure that the - server as the compiler installed and match the path correctly in the - JSON map. +- **cmake_args_map** - maps the job name to the job's specific set of cmake arguments (3 custom workflows only) +- **COMPILERS_MAP** - converts the input Compiler Type to a string with cmake arguments to set the compiler for C and C++ (generic_workflow only) -**example JSON map definition** - -.. code:: yaml +.. warning:: Before adding a new compiler option developers must ensure that the + server has the compiler installed and the cmake arguments specifying that compiler's path are correctly set in the JSON map. - env: - MATHBACKEND_MAP: >- - { - "Fixed" : "2", - "Dynamic" : "4", - "NTL" : "6" - } - -**Passing json map’s value to custom action** +**example: passing a JSON map as an input to generic_workflow.yml** .. code:: yaml jobs: - default: - # ... - - name: default - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - # ... - mathbackend: ${{ fromJson(env.MATHBACKEND_MAP)[github.event.inputs.mathbackend] }} - # ... - + call: + uses: openfheorg/openfhe-development/.github/workflows/generic_workflow.yml@github-ci + with: + # ... + # cmake_args_map holds job specific additional cmake options. compiler flags, native_backend flag and + # OpenMP flag are set in generic_workflow.yml + cmake_args_map: '{ + # ... + "mb2" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2", + "mb2_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=2 -DWITH_TCM=ON", + # ... + "mb6_ntl_debug_tcm" : "-DBUILD_EXTRAS=ON -DMATHBACKEND=6 -DWITH_NTL=ON -DWITH_TCM=ON -DCMAKE_BUILD_TYPE=Debug", + }' .. - -.. warning:: The map’s keys are not linked to the inputs options, this must be - manually kept in sync. - -.. figure:: ci_cd_assets/github_openfhe_custom_workflow_options.png - :alt: github_openfhe_custom_workflow_options +.. warning:: The map’s keys are not linked to the inputs options, this must be manually kept in sync. .. _pull-request-workflow-1: @@ -242,11 +199,9 @@ Pull-Request Workflow The `pull-request.yml `__ -defines the Pull-Request Workflow. The Pull-Request Workflow is run -whenever under 2 conditions: first when a pull-request is opened and -whenever changes are pushed to that branch will the pull-request is -open. The workflow runs on the branch linked to the pull-request. This -is defined by the following code snippet. +defines the Pull-Request Workflow, which runs when a pull request is +opened or reopened or when the head branch of the pull request is updated. +Currently it is setup to run on the main branch only. This is defined by the following code snippet. .. code:: yaml @@ -255,11 +210,8 @@ is defined by the following code snippet. branches: - main -The Pull-Request Workflow only runs one job which is the `Reuseable -Workflow <#reuseable-workflow>`__ with all inputs set to ``true``. - -**Notable differences** \* Doesn’t publish docs \* Doesn’t do -``NATIVE_SIZE=128`` or clang compiler tests +The Pull-Request Workflow calls `Generic/Reuseable Workflow <#generic-reuseable-workflow>`__ and +runs all jobs with ``NATIVE_SIZE=128`` and ``GCC`` only. .. _main-workflow-1: @@ -268,11 +220,7 @@ Main Workflow The `main.yml `__ -defines the Main Workflow, which runs when changes are pushed to main. -The Main Workflow is also run when changes are pushed to the branch -`github-ci `__ -but this is for testing and development purposes of new CI/CD features. -This is defined by the code snippet: +defines the Main Workflow, which runs when changes are pushed to the main branch. .. code:: yaml @@ -280,29 +228,31 @@ This is defined by the code snippet: push: branches: - main - - github-ci - -The Main Workflow use the `Reuseable Workflow <#reuseable-workflow>`__ -for the bulk of the jobs. In addition this workflow has 2 other -important testing jobs are run using the -`default_builder <#default-builder>`__ action to test -``NATIVE_SIZE=128`` (mb2_128) and compilation with clang (mb2_clang). -And lastly this workflow has a job that pushes the doxygen generate -documentation to a specific branch, -`gh-pages `__ -in the repository, is best access through the -`github-pages `__. - -Reuseable Workflow + +The Main Workflow calls `Generic/Reuseable Workflow <#generic-reuseable-workflow>`__ and +runs all jobs with all native backends and with both GCC and CLANG. +And lastly this workflow has a job that pushes the doxygen generated documentation to a specific branch, +`gh-pages `__ in the repository. + +.. _manual-workflow-1: + +Manual workflow +~~~~~~~~~~~~~~~ + +The manual workflow allows for more configurations to be tested and the flexibility to test unique combinations of the compiler, +NativeInteger sizes and jobs. + +.. figure:: ci_cd_assets/manual_workflow_options.png + :alt: manual_workflow_options + +.. _generic-reuseable-workflow-1: + +Generic/Reuseable Workflow ~~~~~~~~~~~~~~~~~~ -The -`reuseable_workflow.yml `__ -defines the Reuseable Workflow, which is not run directly through GitHub -pushes, pull-requests, or UI interactions. Instead this workflow -encapuslates the bulk of the CI/CD that should be use in multiple -workflows. This workflow is declared reuseable by the following code -snippet: +The ``generic_workflow.yml`` defines the reuseable workflow, which is not run directly through GitHub +pushes, pull-requests, or UI interactions. Instead this workflow encapuslates the bulk of the CI/CD that should be used +in multiple workflows. This workflow is declared reuseable by the following code snippet: .. code:: yaml @@ -311,139 +261,43 @@ snippet: inputs: # ... -Where ``workflow_call`` property enables other workflows to run this -entire workflow through the following calling squence: +Where ``workflow_call`` property enables other workflows to run this entire workflow through the following calling squence: .. code:: yaml jobs: call: - uses: openfheorg/openfhe-development/.github/workflows/reuseable_workflow.yml@github-ci + uses: openfheorg/openfhe-development/.github/workflows/generic_workflow.yml@github-ci with: # ... -The Reuseable Workflow makes use of the `Default -Builer <#default-builder>`__ to run configuration checks for a number of -configurations that correspond to the Reuseable Workflow’s ``inputs``. +The workflow makes use of the `Generic Workflow Builder <#generic-workflow-builder>`__ to run a number of configurations that correspond to +the workflow’s ``inputs``. **Inputs** -- mb2_debug -- mb2_tcm -- mb4_noflag -- mb4_debug -- mb4_tcm -- mb6_ntl_noflag -- mb6_ntl_debug_tcm -- mb6_ntl_tcm - -Each of these ``inputs`` is a boolean that enables or disables the -corresponding job. There is one job that is implicitly always enabled, -``default``, which is also mb2_noflag if the same naming convention was -used. The ``default`` job is the portable build and what is created when -no inputs are given to cmake. This allows other workflows to turn off -pieces of the workflow if not desired. This is done by using the inputs -in the following way: - -.. code:: yaml - - mb2_tcm: - needs: [default, mb4_noflag, mb6_ntl_noflag] - runs-on: [self-hosted, Linux, X64] - # This is the line that enables/disables the mb2_tcm job! - # There for everything after this line, for this indented section, is skipped - if: inputs.mb2_tcm - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: mb2_tcm - uses: openfheorg/openfhe-development/.github/actions/default_builder@github-ci - with: - module_name: mb2_tcm - mathbackend: 2 - with_tcm: true - run_extras: true - -.. _manual-workflow-1: - -Manual workflow -~~~~~~~~~~~~~~~ - -The manual workflow allows for more configurations to be tested and the -flexibility to test unique combinations. Should a new parameter be added -it will need to be added to the ``on.workflow_dispathc.inputs`` section. -Currently we have inputs of type ``options`` which will yield a dropdown -and ``boolean`` which will yield a toggle box. There is a third type -GitHub supports which is a ``string`` that we don’t use on purpose. - -Currently the default build is always run, and like the -`main <#main-workflow>`__ and `pull-request <#pull-request>`__ workflows -the other builds depend on it. The difference is that each of the -secondary build configurations can be enabled/disabled. By default none -of the secondary builds are enabled. The code that enabled this is shown -in the `Enablable Build <#enablable-build>`__ - -.. figure:: ci_cd_assets/manual_workflow_options.png - :alt: manual_workflow_options - -Enablable Build -^^^^^^^^^^^^^^^ - -The code that allows the individual builds are a combination of the -boolean inputs and an ``if`` in the *jobs*. See the example below for -the **debug_mb2** - -*input section* - -.. code:: yaml - - debug_mb2: - description: 'Run debug_mb2' - type: boolean - required: true - default: 'false' - -The ``type`` key defines this input to be a checkbox, true or false, and -the ``default`` unchecks/disables this by default. This key itself, -``debug_mb2``, will be what is used later to enable/disable the job to -run. +- MATHBACKEND2 jobs: mb2, mb2_tcm, mb2_debug, all, none +- MATHBACKEND4 jobs: mb4, mb4_tcm, mb4_debug, all, none +- MATHBACKEND6 jobs: mb6_ntl, mb6_ntl_tcm, mb6_ntl_debug_tcm, all, none -*job section* - -.. code:: yaml - - debug_mb2: - needs: default - if: ${{ github.event.inputs.debug_mb2 == 'true' }} - runs-on: [self-hosted, Linux, X64] - env: - -The ``needs`` key, first line in the *debug_mb2* job, is to create a -dependancy on the default, thus this will run after the default -configuration completes. The ``if`` key, second line, is where we -conditionally run the job, this logic uses the input parameter -``debug_mb2`` and skips the rest of this second if it is false. +Each of these ``inputs`` enables or disables the corresponding job(s). Just a reminder that one job +``default`` is always implicitly enabled. Compiler Selection ^^^^^^^^^^^^^^^^^^ -Selecting the compiler is a bit convoluted, the JSON syntax is used to -create a map between compilers and the cmake options to use the compiler -selected. This map uses the -``workflow_dispatch.inputs.compiler.options`` as the key, and the cmake -equivalent option as the value. +Selecting the compiler is a bit convoluted, the JSON syntax is used to create a map between compilers and +the cmake options to use the compiler selected. This map uses the ``workflow_call.inputs.compiler`` as the key in +`.github/workflows/generic_workflow.yml `__. +and the cmake equivalent option as the value. .. note:: This is linked by the definition of **COMPILERS_MAP** in the jobs - - Modifying the input will require modification of all *env.COMPILERS_MAP* - -Because we want to support many compilers and versions we will need to -expose more pairs in the future. For now the key things to understand is -the map and how it’s used. + - Modifying the compiler input will require modification of *env.COMPILERS_MAP* + - Getting cmake compiler options can’t be done in the `.github/actions/generic_builder/action.yml `__, + as access to the ``fromJson`` function isn't available in that scope. -Below is how we’ve created the map, we use JSON syntax in the yml and do -so on multiple lines with ``>-`` operator. +Below is a part of the existing map using the ``>-`` operator for multiple lines: *Compiler map definition* @@ -451,39 +305,26 @@ so on multiple lines with ``>-`` operator. COMPILERS_MAP: >- { - "GCC" : "-DCMAKE_CXX_COMPILER=/usr/bin/g++-9 -DCMAKE_C_COMPILER=/usr/bin/gcc-9", - "CLANG" : "-DCMAKE_CXX_COMPILER=/usr/bin/clang++-10 -DCMAKE_C_COMPILER=/usr/bin/clang-10" + # ... + "GCC-11" : "-DCMAKE_CXX_COMPILER=/usr/bin/g++-11 -DCMAKE_C_COMPILER=/usr/bin/gcc-11", + # ... + "CLANG-14" : "-DCMAKE_CXX_COMPILER=/usr/bin/clang++-14 -DCMAKE_C_COMPILER=/usr/bin/clang-14" } -Below is a snippet to parse the cmake options from the selected compiler -input - -*Compiler map value access by key input* - -.. code:: yaml - - cmake_args: ${{ fromJson(env.COMPILERS_MAP)[github.event.inputs.compiler] }} - -.. - - .. note:: This can’t be done in the `.github/actions/default_builder/action.yml `__, - as access to the ``fromJson`` function isn't available in that scope. - Modifying or Adding New Workflows ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When developing a new workflow it is required that the *Default Branch* -be set to whatever your development branch is to expose the workflows, -and thus reverted on completetion. This can be done by navigating to the -repository’s ``Settings > Branches`` and selecting a new *Default -Branch* as shown below. +When developing a new workflow it is required that the *Default Branch* be set to whatever +your development branch is to expose the workflows, and thus reverted on completion. +This can be done by navigating to the repository’s ``Settings > Branches`` and selecting +a new *Default Branch* as shown below. .. figure:: ci_cd_assets/switch_default_branch_diagram.png :alt: switch_default_branch_diagram -When modifying an existing workflow there are a few approaches for -testing your changes. If the changes are to -`pull-request <#pull-request>`__ as soon as a pull-request is generated. +When modifying an existing workflow then you should test the changes on your feature branch. +The feature branch can be picked from the "Use workflow from" drop-down menu for `Manual <#manual-workflow>`__ or +can be hardcoded for testing for `Main <#main-workflow>`__ or `Pull-Request <#pull-request-workflow>`__. **Please take care with naming new workflows** - Follow the design pattern already in use, where the Workflows name and the corresponding @@ -507,7 +348,7 @@ OpenFHE To see how to setup `linux_platform_packages.sh `__ in the repository, or run it on your linux platform. -.. note:: This is for an Ubuntu 20.04 distribution +.. note:: This is for an Ubuntu 22.04 distribution Launch an EC2 Instance using AWS CLI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/sphinx_rsts/contributing/user_ci_cd_docs.rst b/docs/sphinx_rsts/contributing/user_ci_cd_docs.rst index 5f595aa9c..f9e7b5de9 100644 --- a/docs/sphinx_rsts/contributing/user_ci_cd_docs.rst +++ b/docs/sphinx_rsts/contributing/user_ci_cd_docs.rst @@ -4,116 +4,116 @@ OpenFHE CI/CD Users Guide Introduction ------------ -This documentation is about the CI/CD Transition from GitLab pipeline to -GitHub Actions workflow. It is also intended to improve our CI/CD -capabilities in the new GitHub environment. Directory structure +This documentation describes OpenFHE workflows on GitHub. Repository: https://github.com/openfheorg/openfhe-development :: ├── .github - │ ├── actions <-- Custom GitHub actions - │ │ └─ default_builder <-- Custom GitHub actions to bootstrap the build - │ │ └── action.yml <-- Custom action file, defines the steps for a given configuration, cmake -> build -> unittest -> benchmark -> extras │ ├── workflows <-- GitHub workflows(pipelines) - │ ├── custom.yml <-- Runs on-demand a single build of a custom configuration (this can turn all the knobs) - │ ├── main.yml <-- Runs when a branch is merged to main, uses reusable_workflow - │ ├── manual.yml <-- Runs on-demand with parameters - │ ├── pull-request.yml <-- Runs when a pull-request is created, uses reusable_workflow - │ └── reusable_workflow.yml <-- A workflow that handles the default builds and tests the important configurations, uses default_builder/action.yml + │ ├── main.yml <-- Runs when a branch is merged to main, uses generic_workflow + │ ├── manual.yml <-- Runs on-demand with parameters, uses generic_workflow + │ ├── pull-request.yml <-- Runs when a pull-request to main is created, uses generic_workflow OpenFHE Workflows ----------------- -A workflow is a configurable automated process made up of one or more -jobs. Workflow files use YAML syntax, and must have either a .yml or -.yaml file extension. +A workflow is a configurable automated process made up of one or more jobs. Workflow files use YAML syntax, +and must have either a .yml or .yaml file extension. -Actions are individual tasks that we can combine to create jobs and -customize our workflow. We created a custom action that wraps up all the -common functionality on our jobs. +Actions are individual tasks that we can combine to create jobs and customize our workflow. We created a custom action +that wraps up all the common functionality on our jobs. Features ~~~~~~~~ -- Custom Github Actions (default-builder) -- Workflows are separated into three YAML files (main.yml manual.yml - pull-request.yml) -- Manual pipeline that can be run with a custom parameters +- Custom Github Actions (generic_workflow_builder) +- Workflows are separated into three YAML files (main.yml manual.yml pull-request.yml) +- Manual pipeline that can be run with custom parameters - Build and deploy docs to Github pages only on main branch -- Jobs run in parallel +- Jobs can run in parallel - The benchmark outputs are exported as artifacts - Runs on a self-hosted runners +- All jobs build unittests, benchmarks and extras +- All jobs run unittests +- If the job name includes _tcm, _debug, _ntl, etc., then the job runs with that option (those options) + .. warning: We need to add multiple runners to support concurrent jobs (one self-hosted runner can only run one job at a time) Pull request Workflow --------------------- -This workflow will run whenever a pull request is created against the -main branch. The pull request will run the default job as well as all -the build jobs. - -.. figure:: ci_cd_assets/pull_request_workflow_diagram.png - :alt: pull_request_workflow_diagram - -The test configurations for each job are shown in the table below - -+---------+---------+---------+---------+---------+---------+---------+ -| Build | Build | Build | Build | With | With | Backend | -| name | U | Be | Extras | TCM | debug | | -| | nitTest | nchmark | | | | | -+=========+=========+=========+=========+=========+=========+=========+ -| default | ON | OFF | OFF | OFF | OFF | Not Set | -+---------+---------+---------+---------+---------+---------+---------+ -| mb | ON | OFF | ON | OFF | ON | 2 | -| 2_debug | | | | | | | -+---------+---------+---------+---------+---------+---------+---------+ -| mb2_tcm | ON | OFF | ON | ON | OFF | 2 | -+---------+---------+---------+---------+---------+---------+---------+ -| mb4 | ON | OFF | ON | OFF | OFF | 4 | -| _noflag | | | | | | | -+---------+---------+---------+---------+---------+---------+---------+ -| mb | ON | OFF | ON | OFF | ON | 4 | -| 4_debug | | | | | | | -+---------+---------+---------+---------+---------+---------+---------+ -| mb4_tcm | ON | OFF | ON | ON | OFF | 4 | -+---------+---------+---------+---------+---------+---------+---------+ -| mb6 | ON | OFF | ON | OFF | OFF | 6 | -| _noflag | | | | | | | -+---------+---------+---------+---------+---------+---------+---------+ -| mb6_de | ON | OFF | ON | ON | ON | 6 | -| bug_tcm | | | | | | | -+---------+---------+---------+---------+---------+---------+---------+ -| mb6_tcm | ON | OFF | ON | ON | OFF | 6 | -+---------+---------+---------+---------+---------+---------+---------+ -| mb2 | ON | ON | ON | ON | OFF | 6 | -| _natopt | | | | | | | -+---------+---------+---------+---------+---------+---------+---------+ +This workflow will run whenever a pull request is created against the main branch. The pull request will run +the default job as well as all build jobs. + +The test configurations for all job are shown in the table below: + ++-------------------+---------+---------------+-----------+ +| Build name | Backend | NativeInteger | Compiler | +| | | size(s) | type(s) | ++=========+=========+=========+===============+===========+ +| default | Not Set | 64 | GCC | ++-------------------+---------+---------------+-----------+ +| mb2 | 2 | 64 | GCC | ++-------------------+---------+---------------+-----------+ +| mb2_tcm | 2 | 64 | GCC | ++-------------------+---------+---------------+-----------+ +| mb2_debug | 2 | 64 | GCC | ++-------------------+---------+---------------+-----------+ +| mb4 | 4 | 64 | GCC | ++-------------------+---------+---------------+-----------+ +| mb4_tcm | 4 | 64 | GCC | ++-------------------+---------+---------------+-----------+ +| mb4_debug | 4 | 64 | GCC | ++-------------------+---------+---------------+-----------+ +| mb6_ntl | 6 | 64 | GCC | ++-------------------+---------+---------------+-----------+ +| mb6_ntl_tcm | 6 | 64 | GCC | ++-------------------+---------+---------------+-----------+ +| mb6_ntl_debug_tcm | 6 | 64 | GCC | ++-------------------+---------+---------------+-----------+ Main User Workflow ------------------ -The main workflow runs whenever a pull-request is merged to the main -branch. The build is similar to the pull-request build, but It also runs -the Pages job which builds and publishes the doxygen apidocs in GitHub -pages. - -.. figure:: ci_cd_assets/main_workflow_diagram.png - :alt: main_workflow_diagram +The main workflow runs whenever a pull-request is merged to the main branch. The build is very similar to +the pull-request build. It runs more tests and also runs the Pages job which builds and publishes +the doxygen apidocs in GitHub pages. + +The test configurations for all job are shown in the table below: + ++-------------------+---------+---------------+-----------+ +| Build name | Backend | NativeInteger | Compiler | +| | | size(s) | type(s) | ++=========+=========+=========+===============+===========+ +| default | Not Set | 32/64/128 | GCC/CLANG | ++-------------------+---------+---------------+-----------+ +| mb2 | 2 | 32/64/128 | GCC/CLANG | ++-------------------+---------+---------------+-----------+ +| mb2_tcm | 2 | 32/64/128 | GCC/CLANG | ++-------------------+---------+---------------+-----------+ +| mb2_debug | 2 | 32/64/128 | GCC/CLANG | ++-------------------+---------+---------------+-----------+ +| mb4 | 4 | 32/64/128 | GCC/CLANG | ++-------------------+---------+---------------+-----------+ +| mb4_tcm | 4 | 32/64/128 | GCC/CLANG | ++-------------------+---------+---------------+-----------+ +| mb4_debug | 4 | 32/64/128 | GCC/CLANG | ++-------------------+---------+---------------+-----------+ +| mb6_ntl | 6 | 32/64/128 | GCC/CLANG | ++-------------------+---------+---------------+-----------+ +| mb6_ntl_tcm | 6 | 32/64/128 | GCC/CLANG | ++-------------------+---------+---------------+-----------+ +| mb6_ntl_debug_tcm | 6 | 32/64/128 | GCC/CLANG | ++-------------------+---------+---------------+-----------+ Manual User Workflow -------------------- -The manual pipeline is a workflow that can be run with custom -parameters. It also allows running specific selected jobs. - -.. figure:: ci_cd_assets/manual_workflow_diagram.png - :alt: manual_workflow_diagram - -Run manual workflow -~~~~~~~~~~~~~~~~~~~ +The manual pipeline is a workflow that can be run with custom parameters and allows to select jobs to run. +To run manual workflow: 1. Go to the openfhe-development repository at this URL: https://github.com/openfheorg/openfhe-development diff --git a/docs/sphinx_rsts/intro/tutorials.rst b/docs/sphinx_rsts/intro/tutorials.rst index f4d92fef9..c86d1c7de 100644 --- a/docs/sphinx_rsts/intro/tutorials.rst +++ b/docs/sphinx_rsts/intro/tutorials.rst @@ -1,6 +1,8 @@ Tutorials on Cryptographic Capabilities ==================================== +- `Description of the CryptoContext parameters for BGV, BFV, and CKKS `_ + - `CKKS Noise Flooding `_ - `Smooth Arbitrary Function Evaluation in CKKS `_ diff --git a/docs/static_docs/Release_Notes.md b/docs/static_docs/Release_Notes.md index 183b5c874..6610af402 100644 --- a/docs/static_docs/Release_Notes.md +++ b/docs/static_docs/Release_Notes.md @@ -1,3 +1,17 @@ +06/25/2024: OpenFHE 1.2.0 (stable) is released + +* Updates the lattice parameters tables to support the ring dimension of 2^{16} and 2^{17} for ternary and Gaussian secrets (#806) +* Adds application specifications validator for BGV, BFV, and CKKS (#710) +* Updates the parameter sets for CGGI/DM/LMKCDEY; adds low-probability-of-failure parameter sets (below 2^{-120}) (#673) +* Adds several optimizations for BFV, including support for modulus switching during computation (#682, #715, #731) +* Fixes parameter estimation bugs for BGV, BFV, and CKKS (insecure configurations were possible for scenarios with hybrid key switching) (#785, #786) +* Includes several fixes related to handling the map of automorphism keys for various EvalSum*KeyGen operations (#756, #773, #783, #797) +* Add support for selective serialization/deserialization of automorphism/rotation keys (#775) +* Updates the HRA-Secure BGV PRE implementation based on https://eprint.iacr.org/2024/681 (#767) +* Includes many other bug fixes + +The detailed list of changes is available at https://github.com/openfheorg/openfhe-development/issues?q=is%3Aissue+milestone%3A%22Release+1.2.0%22 + 03/08/2024: OpenFHE 1.1.4 (stable) is released * Fixes a bug affecting the Google C++ Transpiler code generation (#701) diff --git a/scripts/setup/linux_platform_packages.sh b/scripts/setup/linux_platform_packages.sh index 19f3a1a1b..f5683ab05 100644 --- a/scripts/setup/linux_platform_packages.sh +++ b/scripts/setup/linux_platform_packages.sh @@ -2,27 +2,42 @@ # # This script can be used to install all of the requistes for the Linux Platform # -# https://github.com/openfheorg/openfhe-development/wiki/Instructions-for-building-OpenFHE-in-Linux -# update -sudo apt-get update +# run update before installing every package # install cmake -sudo apt-get install -y cmake=3.16.3-1ubuntu1 +sudo apt-get update +sudo apt-get install -y cmake # install required packages +sudo apt-get update sudo apt-get install -y build-essential +sudo apt-get update sudo apt-get install -y autoconf -sudo apt-get install -y libntl-dev -sudo apt-get install -y libgmp-dev +sudo apt-get update sudo apt-get install -y libtool +sudo apt-get update +sudo apt-get install -y libgmp-dev +sudo apt-get update +sudo apt-get install -y libntl-dev -# install clang -sudo apt-get install -y clang-10 - -# Install optional extra compilers for manual pipeline -sudo apt-get install -y g++-11 g++-10 clang-9 clang-11 +# install all necessary and additional compilers +sudo apt-get update +sudo apt-get install -y g++-9 g++-10 g++-11 g++-12 +sudo apt-get update +sudo apt-get install -y clang-12 clang-13 clang-14 clang-15 # for documentation -sudo apt-get install doxygen -y -sudo apt-get install graphviz -y \ No newline at end of file +sudo apt-get update +sudo apt-get install -y doxygen +sudo apt-get update +sudo apt-get install -y graphviz + +# python packages +sudo apt-get update +sudo apt-get install -y python3-pip +sudo apt-get update +sudo pip install pybind11[global] +sudo apt-get update +sudo apt-get install -y python3-pytest +# to verify pytest installation: python3 -m pip show pytest \ No newline at end of file diff --git a/src/binfhe/examples/boolean-multi-input.cpp b/src/binfhe/examples/boolean-multi-input.cpp index e2c17b224..d5f8d9b0c 100644 --- a/src/binfhe/examples/boolean-multi-input.cpp +++ b/src/binfhe/examples/boolean-multi-input.cpp @@ -42,7 +42,7 @@ int main() { auto cc = BinFHEContext(); - cc.GenerateBinFHEContext(STD128_4_LMKCDEY, LMKCDEY); + cc.GenerateBinFHEContext(STD128_4, GINX); // Sample Program: Step 2: Key Generation diff --git a/src/binfhe/include/binfhe-constants.h b/src/binfhe/include/binfhe-constants.h index 15e0ea9e9..fbd002839 100644 --- a/src/binfhe/include/binfhe-constants.h +++ b/src/binfhe/include/binfhe-constants.h @@ -45,61 +45,56 @@ using LWEPlaintextModulus = uint64_t; /** * @brief Security levels for predefined parameter sets */ +// clang-format off enum BINFHE_PARAMSET { - TOY, // no security - MEDIUM, // 108 bits of security for classical and 100 bits for quantum - STD128_LMKCDEY, // Optimized for LMKCDEY (using Gaussian secrets) - - // more than 128 bits of security for classical computer attacks - - // optimize runtime by finding a non-power-of-two n - STD128_AP, // Optimized for AP (has higher failure probability for GINX) - - // more than 128 bits of security for classical computer attacks - - // optimize runtime by finding a non-power-of-two n - STD128, // more than 128 bits of security for classical computer attacks - - // optimize runtime by finding a non-power-of-two n - STD192, // more than 192 bits of security for classical computer attacks - - // optimize runtime by finding a non-power-of-two n - STD256, // more than 256 bits of security for classical computer attacks - - // optimize runtime by finding a non-power-of-two n - STD128Q, // more than 128 bits of security for quantum attacks - - // optimize runtime by finding a non-power-of-two n - STD128Q_LMKCDEY, // Optimized for LMKCDEY (using Gaussian secrets) - - // more than 128 bits of security for quantum attacks - - // optimize runtime by finding a non-power-of-two n - STD192Q, // more than 192 bits of security for quantum attacks - - // optimize runtime by finding a non-power-of-two n - STD256Q, // more than 256 bits of security for quantum attacks - - // optimize runtime by finding a non-power-of-two n - STD128_3, // more than 128 bits of security for classical computer attacks - - // optimize runtime by finding a non-power-of-two n for 3 binary inputs - STD128_3_LMKCDEY, // Optimized for LMKCDEY (using Gaussian secrets) - - // more than 128 bits of security for classical computer attacks - - // optimize runtime by finding a non-power-of-two n for 3 binary inputs - STD128Q_3, // more than 128 bits of security for quantum computer attacks - - // optimize runtime by finding a non-power-of-two n for 3 binary inputs - STD128Q_3_LMKCDEY, // Optimized for LMKCDEY (using Gaussian secrets) - - // more than 128 bits of security for quantum computer attacks - - // optimize runtime by finding a non-power-of-two n for 3 binary inputs - STD192Q_3, // more than 192 bits of security for quantum computer attacks - - // optimize runtime by finding a non-power-of-two n for 3 binary inputs - STD256Q_3, // more than 256 bits of security for quantum computer attacks - - // optimize runtime by finding a non-power-of-two n for 3 binary inputs - STD128_4, // more than 128 bits of security for classical computer attacks - - // optimize runtime by finding a non-power-of-two n for 4 binary inputs - STD128_4_LMKCDEY, // Optimized for LMKCDEY (using Gaussian secrets) - - // more than 128 bits of security for classical computer attacks - - // optimize runtime by finding a non-power-of-two n for 4 binary inputs - STD128Q_4, // more than 128 bits of security for quantum computer attacks - - // optimize runtime by finding a non-power-of-two n for 4 binary inputs - STD128Q_4_LMKCDEY, // Optimized for LMKCDEY (using Gaussian secrets) - - // more than 128 bits of security for quantum computer attacks - - // optimize runtime by finding a non-power-of-two n for 4 binary inputs - STD192Q_4, // more than 192 bits of security for quantum computer attacks - - // optimize runtime by finding a non-power-of-two n for 4 binary inputs - STD256Q_4, // more than 256 bits of security for quantum computer attacks - - // optimize runtime by finding a non-power-of-two n for 4 binary inputs - SIGNED_MOD_TEST // special parameter set for confirming the signed modular - // reduction in the accumulator updates works correctly +// NAME, // Description : Approximate Probability of Failure + TOY, // no security : 2^(-360) + MEDIUM, // 108 bits of security for classical and 100 bits for quantum : 2^(-70) + STD128_AP, // more than 128 bits of security for classical computer attacks : 2^(-50) + STD128, // more than 128 bits of security for classical computer attacks : 2^(-40) + STD128_3, // STD128 for 3 binary inputs : 2^(-50) + STD128_4, // STD128 for 4 binary inputs : 2^(-50) + STD128Q, // more than 128 bits of security for quantum attacks : 2^(-40) + STD128Q_3, // STD128Q for 3 binary inputs : 2^(-50) + STD128Q_4, // STD128Q for 4 binary inputs : 2^(-50) + STD192, // more than 192 bits of security for classical computer attacks : 2^(-40) + STD192_3, // STD192 for 3 binary inputs : 2^(-60) + STD192_4, // STD192 for 4 binary inputs : 2^(-70) + STD192Q, // more than 192 bits of security for quantum attacks : 2^(-80) + STD192Q_3, // STD192Q for 3 binary inputs : 2^(-80) + STD192Q_4, // STD192Q for 4 binary inputs : 2^(-50) + STD256, // more than 256 bits of security for classical computer attacks : 2^(-80) + STD256_3, // STD256 for 3 binary inputs : 2^(-70) + STD256_4, // STD256 for 4 binary inputs : 2^(-50) + STD256Q, // more than 256 bits of security for quantum attacks : 2^(-60) + STD256Q_3, // STD256Q for 3 binary inputs : 2^(-80) + STD256Q_4, // STD256Q for 4 binary inputs : 2^(-50) + STD128_LMKCDEY, // STD128 optimized for LMKCDEY (using Gaussian secrets) : 2^(-55) + STD128_3_LMKCDEY, // STD128_LMKCDEY for 3 binary inputs : 2^(-40) + STD128_4_LMKCDEY, // STD128_LMKCDEY for 4 binary inputs : 2^(-60) + STD128Q_LMKCDEY, // STD128Q optimized for LMKCDEY (using Gaussian secrets) : 2^(-50) + STD128Q_3_LMKCDEY, // STD128Q_LMKCDEY for 3 binary inputs : 2^(-45) + STD128Q_4_LMKCDEY, // STD128Q_LMKCDEY for 4 binary inputs : 2^(-80) + STD192_LMKCDEY, // STD192 optimized for LMKCDEY (using Gaussian secrets) : 2^(-60) + STD192_3_LMKCDEY, // STD192_LMKCDEY for 3 binary inputs : 2^(-60) + STD192_4_LMKCDEY, // STD192_LMKCDEY for 4 binary inputs : 2^(-70) + STD192Q_LMKCDEY, // STD192Q optimized for LMKCDEY (using Gaussian secrets) : 2^(-70) + STD192Q_3_LMKCDEY, // STD192Q_LMKCDEY for 3 binary inputs : 2^(-55) + STD192Q_4_LMKCDEY, // STD192Q_LMKCDEY for 4 binary inputs : 2^(-70) + STD256_LMKCDEY, // STD256 optimized for LMKCDEY (using Gaussian secrets) : 2^(-50) + STD256_3_LMKCDEY, // STD256_LMKCDEY for 3 binary inputs : 2^(-50) + STD256_4_LMKCDEY, // STD256_LMKCDEY for 4 binary inputs : 2^(-60) + STD256Q_LMKCDEY, // STD256Q optimized for LMKCDEY (using Gaussian secrets) : 2^(-60) + STD256Q_3_LMKCDEY, // STD256Q_LMKCDEY for 3 binary inputs : 2^(-50) + STD256Q_4_LMKCDEY, // STD256Q_LMKCDEY for 4 binary inputs : 2^(-45) + LPF_STD128, // STD128 configured with lower probability of failures : 2^(-220) + LPF_STD128Q, // STD128Q configured with lower probability of failures : 2^(-75) + LPF_STD128_LMKCDEY, // LPF_STD128 optimized for LMKCDEY : 2^(-120) + LPF_STD128Q_LMKCDEY, // LPF_STD128Q optimized for LMKCDEY : 2^(-120) + SIGNED_MOD_TEST // special parameter set for confirming the signed modular : 2^(-40) + // reduction in the accumulator updates works correctly }; +// clang-format on std::ostream& operator<<(std::ostream& s, BINFHE_PARAMSET f); /** diff --git a/src/binfhe/include/binfhecontext.h b/src/binfhe/include/binfhecontext.h index b061ea9e5..5e393c114 100644 --- a/src/binfhe/include/binfhecontext.h +++ b/src/binfhe/include/binfhecontext.h @@ -116,7 +116,7 @@ class BinFHEContext : public Serializable { * @param timeOptimization whether to use dynamic bootstrapping technique * @return creates the cryptocontext */ - void GenerateBinFHEContext(BINFHE_PARAMSET set, bool arbFunc, uint32_t logQ = 11, int64_t N = 0, + void GenerateBinFHEContext(BINFHE_PARAMSET set, bool arbFunc, uint32_t logQ = 11, uint32_t N = 0, BINFHE_METHOD method = GINX, bool timeOptimization = false); /** diff --git a/src/binfhe/include/rgsw-cryptoparameters.h b/src/binfhe/include/rgsw-cryptoparameters.h index 1ff4a3620..0b897bea0 100644 --- a/src/binfhe/include/rgsw-cryptoparameters.h +++ b/src/binfhe/include/rgsw-cryptoparameters.h @@ -88,7 +88,7 @@ class RingGSWCryptoParams : public Serializable { m_numAutoKeys(numAutoKeys) { if (!IsPowerOfTwo(baseG)) OPENFHE_THROW("Gadget base should be a power of two."); - if ((method == LMKCDEY) & (numAutoKeys == 0)) + if ((method == LMKCDEY) && (numAutoKeys == 0)) OPENFHE_THROW("numAutoKeys should be greater than 0."); auto logQ{log(m_Q.ConvertToDouble())}; m_digitsG = static_cast(std::ceil(logQ / log(static_cast(m_baseG)))); diff --git a/src/binfhe/lib/binfhe-constants-impl.cpp b/src/binfhe/lib/binfhe-constants-impl.cpp index 377e5e9f8..34de51c62 100644 --- a/src/binfhe/lib/binfhe-constants-impl.cpp +++ b/src/binfhe/lib/binfhe-constants-impl.cpp @@ -43,68 +43,128 @@ std::ostream& operator<<(std::ostream& s, BINFHE_PARAMSET f) { case MEDIUM: s << "MEDIUM"; break; - case STD128_LMKCDEY: - s << "STD128_LMKCDEY"; - break; case STD128_AP: s << "STD128_AP"; break; case STD128: s << "STD128"; break; - case STD192: - s << "STD192"; + case STD128_3: + s << "STD128_3"; break; - case STD256: - s << "STD256"; + case STD128_4: + s << "STD128_4"; break; case STD128Q: s << "STD128Q"; break; - case STD128Q_LMKCDEY: - s << "STD128Q_LMKCDEY"; + case STD128Q_3: + s << "STD128Q_3"; + break; + case STD128Q_4: + s << "STD128Q_4"; + break; + case STD192: + s << "STD192"; + break; + case STD192_3: + s << "STD192_3"; + break; + case STD192_4: + s << "STD192_4"; break; case STD192Q: s << "STD192Q"; break; - case STD256Q: - s << "STD256Q"; + case STD192Q_3: + s << "STD192Q_3"; break; - case STD128_3: - s << "STD128_3"; + case STD192Q_4: + s << "STD192Q_4"; break; - case STD128_3_LMKCDEY: - s << "STD128_3_LMKCDEY"; + case STD256: + s << "STD256"; break; - case STD128Q_3: - s << "STD128Q_3"; + case STD256_3: + s << "STD256_3"; break; - case STD128Q_3_LMKCDEY: - s << "STD128Q_3_LMKCDEY"; + case STD256_4: + s << "STD256_4"; break; - case STD192Q_3: - s << "STD192Q_3"; + case STD256Q: + s << "STD256Q"; break; case STD256Q_3: s << "STD256Q_3"; break; - case STD128_4: - s << "STD128_4"; + case STD256Q_4: + s << "STD256Q_4"; + break; + case STD128_LMKCDEY: + s << "STD128_LMKCDEY"; + break; + case STD128_3_LMKCDEY: + s << "STD128_3_LMKCDEY"; break; case STD128_4_LMKCDEY: s << "STD128_4_LMKCDEY"; break; - case STD128Q_4: - s << "STD128Q_4"; + case STD128Q_LMKCDEY: + s << "STD128Q_LMKCDEY"; + break; + case STD128Q_3_LMKCDEY: + s << "STD128Q_3_LMKCDEY"; break; case STD128Q_4_LMKCDEY: s << "STD128Q_4_LMKCDEY"; break; - case STD192Q_4: - s << "STD192Q_4"; + case STD192_LMKCDEY: + s << "STD192_LMKCDEY"; break; - case STD256Q_4: - s << "STD256Q_4"; + case STD192_3_LMKCDEY: + s << "STD192_3_LMKCDEY"; + break; + case STD192_4_LMKCDEY: + s << "STD192_4_LMKCDEY"; + break; + case STD192Q_LMKCDEY: + s << "STD192Q_LMKCDEY"; + break; + case STD192Q_3_LMKCDEY: + s << "STD192Q_3_LMKCDEY"; + break; + case STD192Q_4_LMKCDEY: + s << "STD192Q_4_LMKCDEY"; + break; + case STD256_LMKCDEY: + s << "STD256_LMKCDEY"; + break; + case STD256_3_LMKCDEY: + s << "STD256_3_LMKCDEY"; + break; + case STD256_4_LMKCDEY: + s << "STD256_4_LMKCDEY"; + break; + case STD256Q_LMKCDEY: + s << "STD256Q_LMKCDEY"; + break; + case STD256Q_3_LMKCDEY: + s << "STD256Q_3_LMKCDEY"; + break; + case STD256Q_4_LMKCDEY: + s << "STD256Q_4_LMKCDEY"; + break; + case LPF_STD128: + s << "LPF_STD128"; + break; + case LPF_STD128Q: + s << "LPF_STD128Q"; + break; + case LPF_STD128_LMKCDEY: + s << "LPF_STD128_LMKCDEY"; + break; + case LPF_STD128Q_LMKCDEY: + s << "LPF_STD128Q_LMKCDEY"; break; case SIGNED_MOD_TEST: s << "SIGNED_MOD_TEST"; diff --git a/src/binfhe/lib/binfhecontext.cpp b/src/binfhe/lib/binfhecontext.cpp index 951b3d023..40624df37 100644 --- a/src/binfhe/lib/binfhecontext.cpp +++ b/src/binfhe/lib/binfhecontext.cpp @@ -37,6 +37,8 @@ #include #include +static constexpr double STD_DEV = 3.19; + namespace lbcrypto { void BinFHEContext::GenerateBinFHEContext(uint32_t n, uint32_t N, const NativeInteger& q, const NativeInteger& Q, @@ -49,25 +51,17 @@ void BinFHEContext::GenerateBinFHEContext(uint32_t n, uint32_t N, const NativeIn m_binfhescheme = std::make_shared(method); } -void BinFHEContext::GenerateBinFHEContext(BINFHE_PARAMSET set, bool arbFunc, uint32_t logQ, int64_t N, +void BinFHEContext::GenerateBinFHEContext(BINFHE_PARAMSET set, bool arbFunc, uint32_t logQ, uint32_t N, BINFHE_METHOD method, bool timeOptimization) { - if (GINX != method) { - std::string errMsg("ERROR: CGGI is the only supported method"); - OPENFHE_THROW(errMsg); - } - if (set != STD128 && set != TOY) { - std::string errMsg("ERROR: STD128 and TOY are the only supported sets"); - OPENFHE_THROW(errMsg); - } + if (method != GINX) + OPENFHE_THROW("CGGI is the only supported method"); + if (set != STD128 && set != TOY) + OPENFHE_THROW("STD128 and TOY are the only supported sets"); + if (logQ > 29) + OPENFHE_THROW("logQ > 29 is not supported"); + if (logQ < 11) + OPENFHE_THROW("logQ < 11 is not supported"); - if (logQ > 29) { - std::string errMsg("ERROR: logQ > 29 is not supported"); - OPENFHE_THROW(errMsg); - } - if (logQ < 11) { - std::string errMsg("ERROR: logQ < 11 is not supported"); - OPENFHE_THROW(errMsg); - } auto logQprime = 54; uint32_t baseG = 0; if (logQ > 25) { @@ -84,188 +78,175 @@ void BinFHEContext::GenerateBinFHEContext(BINFHE_PARAMSET set, bool arbFunc, uin logQprime = 27; } - m_timeOptimization = timeOptimization; - SecurityLevel sl = HEStd_128_classic; // choose minimum ringD satisfying sl and Q - uint32_t ringDim = StdLatticeParm::FindRingDim(HEStd_ternary, sl, logQprime); - if (N >= ringDim) { // if specified some larger N, security is also satisfied - ringDim = N; - } + // if specified some larger N, security is also satisfied + auto minRingDim = StdLatticeParm::FindRingDim(HEStd_ternary, HEStd_128_classic, logQprime); + uint32_t ringDim = N > minRingDim ? N : minRingDim; + // find prime Q for NTT NativeInteger Q = LastPrime(logQprime, 2 * ringDim); + // q = 2*ringDim by default for maximum plaintext space, if needed for arbitrary function evaluation, q = ringDim uint32_t q = arbFunc ? ringDim : 2 * ringDim; - uint64_t qKS = 1 << 30; - qKS <<= 5; + uint64_t qKS = uint64_t(1) << 35; uint32_t n = (set == TOY) ? 32 : 1305; - auto lweparams = std::make_shared(n, ringDim, q, Q, qKS, 3.19, 32); - auto rgswparams = std::make_shared(ringDim, Q, q, baseG, 23, method, 3.19, UNIFORM_TERNARY, + auto lweparams = std::make_shared(n, ringDim, q, Q, qKS, STD_DEV, 32); + auto rgswparams = std::make_shared(ringDim, Q, q, baseG, 23, method, STD_DEV, UNIFORM_TERNARY, ((logQ != 11) && timeOptimization)); - m_params = std::make_shared(lweparams, rgswparams); - m_binfhescheme = std::make_shared(method); - -#if defined(BINFHE_DEBUG) - std::cout << ringDim << " " << Q < < < < " " << n << " " << q << " " << baseG << std::endl; -#endif + m_params = std::make_shared(lweparams, rgswparams); + m_binfhescheme = std::make_shared(method); + m_timeOptimization = timeOptimization; } void BinFHEContext::GenerateBinFHEContext(BINFHE_PARAMSET set, BINFHE_METHOD method) { enum { PRIME = 0 }; // value for modKS if you want to use the intermediate prime for modulus for key switching - constexpr double STD_DEV = 3.19; // clang-format off - const std::unordered_map paramsMap({ - // numberBits|cyclOrder|latticeParam| mod| modKS| stdDev| baseKS| gadgetBase| baseRK| numAutoKeys| keyDist - { TOY, { 27, 1024, 64, 512, PRIME, STD_DEV, 25, 1 << 9, 23, 9, UNIFORM_TERNARY} }, - { MEDIUM, { 28, 2048, 422, 1024, 1 << 14, STD_DEV, 1 << 7, 1 << 10, 32, 10, UNIFORM_TERNARY} }, - { STD128_LMKCDEY, { 28, 2048, 446, 1024, 1 << 13, STD_DEV, 1 << 5, 1 << 10, 32, 10, GAUSSIAN } }, - { STD128_AP, { 27, 2048, 503, 1024, 1 << 14, STD_DEV, 1 << 5, 1 << 9, 32, 10, UNIFORM_TERNARY} }, - { STD128, { 27, 2048, 503, 1024, 1 << 14, STD_DEV, 1 << 5, 1 << 9, 32, 10, UNIFORM_TERNARY} }, - { STD192, { 37, 4096, 805, 1024, 1 << 15, STD_DEV, 32, 1 << 13, 32, 10, UNIFORM_TERNARY} }, - { STD256, { 29, 4096, 990, 2048, 1 << 14, STD_DEV, 1 << 7, 1 << 8, 46, 10, UNIFORM_TERNARY} }, - { STD128Q, { 25, 2048, 534, 1024, 1 << 14, STD_DEV, 32, 1 << 7, 32, 10, UNIFORM_TERNARY} }, - { STD128Q_LMKCDEY, { 27, 2048, 448, 1024, 1 << 13, STD_DEV, 32, 1 << 9, 32, 10, GAUSSIAN } }, - { STD192Q, { 35, 4096, 875, 1024, 1 << 15, STD_DEV, 32, 1 << 12, 32, 10, UNIFORM_TERNARY} }, - { STD256Q, { 27, 4096, 1225, 1024, 1 << 16, STD_DEV, 16, 1 << 7, 32, 10, UNIFORM_TERNARY} }, - { STD128_3, { 27, 2048, 541, 1024, 1 << 15, STD_DEV, 32, 1 << 7, 32, 10, UNIFORM_TERNARY} }, - { STD128_3_LMKCDEY, { 28, 2048, 485, 1024, 1 << 15, STD_DEV, 32, 1 << 10, 32, 10, GAUSSIAN } }, - { STD128Q_3, { 50, 4096, 575, 2048, 1 << 15, STD_DEV, 32, 1 << 25, 32, 10, UNIFORM_TERNARY} }, - { STD128Q_3_LMKCDEY, { 27, 2048, 524, 1024, 1 << 15, STD_DEV, 32, 1 << 9, 32, 10, GAUSSIAN } }, - { STD192Q_3, { 34, 4096, 922, 2048, 1 << 16, STD_DEV, 16, 1 << 12, 32, 10, UNIFORM_TERNARY} }, - { STD256Q_3, { 27, 4096, 1400, 4096, 1 << 16, STD_DEV, 21, 1 << 6, 32, 10, UNIFORM_TERNARY} }, - { STD128_4, { 27, 2048, 541, 2048, 1 << 15, STD_DEV, 32, 1 << 7, 32, 10, UNIFORM_TERNARY} }, - { STD128_4_LMKCDEY, { 28, 2048, 522, 2048, 1 << 15, STD_DEV, 32, 1 << 10, 32, 10, GAUSSIAN } }, - { STD128Q_4, { 50, 4096, 647, 2048, 1 << 16, STD_DEV, 16, 1 << 25, 32, 10, UNIFORM_TERNARY} }, - { STD128Q_4_LMKCDEY, { 27, 2048, 524, 2048, 1 << 15, STD_DEV, 32, 1 << 7, 32, 10, GAUSSIAN } }, - { STD192Q_4, { 34, 4096, 980, 2048, 1 << 17, STD_DEV, 16, 1 << 12, 32, 10, UNIFORM_TERNARY} }, - { STD256Q_4, { 27, 4096, 1625, 4096, 1 << 21, STD_DEV, 16, 1 << 6, 32, 10, UNIFORM_TERNARY} }, - { SIGNED_MOD_TEST, { 28, 2048, 512, 1024, PRIME, STD_DEV, 25, 1 << 7, 23, 10, UNIFORM_TERNARY} }, - }); + static const std::unordered_map paramsMap{ + // { BINFHE_PARAMSET { bits, cycOrder, latParam, modq, modKS, stdDev, Bks, Bg, Brk, autoKeys, keyDist } }, + { TOY, { 27, 1024, 64, 512, PRIME, STD_DEV, 25, 512, 23, 9, UNIFORM_TERNARY } }, + { MEDIUM, { 28, 2048, 422, 1024, 16384, STD_DEV, 128, 1024, 32, 10, UNIFORM_TERNARY } }, + { STD128_AP, { 27, 2048, 503, 1024, 16384, STD_DEV, 32, 512, 32, 10, UNIFORM_TERNARY } }, + { STD128, { 27, 2048, 503, 1024, 16384, STD_DEV, 32, 512, 32, 10, UNIFORM_TERNARY } }, + { STD128_3, { 27, 2048, 595, 1024, 65536, STD_DEV, 64, 128, 32, 10, UNIFORM_TERNARY } }, + { STD128_4, { 27, 2048, 595, 2048, 65536, STD_DEV, 64, 128, 64, 10, UNIFORM_TERNARY } }, + { STD128Q, { 25, 2048, 534, 1024, 16384, STD_DEV, 32, 128, 32, 10, UNIFORM_TERNARY } }, + { STD128Q_3, { 50, 4096, 600, 2048, 32768, STD_DEV, 32, 33554432, 64, 10, UNIFORM_TERNARY } }, + { STD128Q_4, { 50, 4096, 641, 2048, 65536, STD_DEV, 64, 33554432, 64, 10, UNIFORM_TERNARY } }, + { STD192, { 37, 4096, 790, 2048, 16384, STD_DEV, 32, 524288, 64, 10, UNIFORM_TERNARY } }, + { STD192_3, { 37, 4096, 875, 4096, 65536, STD_DEV, 64, 524288, 64, 10, UNIFORM_TERNARY } }, + { STD192_4, { 37, 4096, 875, 4096, 65536, STD_DEV, 64, 8192, 64, 10, UNIFORM_TERNARY } }, + { STD192Q, { 35, 4096, 875, 1024, 32768, STD_DEV, 32, 4096, 32, 10, UNIFORM_TERNARY } }, + { STD192Q_3, { 34, 4096, 922, 2048, 65536, STD_DEV, 16, 4096, 64, 10, UNIFORM_TERNARY } }, + { STD192Q_4, { 34, 4096, 980, 2048, 131072, STD_DEV, 16, 4096, 64, 10, UNIFORM_TERNARY } }, + { STD256, { 29, 4096, 1076, 2048, 32768, STD_DEV, 32, 1024, 64, 10, UNIFORM_TERNARY } }, + { STD256_3, { 29, 4096, 1145, 2048, 65536, STD_DEV, 64, 256, 64, 10, UNIFORM_TERNARY } }, + { STD256_4, { 29, 4096, 1145, 4096, 65536, STD_DEV, 64, 256, 64, 10, UNIFORM_TERNARY } }, + { STD256Q, { 27, 4096, 1225, 1024, 65536, STD_DEV, 16, 128, 32, 10, UNIFORM_TERNARY } }, + { STD256Q_3, { 27, 4096, 1400, 4096, 65536, STD_DEV, 21, 64, 64, 10, UNIFORM_TERNARY } }, + { STD256Q_4, { 27, 4096, 1625, 4096, 2097152, STD_DEV, 16, 64, 64, 10, UNIFORM_TERNARY } }, + { STD128_LMKCDEY, { 28, 2048, 447, 2048, 16384, STD_DEV, 32, 1024, 64, 10, GAUSSIAN } }, + { STD128_3_LMKCDEY, { 27, 2048, 556, 2048, 32768, STD_DEV, 32, 512, 64, 10, UNIFORM_TERNARY } }, + { STD128_4_LMKCDEY, { 27, 2048, 595, 2048, 65536, STD_DEV, 64, 128, 64, 10, UNIFORM_TERNARY } }, + { STD128Q_LMKCDEY, { 27, 2048, 483, 2048, 16384, STD_DEV, 32, 512, 64, 10, GAUSSIAN } }, + { STD128Q_3_LMKCDEY, { 25, 2048, 643, 2048, 65536, STD_DEV, 64, 128, 64, 10, UNIFORM_TERNARY } }, + { STD128Q_4_LMKCDEY, { 50, 4096, 641, 4096, 65536, STD_DEV, 64, 33554432, 64, 10, UNIFORM_TERNARY } }, + { STD192_LMKCDEY, { 39, 4096, 716, 2048, 32768, STD_DEV, 32, 1048576, 64, 10, GAUSSIAN } }, + { STD192_3_LMKCDEY, { 39, 4096, 771, 4096, 65536, STD_DEV, 64, 1048576, 64, 10, GAUSSIAN } }, + { STD192_4_LMKCDEY, { 37, 4096, 875, 4096, 65536, STD_DEV, 64, 8192, 64, 10, UNIFORM_TERNARY } }, + { STD192Q_LMKCDEY, { 36, 4096, 776, 4096, 32768, STD_DEV, 32, 262144, 64, 10, GAUSSIAN } }, + { STD192Q_3_LMKCDEY, { 36, 4096, 834, 4096, 65536, STD_DEV, 64, 4096, 64, 10, GAUSSIAN } }, + { STD192Q_4_LMKCDEY, { 34, 4096, 949, 4096, 65536, STD_DEV, 64, 4096, 64, 10, UNIFORM_TERNARY } }, + { STD256_LMKCDEY, { 30, 4096, 939, 2048, 32768, STD_DEV, 32, 1024, 64, 10, GAUSSIAN } }, + { STD256_3_LMKCDEY, { 29, 4096, 1076, 4096, 32768, STD_DEV, 32, 256, 64, 10, UNIFORM_TERNARY } }, + { STD256_4_LMKCDEY, { 29, 4096, 1145, 4096, 65536, STD_DEV, 64, 256, 64, 10, UNIFORM_TERNARY } }, + { STD256Q_LMKCDEY, { 28, 4096, 1019, 4096, 32768, STD_DEV, 32, 1024, 64, 10, GAUSSIAN } }, + { STD256Q_3_LMKCDEY, { 26, 4096, 1242, 4096, 65536, STD_DEV, 64, 128, 64, 10, UNIFORM_TERNARY } }, + { STD256Q_4_LMKCDEY, { 26, 4096, 1320, 4096, 131072, STD_DEV, 64, 64, 64, 10, UNIFORM_TERNARY } }, + { LPF_STD128, { 27, 2048, 556, 2048, 32768, STD_DEV, 32, 128, 64, 10, UNIFORM_TERNARY } }, + { LPF_STD128Q, { 25, 2048, 645, 2048, 65536, STD_DEV, 64, 128, 64, 10, UNIFORM_TERNARY } }, + { LPF_STD128_LMKCDEY, { 27, 2048, 556, 2048, 32768, STD_DEV, 32, 512, 64, 10, UNIFORM_TERNARY } }, + { LPF_STD128Q_LMKCDEY, { 25, 2048, 600, 2048, 32768, STD_DEV, 32, 128, 64, 10, UNIFORM_TERNARY } }, + { SIGNED_MOD_TEST, { 28, 2048, 512, 1024, PRIME, STD_DEV, 25, 128, 23, 10, UNIFORM_TERNARY } }, + }; // clang-format on auto search = paramsMap.find(set); - if (paramsMap.end() == search) { - std::string errMsg("ERROR: Unknown parameter set [" + std::to_string(set) + "] for FHEW."); - OPENFHE_THROW(errMsg); - } - - BinFHEContextParams params = search->second; - // intermediate prime - NativeInteger Q(LastPrime(params.numberBits, params.cyclOrder)); - - usint ringDim = params.cyclOrder / 2; - auto lweparams = (PRIME == params.modKS) ? - std::make_shared(params.latticeParam, ringDim, params.mod, Q, Q, - params.stdDev, params.baseKS, params.keyDist) : - std::make_shared(params.latticeParam, ringDim, params.mod, Q, params.modKS, - params.stdDev, params.baseKS, params.keyDist); + if (paramsMap.end() == search) + OPENFHE_THROW("unknown parameter set"); + auto& params = search->second; + + auto Q = LastPrime(params.numberBits, params.cyclOrder); + auto ringDim = params.cyclOrder >> 1; + auto lweparams = std::make_shared(params.latticeParam, ringDim, params.mod, Q, + (params.modKS == PRIME ? Q : params.modKS), params.stdDev, + params.baseKS, params.keyDist); auto rgswparams = std::make_shared(ringDim, Q, params.mod, params.gadgetBase, params.baseRK, method, params.stdDev, params.keyDist, false, params.numAutoKeys); + m_params = std::make_shared(lweparams, rgswparams); - m_params = std::make_shared(lweparams, rgswparams); + // TODO: add check that (method == LMKCDEY) for LMKCDEY-optimized BINFHE_PARAMSETs m_binfhescheme = std::make_shared(method); } void BinFHEContext::GenerateBinFHEContext(const BinFHEContextParams& params, BINFHE_METHOD method) { enum { PRIME = 0 }; // value for modKS if you want to use the intermediate prime for modulus for key switching - // intermediate prime - NativeInteger Q(LastPrime(params.numberBits, params.cyclOrder)); - - usint ringDim = params.cyclOrder / 2; - - auto lweparams = (PRIME == params.modKS) ? - std::make_shared(params.latticeParam, ringDim, params.mod, Q, Q, - params.stdDev, params.baseKS, params.keyDist) : - std::make_shared(params.latticeParam, ringDim, params.mod, Q, params.modKS, - params.stdDev, params.baseKS, params.keyDist); + auto Q = LastPrime(params.numberBits, params.cyclOrder); + auto ringDim = params.cyclOrder >> 1; + auto lweparams = std::make_shared(params.latticeParam, ringDim, params.mod, Q, + (params.modKS == PRIME ? Q : params.modKS), params.stdDev, + params.baseKS, params.keyDist); auto rgswparams = std::make_shared(ringDim, Q, params.mod, params.gadgetBase, params.baseRK, method, params.stdDev, params.keyDist, false, params.numAutoKeys); - m_params = std::make_shared(lweparams, rgswparams); m_binfhescheme = std::make_shared(method); } LWEPrivateKey BinFHEContext::KeyGen() const { - auto& LWEParams = m_params->GetLWEParams(); + auto&& LWEParams = m_params->GetLWEParams(); if (LWEParams->GetKeyDist() == GAUSSIAN) return m_LWEscheme->KeyGenGaussian(LWEParams->Getn(), LWEParams->GetqKS()); return m_LWEscheme->KeyGen(LWEParams->Getn(), LWEParams->GetqKS()); } LWEPrivateKey BinFHEContext::KeyGenN() const { - auto& LWEParams = m_params->GetLWEParams(); + auto&& LWEParams = m_params->GetLWEParams(); if (LWEParams->GetKeyDist() == GAUSSIAN) return m_LWEscheme->KeyGenGaussian(LWEParams->GetN(), LWEParams->GetQ()); return m_LWEscheme->KeyGen(LWEParams->GetN(), LWEParams->GetQ()); } LWEKeyPair BinFHEContext::KeyGenPair() const { - auto&& LWEParams = m_params->GetLWEParams(); - return m_LWEscheme->KeyGenPair(LWEParams); + return m_LWEscheme->KeyGenPair(m_params->GetLWEParams()); } LWEPublicKey BinFHEContext::PubKeyGen(ConstLWEPrivateKey& sk) const { - auto&& LWEParams = m_params->GetLWEParams(); - return m_LWEscheme->PubKeyGen(LWEParams, sk); + return m_LWEscheme->PubKeyGen(m_params->GetLWEParams(), sk); } LWECiphertext BinFHEContext::Encrypt(ConstLWEPrivateKey& sk, LWEPlaintext m, BINFHE_OUTPUT output, LWEPlaintextModulus p, const NativeInteger& mod) const { - const auto& LWEParams = m_params->GetLWEParams(); + auto&& LWEParams = m_params->GetLWEParams(); - LWECiphertext ct = (mod == 0) ? m_LWEscheme->Encrypt(LWEParams, sk, m, p, LWEParams->Getq()) : - m_LWEscheme->Encrypt(LWEParams, sk, m, p, mod); + auto ct = m_LWEscheme->Encrypt(LWEParams, sk, m, p, (mod == 0 ? LWEParams->Getq() : mod)); // BINFHE_OUTPUT is kept as it is for backward compatibility but // this logic is obsolete now and commented out // if ((output != FRESH) && (p == 4)) { // ct = m_binfhescheme->Bootstrap(m_params, m_BTKey, ct); //} - return ct; } LWECiphertext BinFHEContext::Encrypt(ConstLWEPublicKey& pk, LWEPlaintext m, BINFHE_OUTPUT output, LWEPlaintextModulus p, const NativeInteger& mod) const { - const auto& LWEParams = m_params->GetLWEParams(); + auto&& LWEParams = m_params->GetLWEParams(); - LWECiphertext ct = (mod == 0) ? m_LWEscheme->EncryptN(LWEParams, pk, m, p, LWEParams->GetQ()) : - m_LWEscheme->EncryptN(LWEParams, pk, m, p, mod); + auto ct = m_LWEscheme->EncryptN(LWEParams, pk, m, p, (mod == 0 ? LWEParams->GetQ() : mod)); // Switch from ct of modulus Q and dimension N to smaller q and n // This is done by default while calling Encrypt but the output could // be set to LARGE_DIM to skip this switching - if (output == SMALL_DIM) { - LWECiphertext ct1 = SwitchCTtoqn(m_BTKey.KSkey, ct); - return ct1; - } + if (output == SMALL_DIM) + return SwitchCTtoqn(m_BTKey.KSkey, ct); return ct; } LWECiphertext BinFHEContext::SwitchCTtoqn(ConstLWESwitchingKey& ksk, ConstLWECiphertext& ct) const { - const auto& LWEParams = m_params->GetLWEParams(); - auto Q = LWEParams->GetQ(); - auto N = LWEParams->GetN(); - - if ((ct->GetLength() != N) && (ct->GetModulus() != Q)) { - std::string errMsg("ERROR: Ciphertext dimension and modulus are not large N and Q"); - OPENFHE_THROW(errMsg); - } - - LWECiphertext ct1 = m_LWEscheme->SwitchCTtoqn(LWEParams, ksk, ct); - - return ct1; + auto&& LWEParams = m_params->GetLWEParams(); + if ((ct->GetLength() != LWEParams->GetN()) && (ct->GetModulus() != LWEParams->GetQ())) + OPENFHE_THROW("ciphertext dimension and modulus are not large N and Q"); + return m_LWEscheme->SwitchCTtoqn(LWEParams, ksk, ct); } void BinFHEContext::Decrypt(ConstLWEPrivateKey& sk, ConstLWECiphertext& ct, LWEPlaintext* result, LWEPlaintextModulus p) const { - auto&& LWEParams = m_params->GetLWEParams(); - m_LWEscheme->Decrypt(LWEParams, sk, ct, result, p); + m_LWEscheme->Decrypt(m_params->GetLWEParams(), sk, ct, result, p); } LWESwitchingKey BinFHEContext::KeySwitchGen(ConstLWEPrivateKey& sk, ConstLWEPrivateKey& skN) const { @@ -273,16 +254,14 @@ LWESwitchingKey BinFHEContext::KeySwitchGen(ConstLWEPrivateKey& sk, ConstLWEPriv } void BinFHEContext::BTKeyGen(ConstLWEPrivateKey& sk, KEYGEN_MODE keygenMode) { - auto& RGSWParams = m_params->GetRingGSWParams(); + auto&& RGSWParams = m_params->GetRingGSWParams(); auto temp = RGSWParams->GetBaseG(); if (m_timeOptimization) { - auto gpowermap = RGSWParams->GetGPowerMap(); - for (std::map>::iterator it = gpowermap.begin(); it != gpowermap.end(); - ++it) { - RGSWParams->Change_BaseG(it->first); - m_BTKey_map[it->first] = m_binfhescheme->KeyGen(m_params, sk, keygenMode); + for (auto&& [k, v] : RGSWParams->GetGPowerMap()) { + RGSWParams->Change_BaseG(k); + m_BTKey_map[k] = m_binfhescheme->KeyGen(m_params, sk, keygenMode); } RGSWParams->Change_BaseG(temp); } @@ -332,8 +311,8 @@ LWECiphertext BinFHEContext::EvalFloor(ConstLWECiphertext& ct, uint32_t roundbit } LWECiphertext BinFHEContext::EvalSign(ConstLWECiphertext& ct, bool schemeSwitch) { - const auto& params = std::make_shared(*m_params); - return m_binfhescheme->EvalSign(params, m_BTKey_map, ct, GetBeta(), schemeSwitch); + return m_binfhescheme->EvalSign(std::make_shared(*m_params), m_BTKey_map, ct, GetBeta(), + schemeSwitch); } std::vector BinFHEContext::EvalDecomp(ConstLWECiphertext& ct) { @@ -342,25 +321,18 @@ std::vector BinFHEContext::EvalDecomp(ConstLWECiphertext& ct) { std::vector BinFHEContext::GenerateLUTviaFunction(NativeInteger (*f)(NativeInteger m, NativeInteger p), NativeInteger p) { - if (ceil(log2(p.ConvertToInt())) != floor(log2(p.ConvertToInt()))) { - std::string errMsg("ERROR: Only support plaintext space to be power-of-two."); - OPENFHE_THROW(errMsg); - } + if (!IsPowerOfTwo(p.ConvertToInt())) + OPENFHE_THROW("plaintext p not power of two"); - NativeInteger q = GetParams()->GetLWEParams()->Getq(); - NativeInteger interval = q / p; - NativeInteger outerval = interval; - usint vecSize = q.ConvertToInt(); - std::vector vec(vecSize); - for (size_t i = 0; i < vecSize; ++i) { - auto temp = f(NativeInteger(i) / interval, p); - if (temp >= p) { - std::string errMsg("ERROR: input function should output in Z_{p_output}."); - OPENFHE_THROW(errMsg); - } - vec[i] = temp * outerval; - } + NativeInteger q{GetParams()->GetLWEParams()->Getq()}; + NativeInteger x{0}; + std::vector vec(q.ConvertToInt(), q / p); + for (size_t i = 0; i < vec.size(); ++i, x += p) { + vec[i] *= f(x / q, p); // x/q = (i*p)/q = i/(q/p) + if (vec[i] >= q) // (f(x/q, p) >= p) --> (f(x/q, p)*(q/p) >= q) + OPENFHE_THROW("input function should output in Z_{p_output}"); + } return vec; } diff --git a/src/core/include/lattice/hal/dcrtpoly-interface.h b/src/core/include/lattice/hal/dcrtpoly-interface.h index 733ab9710..77c3e483b 100644 --- a/src/core/include/lattice/hal/dcrtpoly-interface.h +++ b/src/core/include/lattice/hal/dcrtpoly-interface.h @@ -233,14 +233,6 @@ class DCRTPolyInterface : public ILElement { return this->GetDerived().GetParams()->GetModulus(); } - /** - * @brief returns the element's original modulus, derived from Poly - * @return returns the modulus of the element. - */ - const BigIntType& GetOriginalModulus() const { - return this->GetDerived().GetParams()->GetOriginalModulus(); - } - /** * @brief returns the element's root of unity. * @return the element's root of unity. diff --git a/src/core/include/lattice/hal/default/dcrtpoly-impl.h b/src/core/include/lattice/hal/default/dcrtpoly-impl.h index 8faf94f6e..3d00b236d 100644 --- a/src/core/include/lattice/hal/default/dcrtpoly-impl.h +++ b/src/core/include/lattice/hal/default/dcrtpoly-impl.h @@ -60,7 +60,6 @@ template DCRTPolyImpl::DCRTPolyImpl(const PolyLargeType& rhs, const std::shared_ptr& params) noexcept : DCRTPolyImpl::DCRTPolyImpl(params, rhs.GetFormat(), true) { - m_params->SetOriginalModulus(rhs.GetModulus()); size_t size{m_vectors.size()}; uint32_t rdim{rhs.GetLength()}; for (size_t i{0}; i < size; ++i) { @@ -73,7 +72,6 @@ DCRTPolyImpl::DCRTPolyImpl(const PolyLargeType& rhs, template DCRTPolyImpl& DCRTPolyImpl::operator=(const PolyLargeType& rhs) noexcept { - m_params->SetOriginalModulus(rhs.GetModulus()); m_vectors.clear(); m_vectors.reserve(m_params->GetParams().size()); uint32_t rdim{rhs.GetLength()}; @@ -668,7 +666,6 @@ void DCRTPolyImpl::SetValuesModSwitch(const DCRTPolyImpl& element, cons .Mod(modulus); } m_vectors[0].SetValues(std::move(tmp), Format::COEFFICIENT); - m_params->SetOriginalModulus(modulus); } template diff --git a/src/core/include/lattice/hal/default/ildcrtparams.h b/src/core/include/lattice/hal/default/ildcrtparams.h index e8771b05f..f85157476 100644 --- a/src/core/include/lattice/hal/default/ildcrtparams.h +++ b/src/core/include/lattice/hal/default/ildcrtparams.h @@ -73,7 +73,7 @@ class ILDCRTParams final : public ElemParams { using ILNativeParams = ILParamsImpl; ILDCRTParams(uint32_t corder, const IntType& modulus, const IntType& rootOfUnity = IntType(0)) - : ElemParams(corder, modulus), m_originalModulus(modulus) { + : ElemParams(corder, modulus) { // NOTE params generation uses this constructor to make an empty params that // it will later populate during the gen process. For that special case... // we don't populate, and we just return @@ -146,8 +146,8 @@ class ILDCRTParams final : public ElemParams { ILDCRTParams(uint32_t corder, const std::vector& moduli, const std::vector& rootsOfUnity, const std::vector& moduliBig, - const std::vector& rootsOfUnityBig, const IntType& inputOriginalModulus = IntType(0)) - : ElemParams(corder, 0), m_originalModulus(inputOriginalModulus) { + const std::vector& rootsOfUnityBig) + : ElemParams(corder, 0) { size_t limbs{moduli.size()}; if (limbs != rootsOfUnity.size() || limbs != moduliBig.size() || limbs != rootsOfUnityBig.size()) OPENFHE_THROW("sizes of moduli and roots of unity do not match 2"); @@ -170,9 +170,7 @@ class ILDCRTParams final : public ElemParams { * @param corder the order of the ciphertext * @param &moduli is the tower of moduli */ - ILDCRTParams(uint32_t corder, const std::vector& moduli, - const IntType& inputOriginalModulus = IntType(0)) - : ElemParams(corder, 0), m_originalModulus(inputOriginalModulus) { + ILDCRTParams(uint32_t corder, const std::vector& moduli) : ElemParams(corder, 0) { size_t limbs{moduli.size()}; m_params.reserve(limbs); IntType compositeModulus(1); @@ -191,19 +189,15 @@ class ILDCRTParams final : public ElemParams { * @param params the componet parameters. * @return */ - ILDCRTParams(uint32_t corder, const std::vector>& params, - const IntType& inputOriginalModulus = IntType(0)) - : ElemParams(corder, 0), m_params(params), m_originalModulus(inputOriginalModulus) { + ILDCRTParams(uint32_t corder, const std::vector>& params) + : ElemParams(corder, 0), m_params(params) { RecalculateModulus(); } - ILDCRTParams(const ILDCRTParams& rhs) - : ElemParams(rhs), m_params(rhs.m_params), m_originalModulus(rhs.m_originalModulus) {} + ILDCRTParams(const ILDCRTParams& rhs) : ElemParams(rhs), m_params(rhs.m_params) {} ILDCRTParams(ILDCRTParams&& rhs) noexcept - : ElemParams(rhs), - m_params(std::move(rhs.m_params)), - m_originalModulus(std::move(rhs.m_originalModulus)) {} + : ElemParams(std::move(rhs)), m_params(std::move(rhs.m_params)) {} /** * Assignment Operator. @@ -213,15 +207,13 @@ class ILDCRTParams final : public ElemParams { */ ILDCRTParams& operator=(const ILDCRTParams& rhs) { ElemParams::operator=(rhs); - m_params = rhs.m_params; - m_originalModulus = rhs.m_originalModulus; + m_params = rhs.m_params; return *this; } ILDCRTParams& operator=(ILDCRTParams&& rhs) noexcept { - ElemParams::operator=(rhs); - m_params = std::move(rhs.m_params); - m_originalModulus = std::move(rhs.m_originalModulus); + ElemParams::operator=(std::move(rhs)); + m_params = std::move(rhs.m_params); return *this; } @@ -242,28 +234,12 @@ class ILDCRTParams final : public ElemParams { * @return A vector of the component polynomial parameters. */ std::vector> GetParamPartition(uint32_t start, uint32_t end) const { - if (end < start || end > m_params.size()) + if (end < start || end >= m_params.size()) OPENFHE_THROW("Incorrect parameters for GetParamPartition - (start: " + std::to_string(start) + ", end:" + std::to_string(end) + ")"); return std::vector>(m_params.begin() + start, m_params.begin() + end + 1); } - /** - * @brief Simple getter method for the original modulus, not the ciphertex - * modulus. - * @return The original modulus, not the big ciphertext modulus. - */ - const IntType& GetOriginalModulus() const { - return m_originalModulus; - } - /** - * @brief Simple setter method for the original modulus, not the ciphertex - * modulus. - * @return void - */ - void SetOriginalModulus(const IntType& inputOriginalModulus) { - m_originalModulus = inputOriginalModulus; - } /** * @brief Getter method for the component parameters of a specific index. * @param i the index of the parameters to return. Note this this call is @@ -321,7 +297,7 @@ class ILDCRTParams final : public ElemParams { if (*m_params[i] != *dcrtParams->m_params[i]) return false; } - return (m_originalModulus == dcrtParams->GetOriginalModulus()); + return true; } /** @@ -350,7 +326,6 @@ class ILDCRTParams final : public ElemParams { void save(Archive& ar, std::uint32_t const version) const { ar(::cereal::base_class>(this)); ar(::cereal::make_nvp("p", m_params)); - ar(::cereal::make_nvp("m", m_originalModulus)); } template @@ -361,7 +336,6 @@ class ILDCRTParams final : public ElemParams { } ar(::cereal::base_class>(this)); ar(::cereal::make_nvp("p", m_params)); - ar(::cereal::make_nvp("m", m_originalModulus)); } std::string SerializedObjectName() const override { @@ -378,18 +352,11 @@ class ILDCRTParams final : public ElemParams { out << std::endl << " m_params:" << std::endl; for (size_t i = 0; i < m_params.size(); ++i) out << " " << i << ": " << *m_params[i]; - return out << " m_originalModulus: " << m_originalModulus << std::endl; + return out << std::endl; } // array of smaller ILParams std::vector> m_params; - - // original modulus when being constructed from a Poly or when - // ctor is passed that parameter - // note orignalModulus will be <= composite modules - // i.e. \Prod_i=0^k-1 m_params[i]->GetModulus() - // note not using ElemParams::ciphertextModulus due to object stripping - IntType m_originalModulus; }; } // namespace lbcrypto diff --git a/src/core/include/math/nbtheory-impl.h b/src/core/include/math/nbtheory-impl.h index 3efdb23a0..86d52fbef 100644 --- a/src/core/include/math/nbtheory-impl.h +++ b/src/core/include/math/nbtheory-impl.h @@ -326,7 +326,7 @@ void PrimeFactorize(IntType n, std::set& primeFactors) { } template -IntType FirstPrime(uint32_t nBits, uint32_t m) { +IntType FirstPrime(uint32_t nBits, uint64_t m) { if constexpr (std::is_same_v) { if (nBits > MAX_MODULUS_SIZE) OPENFHE_THROW(std::string(__func__) + ": Requested bit length " + std::to_string(nBits) + @@ -347,7 +347,7 @@ IntType FirstPrime(uint32_t nBits, uint32_t m) { } template -IntType LastPrime(uint32_t nBits, uint32_t m) { +IntType LastPrime(uint32_t nBits, uint64_t m) { if constexpr (std::is_same_v) { if (nBits > MAX_MODULUS_SIZE) OPENFHE_THROW(std::string(__func__) + ": Requested bit length " + std::to_string(nBits) + @@ -373,7 +373,7 @@ IntType LastPrime(uint32_t nBits, uint32_t m) { } template -IntType NextPrime(const IntType& q, uint32_t m) { +IntType NextPrime(const IntType& q, uint64_t m) { IntType M(m), qNew(q + M); while (!MillerRabinPrimalityTest(qNew)) { if ((qNew += M) < q) @@ -383,7 +383,7 @@ IntType NextPrime(const IntType& q, uint32_t m) { } template -IntType PreviousPrime(const IntType& q, uint32_t m) { +IntType PreviousPrime(const IntType& q, uint64_t m) { IntType M(m), qNew(q - M); while (!MillerRabinPrimalityTest(qNew)) { if ((qNew -= M) > q) diff --git a/src/core/include/math/nbtheory.h b/src/core/include/math/nbtheory.h index 36b0f22a3..2614a5055 100644 --- a/src/core/include/math/nbtheory.h +++ b/src/core/include/math/nbtheory.h @@ -278,7 +278,7 @@ void PrimeFactorize(IntType n, std::set& primeFactors); * @return the first prime modulus. */ template -IntType FirstPrime(uint32_t nBits, uint32_t m); +IntType FirstPrime(uint32_t nBits, uint64_t m); /** * Finds the max prime q that satisfies q = 1 mod m with at most nBits bits. @@ -289,7 +289,7 @@ IntType FirstPrime(uint32_t nBits, uint32_t m); * @return the last prime modulus */ template -IntType LastPrime(uint32_t nBits, uint32_t m); +IntType LastPrime(uint32_t nBits, uint64_t m); /** * Finds the next prime that satisfies q = 1 mod m @@ -301,7 +301,7 @@ IntType LastPrime(uint32_t nBits, uint32_t m); * @return the next prime modulus. */ template -IntType NextPrime(const IntType& q, uint32_t m); +IntType NextPrime(const IntType& q, uint64_t m); /** * Finds the previous prime that satisfies q = 1 mod m @@ -313,7 +313,7 @@ IntType NextPrime(const IntType& q, uint32_t m); * @return the previous prime modulus. */ template -IntType PreviousPrime(const IntType& q, uint32_t m); +IntType PreviousPrime(const IntType& q, uint64_t m); /** * Multiplicative inverse for primitive unsigned integer data types diff --git a/src/core/include/utils/blockAllocator/blockAllocator.h b/src/core/include/utils/blockAllocator/blockAllocator.h index ca1e41489..71e1240d9 100644 --- a/src/core/include/utils/blockAllocator/blockAllocator.h +++ b/src/core/include/utils/blockAllocator/blockAllocator.h @@ -35,34 +35,30 @@ #ifndef __ALLOCATOR_H #define __ALLOCATOR_H -#include #include -#include "utils/inttypes.h" - /// See /// http://www.codeproject.com/Articles/1083210/An-efficient-Cplusplus-fixed-block-memory-allocato class Allocator { public: + enum AllocatorMode { HEAP_BLOCKS, HEAP_POOL, STATIC_POOL }; + /// Constructor /// @param[in] size - size of the fixed blocks /// @param[in] objects - maximum number of object. If 0, new blocks are /// created off the heap as necessary. - /// @param[in] memory - pointer to a block of static memory for - /// allocator or nullptr - /// to obtain memory from global heap. If not nullptr, the objects - /// argument defines the size of the memory block (size x objects = - /// memory size in bytes). - /// @param[in] name - optional allocator name string. - Allocator(size_t size, usint objects = 0, char* memory = nullptr, const char* name = nullptr); // NOLINT + /// @param[in] memory - pointer to a block of static memory for allocator or nullptr + /// to obtain memory from global heap. If not nullptr, the objects argument + /// defines the size of the memory block (size x objects = memory size in bytes). + /// @param[in] name - optional allocator name string. + Allocator(size_t size, size_t objects = 0, char* memory = nullptr, const char* name = nullptr); /// Destructor ~Allocator(); /// Get a pointer to a memory block. /// @param[in] size - size of the block to allocate - /// @return Returns pointer to the block. Otherwise nullptr if - /// unsuccessful. + /// @return Returns pointer to the block. Otherwise nullptr if unsuccessful. void* Allocate(size_t size); /// Return a pointer to the memory pool. @@ -70,74 +66,72 @@ class Allocator { void Deallocate(void* pBlock); /// Get the allocator name string. - /// @return A pointer to the allocator name or nullptr if none was - /// assigned. - const char* GetName() { + /// @return A pointer to the allocator name or nullptr if none was assigned. + const char* GetName() const { return m_name; } /// Gets the fixed block memory size, in bytes, handled by the allocator. - /// @return The fixed block size in bytes. - size_t GetBlockSize() { + /// @return The fixed block size in bytes. + size_t GetBlockSize() const { return m_blockSize; } /// Gets the maximum number of blocks created by the allocator. - /// @return The number of fixed memory blocks created. - usint GetBlockCount() { + /// @return The number of fixed memory blocks created. + size_t GetBlockCount() const { return m_blockCnt; } /// Gets the number of blocks in use. - /// @return The number of blocks in use by the application. - usint GetBlocksInUse() { + /// @return The number of blocks in use by the application. + size_t GetBlocksInUse() const { return m_blocksInUse; } /// Gets the total number of allocations for this allocator instance. - /// @return The total number of allocations. - usint GetAllocations() { + /// @return The total number of allocations. + size_t GetAllocations() const { return m_allocations; } /// Gets the total number of deallocations for this allocator instance. - /// @return The total number of deallocations. - usint GetDeallocations() { + /// @return The total number of deallocations. + size_t GetDeallocations() const { return m_deallocations; } + AllocatorMode GetMode() const { + return m_allocatorMode; + } + private: /// Push a memory block onto head of free-list. /// @param[in] pMemory - block of memory to push onto free-list void Push(void* pMemory); /// Pop a memory block from head of free-list. - /// @return Returns pointer to the block. Otherwise nullptr if - /// unsuccessful. + /// @return Returns pointer to the block. Otherwise nullptr if unsuccessful. void* Pop(); struct Block { Block* pNext; }; - enum AllocatorMode { HEAP_BLOCKS, HEAP_POOL, STATIC_POOL }; - - const size_t m_blockSize; - const size_t m_objectSize; - const usint m_maxObjects; - AllocatorMode m_allocatorMode; - Block* m_pHead; - char* m_pPool; - usint m_poolIndex; - usint m_blockCnt; - usint m_blocksInUse; - usint m_allocations; - usint m_deallocations; + size_t m_blockSize; + size_t m_maxObjects; + Block* m_pHead{nullptr}; + char* m_pPool{nullptr}; + size_t m_blockCnt{0}; + size_t m_blocksInUse{0}; + size_t m_allocations{0}; + size_t m_deallocations{0}; + AllocatorMode m_allocatorMode{HEAP_BLOCKS}; const char* m_name; }; // Template class to create external memory pool -template +template class AllocatorPool : public Allocator { public: AllocatorPool() : Allocator(sizeof(T), Objects, m_memory) {} @@ -150,13 +144,9 @@ class AllocatorPool : public Allocator { #define DECLARE_ALLOCATOR \ public: \ void* operator new(size_t size) { \ - OPENFHE_DEBUG_FLAG(false); \ - OPENFHE_DEBUG("allocating " << size << " bytes"); \ return _allocator.Allocate(size); \ } \ void operator delete(void* pObject) { \ - OPENFHE_DEBUG_FLAG(false); \ - OPENFHE_DEBUG("deallocating "); \ _allocator.Deallocate(pObject); \ } \ \ diff --git a/src/core/include/utils/blockAllocator/xallocator.h b/src/core/include/utils/blockAllocator/xallocator.h index 7f0c5cd4b..8dc493a39 100644 --- a/src/core/include/utils/blockAllocator/xallocator.h +++ b/src/core/include/utils/blockAllocator/xallocator.h @@ -33,22 +33,14 @@ #define _XALLOCATOR_H #include -#include "utils/inttypes.h" // See // http://www.codeproject.com/Articles/1084801/Replace-malloc-free-with-a-Fast-Fixed-Block-Memory -#ifdef __cplusplus - // Define AUTOMATIC_XALLOCATOR_INIT_DESTROY to automatically call - // xalloc_init() and xalloc_destroy() when using xallocator in C++ - // projects. On embedded systems that never exit, you can save 1-byte - // of RAM storage per translation unit by undefining - // AUTOMATIC_XALLOCATOR_INIT_DESTROY and calling xalloc_init() - // manually before the OS starts. - #define AUTOMATIC_XALLOCATOR_INIT_DESTROY - #ifdef AUTOMATIC_XALLOCATOR_INIT_DESTROY +#define AUTOMATIC_XALLOCATOR_INIT_DESTROY +#ifdef AUTOMATIC_XALLOCATOR_INIT_DESTROY /// If a C++ translation unit, create a static instance of -/// XallocInitDestroy. Any C++ file including xallocator.h will have +/// XallocInitDestroy, any C++ file including xallocator.h will have /// the xallocDestroy instance declared first within the translation /// unit and thus will be constructed first. Destruction will occur in /// the reverse order so xallocInitDestroy is called last. This way, @@ -60,14 +52,9 @@ class XallocInitDestroy { ~XallocInitDestroy(); private: - static usint refCount; + static uint32_t refCount; }; - #endif // AUTOMATIC_XALLOCATOR_INIT_DESTROY -#endif // __cplusplus - -#ifdef __cplusplus -extern "C" { -#endif +#endif // AUTOMATIC_XALLOCATOR_INIT_DESTROY /// This function must be called exactly one time before the operating /// system threading starts. If using xallocator exclusively in C @@ -115,8 +102,4 @@ public: \ xfree(pObject); \ } -#ifdef __cplusplus -} -#endif - #endif diff --git a/src/core/include/utils/demangle.h b/src/core/include/utils/demangle.h index b12793b66..751b56bd4 100644 --- a/src/core/include/utils/demangle.h +++ b/src/core/include/utils/demangle.h @@ -33,6 +33,6 @@ #include -std::string demangle(const char* name); +std::string demangle(const char* name) noexcept; #endif // __DEMANGLE_H__ diff --git a/src/core/include/utils/get-call-stack.h b/src/core/include/utils/get-call-stack.h index 2481470c2..b54ca1d3d 100644 --- a/src/core/include/utils/get-call-stack.h +++ b/src/core/include/utils/get-call-stack.h @@ -35,9 +35,10 @@ #include /** - * @brief get_call_stack() is a function to get the call stack + * @brief get_call_stack() is a function to get the call stack. + * @attention it must not throw an exception as it is called from OpenFHEException * @return a vector with call stack (demangled function names) */ -std::vector get_call_stack(); +std::vector get_call_stack() noexcept; #endif // __GET_CALL_STACK_H__ diff --git a/src/core/include/utils/serial.h b/src/core/include/utils/serial.h index 9d197f72a..dad6612ad 100644 --- a/src/core/include/utils/serial.h +++ b/src/core/include/utils/serial.h @@ -196,6 +196,18 @@ std::string SerializeToString(const T& t) { return s.str(); } +/** + * DeserializeFromString - deserialize the object from a JSON string + * @param obj - any object to deserialize into + * @param json - JSON string + */ +template +void DeserializeFromString(T& obj, const std::string& json) { + std::stringstream s; + s << json; + Serial::Deserialize(obj, s, SerType::JSON); +} + } // namespace Serial } // namespace lbcrypto diff --git a/src/core/lib/lattice/stdlatticeparms.cpp b/src/core/lib/lattice/stdlatticeparms.cpp index 21ac996a3..948b5ff21 100644 --- a/src/core/lib/lattice/stdlatticeparms.cpp +++ b/src/core/lib/lattice/stdlatticeparms.cpp @@ -159,9 +159,12 @@ std::vector StdLatticeParm::StandardLatticeParmSets({ StdLatticeParm(HEStd_error, 32768, HEStd_128_classic, 883), StdLatticeParm(HEStd_error, 32768, HEStd_192_classic, 613), StdLatticeParm(HEStd_error, 32768, HEStd_256_classic, 478), - StdLatticeParm(HEStd_error, 65536, HEStd_128_classic, 1774), - StdLatticeParm(HEStd_error, 65536, HEStd_192_classic, 1230), - StdLatticeParm(HEStd_error, 65536, HEStd_256_classic, 958), + StdLatticeParm(HEStd_error, 65536, HEStd_128_classic, 1749), + StdLatticeParm(HEStd_error, 65536, HEStd_192_classic, 1201), + StdLatticeParm(HEStd_error, 65536, HEStd_256_classic, 931), + StdLatticeParm(HEStd_error, 131072, HEStd_128_classic, 3525), + StdLatticeParm(HEStd_error, 131072, HEStd_192_classic, 2413), + StdLatticeParm(HEStd_error, 131072, HEStd_256_classic, 1868), StdLatticeParm(HEStd_ternary, 1024, HEStd_128_classic, 27), StdLatticeParm(HEStd_ternary, 1024, HEStd_192_classic, 19), @@ -181,9 +184,12 @@ std::vector StdLatticeParm::StandardLatticeParmSets({ StdLatticeParm(HEStd_ternary, 32768, HEStd_128_classic, 881), StdLatticeParm(HEStd_ternary, 32768, HEStd_192_classic, 611), StdLatticeParm(HEStd_ternary, 32768, HEStd_256_classic, 476), - StdLatticeParm(HEStd_ternary, 65536, HEStd_128_classic, 1772), - StdLatticeParm(HEStd_ternary, 65536, HEStd_192_classic, 1228), - StdLatticeParm(HEStd_ternary, 65536, HEStd_256_classic, 956), + StdLatticeParm(HEStd_ternary, 65536, HEStd_128_classic, 1747), + StdLatticeParm(HEStd_ternary, 65536, HEStd_192_classic, 1199), + StdLatticeParm(HEStd_ternary, 65536, HEStd_256_classic, 929), + StdLatticeParm(HEStd_ternary, 131072, HEStd_128_classic, 3523), + StdLatticeParm(HEStd_ternary, 131072, HEStd_192_classic, 2411), + StdLatticeParm(HEStd_ternary, 131072, HEStd_256_classic, 1866), StdLatticeParm(HEStd_uniform, 1024, HEStd_128_quantum, 27), StdLatticeParm(HEStd_uniform, 1024, HEStd_192_quantum, 19), @@ -222,6 +228,12 @@ std::vector StdLatticeParm::StandardLatticeParmSets({ StdLatticeParm(HEStd_error, 32768, HEStd_128_quantum, 829), StdLatticeParm(HEStd_error, 32768, HEStd_192_quantum, 573), StdLatticeParm(HEStd_error, 32768, HEStd_256_quantum, 445), + StdLatticeParm(HEStd_error, 65536, HEStd_128_quantum, 1665), + StdLatticeParm(HEStd_error, 65536, HEStd_192_quantum, 1147), + StdLatticeParm(HEStd_error, 65536, HEStd_256_quantum, 890), + StdLatticeParm(HEStd_error, 131072, HEStd_128_quantum, 3351), + StdLatticeParm(HEStd_error, 131072, HEStd_192_quantum, 2304), + StdLatticeParm(HEStd_error, 131072, HEStd_256_quantum, 1786), StdLatticeParm(HEStd_ternary, 1024, HEStd_128_quantum, 25), StdLatticeParm(HEStd_ternary, 1024, HEStd_192_quantum, 17), @@ -241,6 +253,12 @@ std::vector StdLatticeParm::StandardLatticeParmSets({ StdLatticeParm(HEStd_ternary, 32768, HEStd_128_quantum, 827), StdLatticeParm(HEStd_ternary, 32768, HEStd_192_quantum, 571), StdLatticeParm(HEStd_ternary, 32768, HEStd_256_quantum, 443), + StdLatticeParm(HEStd_ternary, 65536, HEStd_128_quantum, 1663), + StdLatticeParm(HEStd_ternary, 65536, HEStd_192_quantum, 1145), + StdLatticeParm(HEStd_ternary, 65536, HEStd_256_quantum, 888), + StdLatticeParm(HEStd_ternary, 131072, HEStd_128_quantum, 3348), + StdLatticeParm(HEStd_ternary, 131072, HEStd_192_quantum, 2301), + StdLatticeParm(HEStd_ternary, 131072, HEStd_256_quantum, 1784), }); } /* namespace lbcrypto */ diff --git a/src/core/lib/math/dftransform.cpp b/src/core/lib/math/dftransform.cpp index fe4c1b271..ea5b3b2dc 100644 --- a/src/core/lib/math/dftransform.cpp +++ b/src/core/lib/math/dftransform.cpp @@ -98,8 +98,8 @@ std::vector> DiscreteFourierTransform::FFTForwardTransform( std::vector> B(A); usint l = floor(log2(m)); - // static usint maxMCached(131072); - static usint LOGM_MAX(17); // maximum supported is 2^17 = 131072 + // static usint maxMCached(262144); + static usint LOGM_MAX(18); // maximum supported is 2^18 = 262144 static std::vector cachedM(LOGM_MAX + 1, 0); static std::vector> cosTable(LOGM_MAX + 1); static std::vector> sinTable(LOGM_MAX + 1); diff --git a/src/core/lib/math/hal/bigintdyn/be4-math-impl.cpp b/src/core/lib/math/hal/bigintdyn/be4-math-impl.cpp index 3c3eb8f38..cc08e718e 100644 --- a/src/core/lib/math/hal/bigintdyn/be4-math-impl.cpp +++ b/src/core/lib/math/hal/bigintdyn/be4-math-impl.cpp @@ -57,10 +57,10 @@ template M4Integer GreatestCommonDivisor(const M4Integer& a, const M4Integer& b) template bool MillerRabinPrimalityTest(const M4Integer& p, const usint niter); template const M4Integer PollardRhoFactorization(const M4Integer& n); template void PrimeFactorize(M4Integer n, std::set& primeFactors); -template M4Integer FirstPrime(uint32_t nBits, uint32_t m); -template M4Integer LastPrime(uint32_t nBits, uint32_t m); -template M4Integer NextPrime(const M4Integer& q, uint32_t m); -template M4Integer PreviousPrime(const M4Integer& q, uint32_t m); +template M4Integer FirstPrime(uint32_t nBits, uint64_t m); +template M4Integer LastPrime(uint32_t nBits, uint64_t m); +template M4Integer NextPrime(const M4Integer& q, uint64_t m); +template M4Integer PreviousPrime(const M4Integer& q, uint64_t m); template std::vector GetTotientList(const M4Integer& n); template M4Vector PolyMod(const M4Vector& dividend, const M4Vector& divisor, const M4Integer& modulus); template M4Vector PolynomialMultiplication(const M4Vector& a, const M4Vector& b); diff --git a/src/core/lib/math/hal/bigintfxd/be2-math-impl.cpp b/src/core/lib/math/hal/bigintfxd/be2-math-impl.cpp index 8e1c67317..7c92fbcea 100644 --- a/src/core/lib/math/hal/bigintfxd/be2-math-impl.cpp +++ b/src/core/lib/math/hal/bigintfxd/be2-math-impl.cpp @@ -57,10 +57,10 @@ template M2Integer GreatestCommonDivisor(const M2Integer& a, const M2Integer& b) template bool MillerRabinPrimalityTest(const M2Integer& p, const usint niter); template const M2Integer PollardRhoFactorization(const M2Integer& n); template void PrimeFactorize(M2Integer n, std::set& primeFactors); -template M2Integer FirstPrime(uint32_t nBits, uint32_t m); -template M2Integer LastPrime(uint32_t nBits, uint32_t m); -template M2Integer NextPrime(const M2Integer& q, uint32_t m); -template M2Integer PreviousPrime(const M2Integer& q, uint32_t m); +template M2Integer FirstPrime(uint32_t nBits, uint64_t m); +template M2Integer LastPrime(uint32_t nBits, uint64_t m); +template M2Integer NextPrime(const M2Integer& q, uint64_t m); +template M2Integer PreviousPrime(const M2Integer& q, uint64_t m); template std::vector GetTotientList(const M2Integer& n); template M2Vector PolyMod(const M2Vector& dividend, const M2Vector& divisor, const M2Integer& modulus); template M2Vector PolynomialMultiplication(const M2Vector& a, const M2Vector& b); diff --git a/src/core/lib/math/hal/bigintntl/be6-math-impl.cpp b/src/core/lib/math/hal/bigintntl/be6-math-impl.cpp index 15a8f3fd7..20d286912 100644 --- a/src/core/lib/math/hal/bigintntl/be6-math-impl.cpp +++ b/src/core/lib/math/hal/bigintntl/be6-math-impl.cpp @@ -61,10 +61,10 @@ template M6Integer GreatestCommonDivisor(const M6Integer& a, const M6Integer& b) template bool MillerRabinPrimalityTest(const M6Integer& p, const usint niter); template const M6Integer PollardRhoFactorization(const M6Integer& n); template void PrimeFactorize(M6Integer n, std::set& primeFactors); -template M6Integer FirstPrime(uint32_t nBits, uint32_t m); -template M6Integer LastPrime(uint32_t nBits, uint32_t m); -template M6Integer NextPrime(const M6Integer& q, uint32_t m); -template M6Integer PreviousPrime(const M6Integer& q, uint32_t m); +template M6Integer FirstPrime(uint32_t nBits, uint64_t m); +template M6Integer LastPrime(uint32_t nBits, uint64_t m); +template M6Integer NextPrime(const M6Integer& q, uint64_t m); +template M6Integer PreviousPrime(const M6Integer& q, uint64_t m); template std::vector GetTotientList(const M6Integer& n); template M6Vector PolyMod(const M6Vector& dividend, const M6Vector& divisor, const M6Integer& modulus); template M6Vector PolynomialMultiplication(const M6Vector& a, const M6Vector& b); diff --git a/src/core/lib/math/hal/intnat/benative-math-impl.cpp b/src/core/lib/math/hal/intnat/benative-math-impl.cpp index 6cca82edc..8ca835d39 100644 --- a/src/core/lib/math/hal/intnat/benative-math-impl.cpp +++ b/src/core/lib/math/hal/intnat/benative-math-impl.cpp @@ -56,10 +56,10 @@ template NativeInteger GreatestCommonDivisor(const NativeInteger& a, const Nativ template bool MillerRabinPrimalityTest(const NativeInteger& p, const usint niter); template const NativeInteger PollardRhoFactorization(const NativeInteger& n); template void PrimeFactorize(NativeInteger n, std::set& primeFactors); -template NativeInteger FirstPrime(uint32_t nBits, uint32_t m); -template NativeInteger LastPrime(uint32_t nBits, uint32_t m); -template NativeInteger NextPrime(const NativeInteger& q, uint32_t m); -template NativeInteger PreviousPrime(const NativeInteger& q, uint32_t m); +template NativeInteger FirstPrime(uint32_t nBits, uint64_t m); +template NativeInteger LastPrime(uint32_t nBits, uint64_t m); +template NativeInteger NextPrime(const NativeInteger& q, uint64_t m); +template NativeInteger PreviousPrime(const NativeInteger& q, uint64_t m); template std::vector GetTotientList(const NativeInteger& n); template std::vector GetTotientList(const usint& n); diff --git a/src/core/lib/utils/blockAllocator/blockAllocator.cpp b/src/core/lib/utils/blockAllocator/blockAllocator.cpp index 75077a982..aa890f5ee 100644 --- a/src/core/lib/utils/blockAllocator/blockAllocator.cpp +++ b/src/core/lib/utils/blockAllocator/blockAllocator.cpp @@ -33,26 +33,17 @@ See http://www.codeproject.com/Articles/1089905/A-Custom-STL-std-allocator-Replacement-Improves-Performance- */ -#include -#include #include "utils/blockAllocator/blockAllocator.h" +#include "utils/exception.h" +#include //------------------------------------------------------------------------------ // Constructor //------------------------------------------------------------------------------ -Allocator::Allocator(size_t size, usint objects, char* memory, const char* name) - : m_blockSize(size < sizeof(long*) ? sizeof(long*) : size), // NOLINT - m_objectSize(size), - m_maxObjects(objects), - m_pHead(nullptr), - m_poolIndex(0), - m_blockCnt(0), - m_blocksInUse(0), - m_allocations(0), - m_deallocations(0), - m_name(name) { +Allocator::Allocator(size_t size, size_t objects, char* memory, const char* name) + : m_blockSize(size), m_maxObjects(objects), m_name(name) { // If using a fixed memory pool - if (m_maxObjects) { + if (m_maxObjects > 0) { // If caller provided an external memory pool if (memory) { m_pPool = memory; @@ -63,9 +54,6 @@ Allocator::Allocator(size_t size, usint objects, char* memory, const char* name) m_allocatorMode = HEAP_POOL; } } - else { - m_allocatorMode = HEAP_BLOCKS; - } } //------------------------------------------------------------------------------ @@ -87,39 +75,29 @@ Allocator::~Allocator() { // Allocate //------------------------------------------------------------------------------ void* Allocator::Allocate(size_t size) { - assert(size <= m_objectSize); + if (size > m_blockSize) + OPENFHE_THROW("Exceeded max block size " + std::to_string(size)); - // If can't obtain existing block then get a new one void* pBlock = Pop(); if (!pBlock) { // If using a pool method then get block from pool, // otherwise using dynamic so get block from heap - if (m_maxObjects) { + if (m_maxObjects > 0) { // If we have not exceeded the pool maximum - if (m_poolIndex < m_maxObjects) { - pBlock = reinterpret_cast(m_pPool + (m_poolIndex++ * m_blockSize)); + if (m_blockCnt < m_maxObjects) { + pBlock = reinterpret_cast(m_pPool + (m_blockCnt++ * m_blockSize)); } else { - // Get the pointer to the new handler - std::new_handler handler = std::set_new_handler(0); - std::set_new_handler(handler); - - // If a new handler is defined, call it - if (handler) - (*handler)(); - else - assert(0); + OPENFHE_THROW("Exceeded max block count " + std::to_string(size)); } } else { - m_blockCnt++; + ++m_blockCnt; pBlock = reinterpret_cast(new char[m_blockSize]); } } - - m_blocksInUse++; - m_allocations++; - + ++m_blocksInUse; + ++m_allocations; return pBlock; } @@ -128,8 +106,8 @@ void* Allocator::Allocate(size_t size) { //------------------------------------------------------------------------------ void Allocator::Deallocate(void* pBlock) { Push(pBlock); - m_blocksInUse--; - m_deallocations++; + --m_blocksInUse; + ++m_deallocations; } //------------------------------------------------------------------------------ @@ -146,11 +124,9 @@ void Allocator::Push(void* pMemory) { //------------------------------------------------------------------------------ void* Allocator::Pop() { Block* pBlock = nullptr; - if (m_pHead) { pBlock = m_pHead; m_pHead = m_pHead->pNext; } - return reinterpret_cast(pBlock); } diff --git a/src/core/lib/utils/blockAllocator/xallocator.cpp b/src/core/lib/utils/blockAllocator/xallocator.cpp index e752df5e8..d95798368 100644 --- a/src/core/lib/utils/blockAllocator/xallocator.cpp +++ b/src/core/lib/utils/blockAllocator/xallocator.cpp @@ -36,54 +36,66 @@ #include #include // for memcpy consider changing to copy #include +#include #include #include #include "utils/blockAllocator/blockAllocator.h" #include "utils/blockAllocator/xallocator.h" -#include "utils/debug.h" - -#ifndef CHAR_BIT - #define CHAR_BIT 8 -#endif - -// static CRITICAL_SECTION _criticalSection; +#include "utils/exception.h" static std::mutex xalloc_mutex; - static bool _xallocInitialized = false; +static std::map _allocators; -// Define STATIC_POOLS to switch from heap blocks mode to static pools mode // #define STATIC_POOLS #ifdef STATIC_POOLS - // Update this section as necessary if you want to use static memory pools. - // See also xalloc_init() and xalloc_destroy() for additional updates required. - #define MAX_ALLOCATORS 14 - // #define MAX_BLOCKS 2048 - #define MAX_BLOCKS 18948 + +// Update this section, xalloc_init() and xalloc_destroy() as needed if you want to use static memory pools. +// Add add_compile_options(-mcmodel=medium) to CMakeLists.txt to avoid relocation truncated to fit: R_X86_64_PC32 against `.bss' error + +#define DEFAULT_BLOCK_COUNT 1024 +using _pool8 = AllocatorPool; +using _pool16 = AllocatorPool; +using _pool32 = AllocatorPool; +using _pool64 = AllocatorPool; +using _pool128 = AllocatorPool; +using _pool256 = AllocatorPool; +using _pool512 = AllocatorPool; +using _pool1k = AllocatorPool; +using _pool2k = AllocatorPool; +using _pool4k = AllocatorPool; +using _pool8k = AllocatorPool; +using _pool16k = AllocatorPool; +using _pool32k = AllocatorPool; +using _pool64k = AllocatorPool; +using _pool128k = AllocatorPool; +using _pool256k = AllocatorPool; +using _pool512k = AllocatorPool; +using _pool1M = AllocatorPool; +using _pool2M = AllocatorPool; // Create static storage for each static allocator instance -char* _allocator8[sizeof(AllocatorPool)]; -char* _allocator16[sizeof(AllocatorPool)]; -char* _allocator32[sizeof(AllocatorPool)]; -char* _allocator64[sizeof(AllocatorPool)]; -char* _allocator128[sizeof(AllocatorPool)]; -char* _allocator256[sizeof(AllocatorPool)]; -char* _allocator396[sizeof(AllocatorPool)]; -char* _allocator512[sizeof(AllocatorPool)]; -char* _allocator768[sizeof(AllocatorPool)]; -char* _allocator1024[sizeof(AllocatorPool)]; -char* _allocator2048[sizeof(AllocatorPool)]; -char* _allocator4096[sizeof(AllocatorPool)]; -char* _allocator8192[sizeof(AllocatorPool)]; -char* _allocator16384[sizeof(AllocatorPool)]; - -// Array of pointers to all allocator instances -static Allocator* _allocators[MAX_ALLOCATORS]; +static char* _allocator8[sizeof(_pool8)]; +static char* _allocator16[sizeof(_pool16)]; +static char* _allocator32[sizeof(_pool32)]; +static char* _allocator64[sizeof(_pool64)]; +static char* _allocator128[sizeof(_pool128)]; +static char* _allocator256[sizeof(_pool256)]; +static char* _allocator512[sizeof(_pool512)]; +static char* _allocator1k[sizeof(_pool1k)]; +static char* _allocator2k[sizeof(_pool2k)]; +static char* _allocator4k[sizeof(_pool4k)]; +static char* _allocator8k[sizeof(_pool8k)]; +static char* _allocator16k[sizeof(_pool16k)]; +static char* _allocator32k[sizeof(_pool32k)]; +static char* _allocator64k[sizeof(_pool64k)]; +static char* _allocator128k[sizeof(_pool128k)]; +static char* _allocator256k[sizeof(_pool256k)]; +static char* _allocator512k[sizeof(_pool512k)]; +static char* _allocator1M[sizeof(_pool1M)]; +// static char* _allocator2M[sizeof(_pool2M)]; -#else - #define MAX_ALLOCATORS 15 -static Allocator* _allocators[MAX_ALLOCATORS]; #endif // STATIC_POOLS static XallocInitDestroy xallocInitDestroy; @@ -102,7 +114,7 @@ static XallocInitDestroy xallocInitDestroy; // and xalloc_destroy() before main exits. In all other situations // XallocInitDestroy must be used to call xalloc_init() and xalloc_destroy(). #ifdef AUTOMATIC_XALLOCATOR_INIT_DESTROY -usint XallocInitDestroy::refCount = 0; +uint32_t XallocInitDestroy::refCount = 0; XallocInitDestroy::XallocInitDestroy() { // Track how many static instances of XallocInitDestroy are created if (refCount++ == 0) @@ -116,18 +128,6 @@ XallocInitDestroy::~XallocInitDestroy() { } #endif // AUTOMATIC_XALLOCATOR_INIT_DESTROY -/// Returns the next higher powers of two. For instance, pass in 12 and -/// the value returned would be 16. -/// @param[in] k - numeric value to compute the next higher power of two. -/// @return The next higher power of two based on the input k. -template -T nexthigher(T k) { - k--; - for (size_t i = 1; i < sizeof(T) * CHAR_BIT; i <<= 1) - k |= (k >> i); - return k + 1; -} - /// Create the xallocator lock. Call only one time at startup. /// note for C++11 we do not need to control the lock with the lock_* functions. /// instead we control the next exection function in the code. @@ -138,8 +138,8 @@ static void lock_init() { /// Destroy the xallocator lock. static void lock_destroy() { #if 0 - // DeleteCriticalSection(&_criticalSection); - irc = pthread_mutex_destroy(&xalloc_mutex); + // DeleteCriticalSection(&_criticalSection); + irc = pthread_mutex_destroy(&xalloc_mutex); #endif _xallocInitialized = false; } @@ -149,9 +149,9 @@ static inline void lock_get() { if (_xallocInitialized == false) return; #if 0 - // Acquire the mutex to access the shared resource - pthread_mutex_lock(&xalloc_mutex); - // EnterCriticalSection(&_criticalSection); + // Acquire the mutex to access the shared resource + pthread_mutex_lock(&xalloc_mutex); + // EnterCriticalSection(&_criticalSection); #endif } @@ -159,156 +159,125 @@ static inline void lock_get() { static inline void lock_release() { if (_xallocInitialized == false) return; - #if 0 - // Release the mutex and release the access to shared resource - pthread_mutex_unlock(&xalloc_mutex); - // LeaveCriticalSection(&_criticalSection); + // Release the mutex and release the access to shared resource + pthread_mutex_unlock(&xalloc_mutex); + // LeaveCriticalSection(&_criticalSection); #endif } /// Stored a pointer to the allocator instance within the block region. -/// a pointer to the client's area within the block. -/// @param[in] block - a pointer to the raw memory block. +/// @param[in] block - a pointer to the raw memory block. /// @param[in] size - the client requested size of the memory block. -/// @return A pointer to the client's address within the raw memory block. +/// @return A pointer to the client's address within the raw memory block. static inline void* set_block_allocator(void* block, Allocator* allocator) { // Cast the raw block memory to a Allocator pointer - Allocator** pAllocatorInBlock = static_cast(block); - // Write the size into the memory block - *pAllocatorInBlock = allocator; - // Advance the pointer past the Allocator* block size and return a pointer to // the client's memory region + Allocator** pAllocatorInBlock = static_cast(block); + *pAllocatorInBlock = allocator; return ++pAllocatorInBlock; } /// Gets the size of the memory block stored within the block. -/// @param[in] block - a pointer to the client's memory block. -/// @return The original allocator instance stored in the memory block. +/// @param[in] block - a pointer to the client's memory block. +/// @return The original allocator instance stored in the memory block. static inline Allocator* get_block_allocator(void* block) { // Cast the client memory to a Allocator pointer - Allocator** pAllocatorInBlock = static_cast(block); - // Back up one Allocator* position to get the stored allocator instance - pAllocatorInBlock--; - // Return the allocator instance stored within the memory block + Allocator** pAllocatorInBlock = static_cast(block); + --pAllocatorInBlock; return *pAllocatorInBlock; } /// Returns the raw memory block pointer given a client memory pointer. -/// @param[in] block - a pointer to the client memory block. -/// @return A pointer to the original raw memory block address. +/// @param[in] block - a pointer to the client memory block. +/// @return A pointer to the original raw memory block address. static inline void* get_block_ptr(void* block) { // Cast the client memory to a Allocator* pointer - Allocator** pAllocatorInBlock = static_cast(block); - // Back up one Allocator* position and return the original raw memory block // pointer + Allocator** pAllocatorInBlock = static_cast(block); return --pAllocatorInBlock; } -/// Returns an allocator instance matching the size provided -/// @param[in] size - allocator block size -/// @return Allocator instance handling requested block size or nullptr -/// if no allocator exists. -static inline Allocator* find_allocator(size_t size) { - OPENFHE_DEBUG_FLAG(false); - for (usint i = 0; i < MAX_ALLOCATORS; i++) { - OPENFHE_DEBUG("allocator " << i << " " << _allocators[i]); - - if (_allocators[i] == 0) - break; - - if (_allocators[i]->GetBlockSize() == size) - return _allocators[i]; - } - - return nullptr; -} - -/// Insert an allocator instance into the array -/// @param[in] allocator - An allocator instance -static inline void insert_allocator(Allocator* allocator) { - for (usint i = 0; i < MAX_ALLOCATORS; i++) { - if (_allocators[i] == 0) { - _allocators[i] = allocator; - return; - } - } - - assert(0); -} - /// This function must be called exactly one time *before* any other xallocator -/// API is called. XallocInitDestroy constructor calls this function -/// automatically. -extern "C" void xalloc_init() { +/// API is called. XallocInitDestroy constructor calls this function automatically. +void xalloc_init() { lock_init(); #ifdef STATIC_POOLS // For STATIC_POOLS mode, the allocators must be initialized before any other // static user class constructor is run. Therefore, use placement new to - // initialize each allocator into the previously reserved static memory - // locations. - new (&_allocator8) AllocatorPool(); - new (&_allocator16) AllocatorPool(); - new (&_allocator32) AllocatorPool(); - new (&_allocator64) AllocatorPool(); - new (&_allocator128) AllocatorPool(); - new (&_allocator256) AllocatorPool(); - new (&_allocator396) AllocatorPool(); - new (&_allocator512) AllocatorPool(); - new (&_allocator768) AllocatorPool(); - new (&_allocator1024) AllocatorPool(); - new (&_allocator2048) AllocatorPool(); - new (&_allocator4096) AllocatorPool(); - new (&_allocator8192) AllocatorPool(); - new (&_allocator16384) AllocatorPool(); - - // Populate allocator array with all instances - _allocators[0] = reinterpret_cast(&_allocator8); - _allocators[1] = reinterpret_cast(&_allocator16); - _allocators[2] = reinterpret_cast(&_allocator32); - _allocators[3] = reinterpret_cast(&_allocator64); - _allocators[4] = reinterpret_cast(&_allocator128); - _allocators[5] = reinterpret_cast(&_allocator256); - _allocators[6] = reinterpret_cast(&_allocator396); - _allocators[7] = reinterpret_cast(&_allocator512); - _allocators[8] = reinterpret_cast(&_allocator768); - _allocators[9] = reinterpret_cast(&_allocator1024); - _allocators[10] = reinterpret_cast(&_allocator2048); - _allocators[11] = reinterpret_cast(&_allocator4096); - _allocators[12] = reinterpret_cast(&_allocator8192); - _allocators[13] = reinterpret_cast(&_allocator16384); - + // initialize each allocator into the previously reserved static memory locations. + + new (&_allocator8) _pool8; + new (&_allocator16) _pool16; + new (&_allocator32) _pool32; + new (&_allocator64) _pool64; + new (&_allocator128) _pool128; + new (&_allocator256) _pool256; + new (&_allocator512) _pool512; + new (&_allocator1k) _pool1k; + new (&_allocator2k) _pool2k; + new (&_allocator4k) _pool4k; + new (&_allocator8k) _pool8k; + new (&_allocator16k) _pool16k; + new (&_allocator32k) _pool32k; + new (&_allocator64k) _pool64k; + new (&_allocator128k) _pool128k; + new (&_allocator256k) _pool256k; + new (&_allocator512k) _pool512k; + new (&_allocator1M) _pool1M; +// new (&_allocator2M) _pool2M; + + _allocators = { {sizeof(Allocator*) + (1 << 3), reinterpret_cast(&_allocator8)}, + {sizeof(Allocator*) + (1 << 4), reinterpret_cast(&_allocator16)}, + {sizeof(Allocator*) + (1 << 5), reinterpret_cast(&_allocator32)}, + {sizeof(Allocator*) + (1 << 6), reinterpret_cast(&_allocator64)}, + {sizeof(Allocator*) + (1 << 7), reinterpret_cast(&_allocator128)}, + {sizeof(Allocator*) + (1 << 8), reinterpret_cast(&_allocator256)}, + {sizeof(Allocator*) + (1 << 9), reinterpret_cast(&_allocator512)}, + {sizeof(Allocator*) + (1 << 10), reinterpret_cast(&_allocator1k)}, + {sizeof(Allocator*) + (1 << 11), reinterpret_cast(&_allocator2k)}, + {sizeof(Allocator*) + (1 << 12), reinterpret_cast(&_allocator4k)}, + {sizeof(Allocator*) + (1 << 13), reinterpret_cast(&_allocator8k)}, + {sizeof(Allocator*) + (1 << 14), reinterpret_cast(&_allocator16k)}, + {sizeof(Allocator*) + (1 << 15), reinterpret_cast(&_allocator32k)}, + {sizeof(Allocator*) + (1 << 16), reinterpret_cast(&_allocator64k)}, + {sizeof(Allocator*) + (1 << 17), reinterpret_cast(&_allocator128k)}, + {sizeof(Allocator*) + (1 << 18), reinterpret_cast(&_allocator256k)}, + {sizeof(Allocator*) + (1 << 19), reinterpret_cast(&_allocator512k)}, + {sizeof(Allocator*) + (1 << 20), reinterpret_cast(&_allocator1M)} +// {sizeof(Allocator*) + (1 << 21), reinterpret_cast(&_allocator2M)} + }; +#else + for (size_t b = 3; b < 21; ++b) { + size_t blockSize = sizeof(Allocator*) + (1 << b); + _allocators[blockSize] = new Allocator(blockSize); + } #endif } /// Called one time when the application exits to cleanup any allocated memory. /// ~XallocInitDestroy destructor calls this function automatically. -extern "C" void xalloc_destroy() { +void xalloc_destroy() { lock_get(); std::unique_lock lock(xalloc_mutex); { + for (auto& [k, a] : _allocators) { #ifdef STATIC_POOLS - for (usint i = 0; i < MAX_ALLOCATORS; i++) { - _allocators[i]->~Allocator(); - _allocators[i] = 0; - } + a->~Allocator(); #else - for (usint i = 0; i < MAX_ALLOCATORS; i++) { - if (_allocators[i] == 0) - break; - delete _allocators[i]; - _allocators[i] = 0; - } + delete a; #endif + a = nullptr; + } + _allocators.clear(); } lock_release(); - lock_destroy(); } @@ -316,52 +285,20 @@ extern "C" void xalloc_destroy() { /// If a Allocator instance is not currently available to handle the size, /// then a new Allocator instance is create. /// @param[in] size - the client's requested block size. -/// @return An Allocator instance that handles blocks of the requested -/// size. -extern "C" Allocator* xallocator_get_allocator(size_t size) { - // Based on the size, find the next higher powers of two value. - // Add sizeof(Allocator*) to the requested block size to hold the size - // within the block memory region. Most blocks are powers of two, - // however some common allocator block sizes can be explicitly defined - // to minimize wasted storage. This offers application specific tuning. - OPENFHE_DEBUG_FLAG(false); +/// @return An Allocator instance that handles blocks of the requested size. +Allocator* xallocator_get_allocator(size_t size) { size_t blockSize = size + sizeof(Allocator*); - if (blockSize > 256 && blockSize <= 396) - blockSize = 396; - else if (blockSize > 512 && blockSize <= 768) - blockSize = 768; - else - blockSize = nexthigher(blockSize); - OPENFHE_DEBUG("finding allocator for blockSize " << blockSize); - Allocator* allocator = find_allocator(blockSize); - -#ifdef STATIC_POOLS - - if (allocator == nullptr) { - std::cerr << "static pool allocator for blockSize " << blockSize << " not found! " << std::endl; - } - assert(allocator != nullptr); -#else - // If there is not an allocator already created to handle this block size - if (allocator == nullptr) { - // Create a new allocator to handle blocks of the size required - allocator = new Allocator(blockSize, 0, 0, "xallocator"); - - // Insert allocator into array - insert_allocator(allocator); - } -#endif - - return allocator; + auto it = _allocators.lower_bound(blockSize); + if (it != _allocators.end()) + return it->second; + OPENFHE_THROW("Exceeded max block size"); } /// Allocates a memory block of the requested size. The blocks are created from -/// the fixed block allocators. +/// the fixed block allocators. /// @param[in] size - the client requested size of the block. -/// @return A pointer to the client's memory block. -extern "C" void* xmalloc(size_t size) { - OPENFHE_DEBUG_FLAG(false); - +/// @return A pointer to the client's memory block. +void* xmalloc(size_t size) { Allocator* allocator; void* blockMemoryPtr; lock_get(); @@ -370,23 +307,18 @@ extern "C" void* xmalloc(size_t size) { // Allocate a raw memory block allocator = xallocator_get_allocator(size); blockMemoryPtr = allocator->Allocate(sizeof(Allocator*) + size); - OPENFHE_DEBUG("xmalloc " << size); } lock_release(); // Set the block Allocator* within the raw memory block region - void* clientsMemoryPtr = set_block_allocator(blockMemoryPtr, allocator); - return clientsMemoryPtr; + return set_block_allocator(blockMemoryPtr, allocator); } /// Frees a memory block previously allocated with xalloc. The blocks are -/// returned -/// to the fixed block allocator that originally created it. +/// returned to the fixed block allocator that originally created it. /// @param[in] ptr - a pointer to a block created with xalloc. -extern "C" void xfree(void* ptr) { - OPENFHE_DEBUG_FLAG(false); - OPENFHE_DEBUG("xfree "); - if (ptr == 0) +void xfree(void* ptr) { + if (!ptr) return; // Extract the original allocator instance from the caller's block pointer @@ -407,57 +339,63 @@ extern "C" void xfree(void* ptr) { /// Reallocates a memory block previously allocated with xalloc. /// @param[in] ptr - a pointer to a block created with xalloc. /// @param[in] size - the client requested block size to create. -extern "C" void* xrealloc(void* oldMem, size_t size) { - if (oldMem == 0) +void* xrealloc(void* oldMem, size_t size) { + if (!oldMem) return xmalloc(size); if (size == 0) { xfree(oldMem); - return 0; + return nullptr; } - else { - // Create a new memory block - void* newMem = xmalloc(size); - if (newMem != 0) { - // Get the original allocator instance from the old memory block - Allocator* oldAllocator = get_block_allocator(oldMem); - size_t oldSize = oldAllocator->GetBlockSize() - sizeof(Allocator*); - - // Copy the bytes from the old memory block into the new (as much as will - // fit) - std::memcpy(newMem, oldMem, (oldSize < size) ? oldSize : size); - - // Free the old memory block - xfree(oldMem); - - // Return the client pointer to the new memory block - return newMem; - } - return 0; + + // Create a new memory block + void* newMem = xmalloc(size); + if (newMem) { + // Get the original allocator instance from the old memory block + Allocator* oldAllocator = get_block_allocator(oldMem); + size_t oldSize = oldAllocator->GetBlockSize() - sizeof(Allocator*); + + // Copy the bytes from the old memory block into the new (as much as will fit) + std::memcpy(newMem, oldMem, (oldSize < size) ? oldSize : size); + + // Free the old memory block + xfree(oldMem); + + // Return the client pointer to the new memory block + return newMem; } + return nullptr; } /// Output xallocator usage statistics -extern "C" void xalloc_stats() { +void xalloc_stats() { lock_get(); std::unique_lock lock(xalloc_mutex); { -#ifdef STATIC_POOLS - std::cout << " Static Pools " << std::endl; -#endif - - for (usint i = 0; i < MAX_ALLOCATORS; i++) { - if (_allocators[i] == 0) - break; - - if (_allocators[i]->GetName() != nullptr) - std::cout << _allocators[i]->GetName(); + std::cout << "\n***********************"; + if (!_allocators.empty()) { + auto mode = _allocators.begin()->second->GetMode(); + if (mode == Allocator::HEAP_BLOCKS) + std::cout << " HEAP_BLOCKS\n"; + if (mode == Allocator::HEAP_POOL) + std::cout << " HEAP_POOL\n"; + if (mode == Allocator::STATIC_POOL) + std::cout << " STATIC_POOL\n"; + } - std::cout << " Block Size: " << _allocators[i]->GetBlockSize(); - std::cout << " Block Count: " << _allocators[i]->GetBlockCount(); - std::cout << " Blocks In Use: " << _allocators[i]->GetBlocksInUse(); + for (auto& [k, a] : _allocators) { + if (a->GetBlockCount() == 0) + continue; + if (a->GetName()) + std::cout << a->GetName(); + std::cout << " Block Size: " << a->GetBlockSize(); + std::cout << " Block Count: " << a->GetBlockCount(); + std::cout << " Block Allocs: " << a->GetAllocations(); + std::cout << " Block Deallocs: " << a->GetDeallocations(); + std::cout << " Blocks In Use: " << a->GetBlocksInUse(); std::cout << std::endl; } + std::cout << "***********************\n"; } lock_release(); } diff --git a/src/core/lib/utils/demangle.cpp b/src/core/lib/utils/demangle.cpp index 6be50c5f8..ee476a160 100644 --- a/src/core/lib/utils/demangle.cpp +++ b/src/core/lib/utils/demangle.cpp @@ -34,14 +34,31 @@ #if defined(__clang__) || defined(__GNUC__) #include -std::string demangle(const char* const name) { - int status = -1; - std::unique_ptr result{abi::__cxa_demangle(name, NULL, NULL, &status)}; +std::string demangle(const char* const name) noexcept { + // output_buffer must be malloc'ed + size_t output_buffer_size = 512; + auto output_buffer = reinterpret_cast(std::malloc(output_buffer_size)); + int status = -1; - return (status == 0) ? result.get() : (std::string("Can not demangle symbol: ") + name); + char* ptr = abi::__cxa_demangle(name, output_buffer, &output_buffer_size, &status); + std::string result; + if (status == 0 && ptr != nullptr) { + result = ptr; + // If ptr is different from output_buffer, free ptr as it points to the newly allocated (realloc) buffer + if (ptr != output_buffer) + std::free(ptr); + else + std::free(output_buffer); + } + else { + result = "Cannot demangle symbol: " + std::string(name); + std::free(output_buffer); + } + + return result; } #else -std::string demangle(const char* const name) { +std::string demangle(const char* const name) noexcept { return name; } #endif diff --git a/src/core/lib/utils/get-call-stack.cpp b/src/core/lib/utils/get-call-stack.cpp index 28c049021..7b0bccd25 100644 --- a/src/core/lib/utils/get-call-stack.cpp +++ b/src/core/lib/utils/get-call-stack.cpp @@ -43,7 +43,7 @@ namespace { enum { MAX_BACKTRACE_ADDRESSES = 512 }; } -static bool stringEmpty(const std::string& str) { +static bool stringEmpty(const std::string& str) noexcept { if (!str.length()) return true; @@ -56,18 +56,21 @@ static bool stringEmpty(const std::string& str) { return true; } -std::vector get_call_stack() { +std::vector get_call_stack() noexcept { void* bt_buffer[MAX_BACKTRACE_ADDRESSES] = {NULL}; const int n = backtrace(bt_buffer, MAX_BACKTRACE_ADDRESSES); if (n < 1) { return std::vector(); } - const std::unique_ptr symbols(backtrace_symbols(bt_buffer, n)); + char** symbols = reinterpret_cast(backtrace_symbols(bt_buffer, n)); + if (symbols == NULL) { + return std::vector(); + } const size_t numSymbols = static_cast(n); - std::vector ret(numSymbols); + std::vector retVec(numSymbols); for (size_t i = 0; i < numSymbols; ++i) { - std::string symbol(symbols.get()[i]); + std::string symbol(symbols[i]); // we need to get rid of anything that doesn't belong to the name // Mangled symbol examples: // ./lib/libOPENFHEcore.so.1(_Z14get_call_stackB5cxx11v+0x35) [0x7f1b5cdb91d5] @@ -81,13 +84,14 @@ std::vector get_call_stack() { size_t newLen = symbol.length() - pos; std::string mangledName(symbol.substr(pos + 1, newLen)); - ret[i] = (stringEmpty(mangledName)) ? symbols.get()[i] : demangle(mangledName.c_str()); + retVec[i] = (stringEmpty(mangledName)) ? symbols[i] : demangle(mangledName.c_str()); } - return ret; + free(symbols); + return retVec; } #else -std::vector get_call_stack() { +std::vector get_call_stack() noexcept { return std::vector(); } #endif diff --git a/src/pke/examples/README.md b/src/pke/examples/README.md index 03e6d0746..988bde890 100644 --- a/src/pke/examples/README.md +++ b/src/pke/examples/README.md @@ -31,6 +31,7 @@ File Listing - [function-evaluation.cpp](function-evaluation.cpp): demonstrates the evaluation of a non-polynomial function using a Chebyshev approximation using CKKS - [polynomial-evaluation.cpp](polynomial-evaluation.cpp): demonstrates an evaluation of a polynomial (power series) using CKKS - [pre-buffer.cpp](pre-buffer.cpp): demonstrates use of OpenFHE for encryption, re-encryption and decryption of packed vector of binary data +- [pre-hra-secure.cpp](pre-hra-secure.cpp): shows examples of HRA-secure PRE based on BGV - [rotation.cpp](rotation.cpp): demonstrates use of EvalRotate for different schemes - [scheme-switching.cpp](scheme-switching.cpp): demonstrates several use cases for switching between CKKS and FHEW ciphertexts - [simple-ckks-bootstrapping.cpp](simple-ckks-bootstrapping.cpp): simple example showing CKKS bootstrapping for a ciphertext with full packing @@ -46,7 +47,7 @@ File Listing How To Link Your Own Project After Having OpenFHE Installed =================== 1. Check that you do not get error messages at the time of running "make install" for OpenFHE. You may need the admin rights to install. -2. Go to a new directory where you will keep “my_own_project.cpp” file. +2. Go to a new directory where you will keep "my_own_project.cpp" file. 3. Copy openfhe-development/CMakeLists.User.txt to the new directory and rename it to CMakeLists.txt. 4. Open CMakeLists.txt for editing and add a line to its end as suggested in the comments in CMakeLists.txt. Something like this: ``` @@ -110,68 +111,80 @@ Now your code should look like this: ........................................... ``` -## Description of the CryptoContext parameters +## Description of the CryptoContext parameters and their restrictions Choosing the CryptoContext parameters is important for obtaining the best performance for your encrypted application, while maintaining the desired level of security. We strongly recommend that you specify the security level and have OpenFHE automatically select the other parameters, unless you are an expert in homomorphic encryption. If you would like to modify the parameters to understand how they affect noise growth and performance, we provide descriptions below. The default values for all the parameters can be found in [gen-cryptocontext-params-defaults.h](../include/scheme/gen-cryptocontext-params-defaults.h) -**PlaintextModulus ptModulus** - plaintext modulus(for BGV/BFV), which impacts noise growth +If the set function is called for a parameter which is not available for the given scheme, then an exception will be thrown at run-time. -**usint digitSize** - for BV key switching only (when KeySwitchTechnique = BV). We use digit size in digit decomposition, which impacts noise growth +**PlaintextModulus ptModulus (BGV/BFV only)** - impacts noise growth and has to be set by user as it can not be zero. -**float standardDeviation** - used for Gaussian error generation +**uint32_t digitSize** - used in digit decomposition and impacts noise growth. + +**float standardDeviation** - error distribution parameter (recommended for advanced users), used for Gaussian error generation. **SecretKeyDist secretKeyDist** - secret key distribution: GAUSSIAN, UNIFORM_TERNARY, etc. -**usint maxRelinSkDeg** - max relinearization degree of secret key polynomial (used for lazy relinearization) +**uint32_t maxRelinSkDeg** - max relinearization degree of secret key polynomial (used for lazy relinearization). -**KeySwitchTechnique ksTech (BV or HYBRID currently)**: +**KeySwitchTechnique ksTech**: BV or HYBRID currently - For BV we do not have extra modulus, so the security depends on ciphertext modulus Q - For BV we need digitSize - digit size in digit decomposition -- For HYBRID we do have extra modulus P, so the security depends on modulus P*Q +- For HYBRID we do have an extra modulus P, so the security depends on modulus P*Q - For HYBRID we need numLargeDigits - number of digits in digit decomposition -**ScalingTechnique scalTech (for CKKS/BGV)** - rescaling/modulus switching technique FLEXIBLEAUTOEXT, FIXEDMANUAL, FLEXIBLEAUTO, etc. see https://eprint.iacr.org/2022/915 for additional details +**ScalingTechnique scalTech (CKKS/BGV only)** - rescaling/modulus switching technique: FIXEDMANUAL, FIXEDAUTO, FLEXIBLEAUTO, FLEXIBLEAUTOEXT. NORESCALE is not allowed (used for BFV internally). see https://eprint.iacr.org/2022/915 for additional details. + +**uint32_t batchSize** - max batch size of messages to be packed in encoding (number of slots). -**usint batchSize** - max batch size of messages to be packed in encoding (number of slots) +**ProxyReEncryptionMode PREMode** - PRE security mode IND-CPA, FIXED_NOISE_HRA. NOISE_FLOODING_HRA supported only in BGV for scaleTech=FIXEDMANUAL. -**ProxyReEncryptionMode PREMode** - PRE security mode IND-CPA, FIXED_NOISE_HRA, etc +**MultipartyMode multipartyMode (BFV/BGV only)** - multiparty security mode. The NOISE_FLOODING_MULTIPARTY mode adds extra noise and gives enhanced security compared to the FIXED_NOISE_MULTIPARTY mode. Not available for CKKS, but FIXED_NOISE_MULTIPARTY is used for CKKS internally -**MultipartyMode multipartyMode** - multiparty security mode in BFV/BGV. The NOISE_FLOODING_MULTIPARTY mode adds extra noise and gives enhanced security compared to the FIXED_NOISE_MULTIPARTY mode +**DecryptionNoiseMode decryptionNoiseMode (CKKS only)** - NOISE_FLOODING_DECRYPT mode is more secure (provable secure) than FIXED_NOISE_DECRYPT, but it requires executing all computations twice. -**DecryptionNoiseMode decryptionNoiseMode** - decryption noise mode in CKKS. NOISE_FLOODING_DECRYPT mode is more secure than FIXED_NOISE_DECRYPT, but it requires executing all computations twice +**ExecutionMode executionMode (CKKS only)** - The execution mode is only used in NOISE_FLOODING_DECRYPT mode: +- EXEC_NOISE_ESTIMATION - we estimate the noise we need to add to the actual computation to guarantee good security. +- EXEC_EVALUATION - we input our noise estimate and perform the desired secure encrypted computation. +- Although not available for BGV/BFV, EXEC_EVALUATION is used for these schemes internally. -**ExecutionMode executionMode** - execution mode in CKKS. The execution mode is only used in NOISE_FLOODING_DECRYPT mode: -- EXEC_NOISE_ESTIMATION - we estimate the noise we need to add to the actual computation to guarantee good security -- EXEC_EVALUATION - we input our noise estimate and perform the desired secure encrypted computation +**double noiseEstimate (CKKS only)** - This estimate is obtained from running the computation in EXEC_NOISE_ESTIMATION mode. It is only used in the NOISE_FLOODING_DECRYPT mode. -**double noiseEstimate** - noise estimate in CKKS. This estimate is obtained from running the computation in EXEC_NOISE_ESTIMATION mode. It is only used in NOISE_FLOODING_DECRYPT mode +**double desiredPrecision (CKKS only)** - desired precision for 128-bit CKKS. We use this value in NOISE_FLOODING_DECRYPT mode to determine the scaling factor. -**double desiredPrecision** - desired precision for 128-bit CKKS. We use this value in NOISE_FLOODING_DECRYPT mode to determine the scaling factor +**uint32_t statisticalSecurity (BGV/CKKS only)** - statistical security of CKKS in NOISE_FLOODING_DECRYPT mode. This is the bound on the probability of success that any adversary can have. Specifically, they have a probability of success of at most 2^(-statisticalSecurity). Used for BGV when PREMode=NOISE_FLOODING_HRA and for CKKS when multipartyMode=NOISE_FLOODING_MULTIPARTY. -**uint32_t statisticalSecurity** - statistical security of CKKS in NOISE_FLOODING_DECRYPT mode. This is the bound on the probability of success that any adversary can have. Specifically, they have a probability of success of at most 2^(-statisticalSecurity) +**uint32_t numAdversarialQueries (BGV/CKKS only)** - this is the number of adversarial queries a user is expecting for their application, which we use to ensure security of CKKS in NOISE_FLOODING_DECRYPT mode. Used for BGV when PREMode=NOISE_FLOODING_HRA and for CKKS when multipartyMode=NOISE_FLOODING_MULTIPARTY. -**uint32_t numAdversarialQueries** - this is the number of adversarial queries a user is expecting for their application, which we use to ensure security of CKKS in NOISE_FLOODING_DECRYPT mode +**uint32_t thresholdNumOfParties (BGV/BFV only)** - number of parties in a threshold application, which is used for the bound on the joint secret key. -**usint firstModSize and usint scalingModSize** - are used to calculate ciphertext modulus. The ciphertext modulus should be seen as: Q = q_0 * q_1 * ... * q_n * q': +**uint32_t firstModSize (CKKS/BGV only) and uint32_t scalingModSize** - are used to calculate ciphertext modulus. The ciphertext modulus should be seen as: Q = q_0 * q_1 * ... * q_n * q': - q_0 is first prime, and it's number of bits is firstModSize - q_i have same number of bits and is equal to scalingModSize - the prime q' is not explicitly given, but it is used internally in CKKS and BGV schemes (in *EXT scaling methods) +- **firstModSize** is allowed for BGV with **scalTech = FIXEDMANUAL** only +- **scalingModSize** is allowed for BGV with **scalTech = FIXEDMANUAL** and **scalingModSize** must be < 60 for CKKS and NATIVEINT=64. + +**uint32_t numLargeDigits** - number of digits in HYBRID key switching (see KeySwitchTechnique). -**usint numLargeDigits** - number of digits in HYBRID key switching (see KeySwitchTechnique) +**uint32_t multiplicativeDepth** - the maximum number of multiplications (in a binary tree manner) we can perform before bootstrapping. Must be 0 for BGV if PREMode=NOISE_FLOODING_HRA. -**usint multiplicativeDepth** - the maximum number of multiplication we can perform before bootstrapping +**SecurityLevel securityLevel** - We use the values from the security standard at http://homomorphicencryption.org/wp-content/uploads/2018/11/HomomorphicEncryptionStandardv1.1.pdf. Given the ring dimension and security level, we have upper bound of possible highest modulus (Q for BV or P*Q for HYBRID). -**SecurityLevel securityLevel** - We use the values from the security standard at http://homomorphicencryption.org/wp-content/uploads/2018/11/HomomorphicEncryptionStandardv1.1.pdf. For given ring dimension and security level we have upper bound of possible highest modulus (Q for BV or P*Q for HYBRID) +**uint32_t ringDim** - ring dimension N of the scheme : the ring is Z_Q[x] / (X^N+1) -**usint ringDim** - ring dimension N of the scheme : the ring is Z_Q[x] / (X^N+1) +**uint32_t evalAddCount (BGV/BFV only)** - maximum number of additions (used for setting noise). In BGV, it is the maximum number of additions at any level. -**usint evalAddCount** - number of additions (used for setting noise in BGV and BFV) +**EncryptionTechnique encryptionTechnique (BFV only)** - STANDARD or EXTENDED mode for BFV encryption; EXTENDED slightly reduces the size of Q (by few bits) but makes encryption somewhat slower (see https://eprint.iacr.org/2022/915 for details). Although not available for CKKS/BGV, STANDARD is used for these 2 schemes internally -**usint keySwitchCount** - number of key switching operations (used for setting noise in BGV and BFV) +**MultiplicationTechnique multiplicationTechnique (BFV only)** - multiplication method in BFV: BEHZ, HPS, HPSPOVERQ, HPSPOVERLEVELED (see https://eprint.iacr.org/2022/915 for details). -**usint multiHopModSize** - size of moduli used for PRE in the provable HRA setting +**uint32_t keySwitchCount (BGV/BFV only)** - maximum number of key switching operations (used for setting noise). -**EncryptionTechnique encryptionTechnique** - STANDARD or EXTENDED mode for BFV encryption; EXTENDED slightly reduces the size of Q (by few bits) but makes encryption somewhat slower (see https://eprint.iacr.org/2022/915 for details) +**uint32_t PRENumHops (BGV only)** - number of hops supported for PRE in the provable HRA setting: +- used only with multipartyMode=NOISE_FLOODING_MULTIPARTY +- if PREMode=NOISE_FLOODING_HRA, then **PRENumHops** must be > 0 -**MultiplicationTechnique multiplicationTechnique** - multiplication method in BFV: BEHZ, HPS, etc. (see https://eprint.iacr.org/2022/915 for details) +**COMPRESSION_LEVEL interactiveBootCompressionLevel (CKKS only)** - interactive multi-party bootstrapping parameter which sets the compression +level in ciphertext to SLACK (has weaker security assumption, thus less efficient) or COMPACT (has stronger security assumption, thus more efficient) diff --git a/src/pke/examples/pre-hra-secure.cpp b/src/pke/examples/pre-hra-secure.cpp new file mode 100644 index 000000000..dc7f32443 --- /dev/null +++ b/src/pke/examples/pre-hra-secure.cpp @@ -0,0 +1,267 @@ +//================================================================================== +// BSD 2-Clause License +// +// Copyright (c) 2014-2022, NJIT, Duality Technologies Inc. and other contributors +// +// All rights reserved. +// +// Author TPOC: contact@openfhe.org +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//================================================================================== + +/* + Example of HRA-secure Proxy Re-Encryption with 13 hops. + */ + +#define PROFILE // for TIC TOC +#include "openfhe.h" + +using namespace lbcrypto; + +using CT = Ciphertext; // ciphertext +using PT = Plaintext; // plaintext + +using vecInt = std::vector; // vector of ints +using vecChar = std::vector; // vector of characters + +bool run_demo_pre(void); + +int main(int argc, char* argv[]) { + //////////////////////////////////////////////////////////// + // Set-up of parameters + //////////////////////////////////////////////////////////// + + bool passed = run_demo_pre(); + + if (!passed) { // there could be an error + exit(1); + } + exit(0); // successful return +} + +bool run_demo_pre(void) { + // Generate parameters. + TimeVar t; // timer for tic toc + std::cout << "setting up the HRA-secure BGV PRE cryptosystem" << std::endl; + TIC(t); + + double t1; + + uint32_t plaintextModulus = 2; // can encode shorts + + uint32_t numHops = 13; + + CCParams parameters; + parameters.SetPlaintextModulus(plaintextModulus); + parameters.SetScalingTechnique(FIXEDMANUAL); + parameters.SetPRENumHops(numHops); + parameters.SetStatisticalSecurity(40); + parameters.SetNumAdversarialQueries(1048576); + parameters.SetRingDim(32768); + parameters.SetPREMode(NOISE_FLOODING_HRA); + parameters.SetKeySwitchTechnique(HYBRID); + parameters.SetMultiplicativeDepth(0); + // parameters.SetNumLargeDigits(3); + // parameters.SetKeySwitchTechnique(BV); + // parameters.SetDigitSize(15); + + CryptoContext cc = GenCryptoContext(parameters); + std::cout << "\nParam generation time: " + << "\t" << TOC_US(t) << " ms" << std::endl; + // Turn on features + cc->Enable(PKE); + cc->Enable(KEYSWITCH); + cc->Enable(LEVELEDSHE); + cc->Enable(PRE); + + std::cout << "p = " << cc->GetCryptoParameters()->GetPlaintextModulus() << std::endl; + std::cout << "n = " << cc->GetCryptoParameters()->GetElementParams()->GetCyclotomicOrder() / 2 << std::endl; + std::cout << "log2 q = " << log2(cc->GetCryptoParameters()->GetElementParams()->GetModulus().ConvertToDouble()) + << std::endl; + // std::cout << "crypto parameters = " << *cc->GetCryptoParameters() << std::endl; + const auto cryptoParamsBGV = std::dynamic_pointer_cast(cc->GetCryptoParameters()); + std::cout << "log QP = " << cryptoParamsBGV->GetParamsQP()->GetModulus().GetMSB() << std::endl; + // std::cout << "RNS parameters = " << *cryptoParamsBGV->GetParamsQP() << std::endl; + + auto ringsize = cc->GetRingDimension(); + std::cout << "Alice can encrypt " << ringsize / 8 << " bytes of data" << std::endl; + //////////////////////////////////////////////////////////// + // Perform Key Generation Operation + //////////////////////////////////////////////////////////// + + // Initialize Key Pair Containers + KeyPair keyPair1; + + std::cout << "\nRunning Alice key generation (used for source data)..." << std::endl; + + TIC(t); + keyPair1 = cc->KeyGen(); + t1 = TOC_US(t); + std::cout << "Key generation time: " + << "\t" << t1 / 1000.0 << " ms" << std::endl; + + if (!keyPair1.good()) { + std::cout << "Alice Key generation failed!" << std::endl; + return (false); + } + + //////////////////////////////////////////////////////////// + // Encode source data + //////////////////////////////////////////////////////////// + + unsigned int nshort = ringsize; + + vecInt vShorts; + + for (size_t i = 0; i < nshort; i++) + vShorts.push_back(std::rand() % plaintextModulus); + + PT pt = cc->MakeCoefPackedPlaintext(vShorts); + + //////////////////////////////////////////////////////////// + // Encryption + //////////////////////////////////////////////////////////// + + TIC(t); + auto ct1 = cc->Encrypt(keyPair1.publicKey, pt); + t1 = TOC_US(t); + std::cout << "Encryption time: " + << "\t" << t1 / 1000.0 << " ms" << std::endl; + + //////////////////////////////////////////////////////////// + // Decryption of Ciphertext + //////////////////////////////////////////////////////////// + + PT ptDec1; + + TIC(t); + cc->Decrypt(keyPair1.secretKey, ct1, &ptDec1); + t1 = TOC_US(t); + std::cout << "Decryption time: " + << "\t" << t1 / 1000.0 << " ms" << std::endl; + + ptDec1->SetLength(pt->GetLength()); + + //////////////////////////////////////////////////////////// + // Perform Key Generation Operation + //////////////////////////////////////////////////////////// + + // Initialize Key Pair Containers + std::vector> keyPairVector(numHops); + std::vector> reencryptionKeyVector(numHops); + + std::cout << "Generating keys for " << numHops << " parties" << std::endl; + + for (unsigned int i = 0; i < numHops; i++) { + TIC(t); + keyPairVector[i] = cc->KeyGen(); + t1 = TOC_US(t); + if (i == 1) + std::cout << "Key generation time: " + << "\t" << t1 / 1000.0 << " ms" << std::endl; + + if (!keyPairVector[i].good()) { + std::cout << "Bob Key generation failed!" << std::endl; + return (false); + } + + //////////////////////////////////////////////////////////// + // Perform the proxy re-encryption key generation operation. + // This generates the keys which are used to perform the key switching. + //////////////////////////////////////////////////////////// + if (i == 0) { + reencryptionKeyVector[i] = cc->ReKeyGen(keyPair1.secretKey, keyPairVector[i].publicKey); + } + else { + TIC(t); + reencryptionKeyVector[i] = cc->ReKeyGen(keyPairVector[i - 1].secretKey, keyPairVector[i].publicKey); + t1 = TOC_US(t); + if (i == 1) + std::cout << "Re-encryption key generation time: " + << "\t" << t1 / 1000.0 << " ms" << std::endl; + } + } + + //////////////////////////////////////////////////////////// + // Re-Encryption + //////////////////////////////////////////////////////////// + bool good = true; + for (unsigned int i = 0; i < numHops; i++) { + TIC(t); + ct1 = cc->ReEncrypt(ct1, reencryptionKeyVector[i]); + t1 = TOC_US(t); + std::cout << "Re-Encryption time at hop " << i + 1 << "\t" << t1 / 1000.0 << " ms" << std::endl; + + if (i < numHops - 1) + cc->ModReduceInPlace(ct1); + + //////////////////////////////////////////////////////////// + // Decryption of Ciphertext + //////////////////////////////////////////////////////////// + + PT ptDec2; + + TIC(t); + cc->Decrypt(keyPairVector[i].secretKey, ct1, &ptDec2); + t1 = TOC_US(t); + std::cout << "Decryption time: " + << "\t" << t1 / 1000.0 << " ms" << std::endl; + + ptDec2->SetLength(pt->GetLength()); + + auto unpacked0 = pt->GetCoefPackedValue(); + auto unpacked1 = ptDec1->GetCoefPackedValue(); + auto unpacked2 = ptDec2->GetCoefPackedValue(); + + // note that OpenFHE assumes that plaintext is in the range of -p/2..p/2 + // to recover 0...q simply add q if the unpacked value is negative + for (unsigned int j = 0; j < pt->GetLength(); j++) { + if (unpacked1[j] < 0) + unpacked1[j] += plaintextModulus; + if (unpacked2[j] < 0) + unpacked2[j] += plaintextModulus; + } + + // compare all the results for correctness + for (unsigned int j = 0; j < pt->GetLength(); j++) { + if ((unpacked0[j] != unpacked1[j]) || (unpacked0[j] != unpacked2[j])) { + // std::cout << j << ", " << unpacked0[j] << ", " << unpacked1[j] << ", " << unpacked2[j] << std::endl; + good = false; + } + } + if (good) { + std::cout << "PRE passes" << std::endl; + } + else { + std::cout << "PRE fails" << std::endl; + } + } + + //////////////////////////////////////////////////////////// + // Done + //////////////////////////////////////////////////////////// + + std::cout << "Execution Completed." << std::endl; + + return good; +} diff --git a/src/pke/examples/scheme-switching.cpp b/src/pke/examples/scheme-switching.cpp index 6f4fb4086..b964b7174 100644 --- a/src/pke/examples/scheme-switching.cpp +++ b/src/pke/examples/scheme-switching.cpp @@ -53,14 +53,14 @@ std::vector RotateInt(const std::vector&, int32_t); int main() { SwitchCKKSToFHEW(); SwitchFHEWtoCKKS(); - // FloorViaSchemeSwitching(); - // FuncViaSchemeSwitching(); - // PolyViaSchemeSwitching(); + FloorViaSchemeSwitching(); + FuncViaSchemeSwitching(); + PolyViaSchemeSwitching(); ComparisonViaSchemeSwitching(); ArgminViaSchemeSwitching(); ArgminViaSchemeSwitchingAlt(); - // ArgminViaSchemeSwitchingUnit(); - // ArgminViaSchemeSwitchingAltUnit(); + ArgminViaSchemeSwitchingUnit(); + ArgminViaSchemeSwitchingAltUnit(); return 0; } diff --git a/src/pke/examples/tckks-interactive-mp-bootstrapping-Chebyshev.cpp b/src/pke/examples/tckks-interactive-mp-bootstrapping-Chebyshev.cpp index df4007777..6d514fb2a 100644 --- a/src/pke/examples/tckks-interactive-mp-bootstrapping-Chebyshev.cpp +++ b/src/pke/examples/tckks-interactive-mp-bootstrapping-Chebyshev.cpp @@ -223,8 +223,9 @@ void TCKKSCollectiveBoot(enum ScalingTechnique scaleTech) { auto evalMultFinal2 = cryptoContext->MultiAddEvalMultKeys(evalMultABABC, evalMultCABC, evalMultCABC->GetKeyTag()); cryptoContext->InsertEvalMultKey({evalMultFinal2}); - auto evalSumKeysC = cryptoContext->MultiEvalSumKeyGen(kp3.secretKey, evalSumKeys, kp3.publicKey->GetKeyTag()); - auto evalSumKeysJoin2 = cryptoContext->MultiAddEvalSumKeys(evalSumKeys, evalSumKeysC, kp3.publicKey->GetKeyTag()); + auto evalSumKeysC = cryptoContext->MultiEvalSumKeyGen(kp3.secretKey, evalSumKeys, kp3.publicKey->GetKeyTag()); + auto evalSumKeysJoin2 = + cryptoContext->MultiAddEvalSumKeys(evalSumKeysJoin, evalSumKeysC, kp3.publicKey->GetKeyTag()); cryptoContext->InsertEvalSumKey(evalSumKeysJoin2); if (!kp1.good()) { diff --git a/src/pke/examples/threshold-fhe-5p.cpp b/src/pke/examples/threshold-fhe-5p.cpp index 1eef397b3..245156d9b 100644 --- a/src/pke/examples/threshold-fhe-5p.cpp +++ b/src/pke/examples/threshold-fhe-5p.cpp @@ -69,7 +69,6 @@ void RunBFVrns() { parameters.SetBatchSize(batchSize); parameters.SetDigitSize(digitSize); parameters.SetScalingModSize(dcrtBits); - parameters.SetThresholdNumOfParties(5); parameters.SetMultiplicationTechnique(HPSPOVERQLEVELED); CryptoContext cc = GenCryptoContext(parameters); diff --git a/src/pke/extras/bfv-encode-vs-ptxt-ctxt-benchmark.cpp.cpp b/src/pke/extras/bfv-encode-vs-ptxt-ctxt-benchmark.cpp.cpp new file mode 100644 index 000000000..22582e6e2 --- /dev/null +++ b/src/pke/extras/bfv-encode-vs-ptxt-ctxt-benchmark.cpp.cpp @@ -0,0 +1,126 @@ +//================================================================================== +// BSD 2-Clause License +// +// Copyright (c) 2014-2022, NJIT, Duality Technologies Inc. and other contributors +// +// All rights reserved. +// +// Author TPOC: contact@openfhe.org +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//================================================================================== + +/* + Compares the performance of BFV plaintext encode vs plaintext-ciphertext multiplication, + both are heavly used operations + */ + +#define PROFILE + +#include +#include +#include + +#include "openfhe.h" + +using namespace lbcrypto; + +int main() { + // Sample Program: Step 1: Set CryptoContext + CCParams parameters; + parameters.SetPlaintextModulus(65537); + parameters.SetMultiplicativeDepth(5); + parameters.SetSecurityLevel(HEStd_NotSet); + parameters.SetMultiplicationTechnique(HPSPOVERQLEVELED); + parameters.SetKeySwitchTechnique(BV); + parameters.SetRingDim((1 << 14)); + + CryptoContext cryptoContext = GenCryptoContext(parameters); + + std::cout << "Element parameters: \n" << *cryptoContext->GetElementParams() << "\n"; + + usint ringDim = cryptoContext->GetRingDimension(); + std::cout << "BFVrns scheme is using ring dimension " << ringDim << std::endl << std::endl; + + // Enable features that you wish to use + cryptoContext->Enable(PKE); + cryptoContext->Enable(KEYSWITCH); + cryptoContext->Enable(LEVELEDSHE); + + // Sample Program: Step 2: Key Generation + + // Initialize Public Key Containers + KeyPair keyPair; + + // Generate a public/private key pair + keyPair = cryptoContext->KeyGen(); + + // Sample Program: Step 3: Encryption + std::vector payload = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + // Second plaintext vector is encoded + std::vector payload2 = {3, 2, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + Plaintext ptxt2 = cryptoContext->MakePackedPlaintext(payload2, 1, 3); + + // Number of iterations for benchmarking + int numIterations = 1000; + + // Variables to store total times + TimeVar t; + double totalEncodeTime = 0.0; + double totalMultTime = 0.0; + + auto ctxtGT = cryptoContext->Encrypt(keyPair.publicKey, ptxt2); + + // Benchmark loop + for (int i = 0; i < numIterations; ++i) { + TIC(t); + Plaintext ptxt1 = cryptoContext->MakePackedPlaintext(payload, 1, 3); + totalEncodeTime += TOC_NS(t); + + auto ctxt2 = cryptoContext->Encrypt(keyPair.publicKey, ptxt2); + + TIC(t); + auto ctxtRes = cryptoContext->EvalMult(ctxt2, ptxt1); + totalMultTime += TOC_NS(t); + ctxtGT = ctxtRes; + } + + // Calculate and report average times + double avgEncodeTime = totalEncodeTime / numIterations / 1e6; + double avgMultTime = totalMultTime / numIterations / 1e6; + + // Average time to encode + std::cout << "encode took: " << avgEncodeTime << " ms" << std::endl; + // Average time to compute evalmult(ctxt, ptxt) + std::cout << "ptxt-ctxt took: " << avgMultTime << " ms" << std::endl; + + Plaintext plaintextMult; + cryptoContext->Decrypt(keyPair.secretKey, ctxtGT, &plaintextMult); + + plaintextMult->SetLength(payload.size()); + + // Output results + std::cout << "\nResults of homomorphic computations" << std::endl; + std::cout << "plaintextMult: " << plaintextMult << std::endl; + + return 0; +} diff --git a/src/pke/include/constants-defs.h b/src/pke/include/constants-defs.h new file mode 100644 index 000000000..1cef5594f --- /dev/null +++ b/src/pke/include/constants-defs.h @@ -0,0 +1,151 @@ +//================================================================================== +// BSD 2-Clause License +// +// Copyright (c) 2014-2024, NJIT, Duality Technologies Inc. and other contributors +// +// All rights reserved. +// +// Author TPOC: contact@openfhe.org +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//================================================================================== +#ifndef __CONSTANTS_DEFS_H__ +#define __CONSTANTS_DEFS_H__ + +#include "math/hal/basicint.h" // for MAX_MODULUS_SIZE + +namespace lbcrypto { + +/** + * @brief Lists all features supported by public key encryption schemes + */ +enum PKESchemeFeature { + PKE = 0x01, + KEYSWITCH = 0x02, + PRE = 0x04, + LEVELEDSHE = 0x08, + ADVANCEDSHE = 0x10, + MULTIPARTY = 0x20, + FHE = 0x40, + SCHEMESWITCH = 0x80, +}; + +enum ScalingTechnique { + FIXEDMANUAL = 0, + FIXEDAUTO, + FLEXIBLEAUTO, + FLEXIBLEAUTOEXT, + NORESCALE, + INVALID_RS_TECHNIQUE, // TODO (dsuponit): make this the first value +}; + +enum ProxyReEncryptionMode { + NOT_SET = 0, + INDCPA, + FIXED_NOISE_HRA, + NOISE_FLOODING_HRA, +}; + +enum MultipartyMode { + INVALID_MULTIPARTY_MODE = 0, + FIXED_NOISE_MULTIPARTY, + NOISE_FLOODING_MULTIPARTY, +}; + +enum ExecutionMode { + EXEC_EVALUATION = 0, + EXEC_NOISE_ESTIMATION, +}; + +enum DecryptionNoiseMode { + FIXED_NOISE_DECRYPT = 0, + NOISE_FLOODING_DECRYPT, +}; + +enum KeySwitchTechnique { + INVALID_KS_TECH = 0, + BV, + HYBRID, +}; + +enum EncryptionTechnique { + STANDARD = 0, + EXTENDED, +}; + +enum MultiplicationTechnique { + BEHZ = 0, + HPS, + HPSPOVERQ, + HPSPOVERQLEVELED, +}; + +enum PlaintextEncodings { + INVALID_ENCODING = 0, + COEF_PACKED_ENCODING, + PACKED_ENCODING, + STRING_ENCODING, + CKKS_PACKED_ENCODING, +}; + +enum LargeScalingFactorConstants { + MAX_BITS_IN_WORD = 61, + MAX_LOG_STEP = 60, +}; + +/** + * @brief BASE_NUM_LEVELS_TO_DROP is the most common value for levels/towers to drop (do not make it a default argument + * as default arguments work differently for virtual functions) + */ +// TODO (dsuponit): remove BASE_NUM_LEVELS_TO_DROP +enum { + BASE_NUM_LEVELS_TO_DROP = 1, +}; + +enum NoiseFlooding { + // noise flooding distribution parameter for distributed decryption in threshold FHE + MP_SD = 1048576, + // noise flooding distribution parameter for fixed 20 bits noise multihop PRE + PRE_SD = 1048576, + // number of additional moduli in NOISE_FLOODING_MULTIPARTY mode + NUM_MODULI_MULTIPARTY = 2, +// modulus size for additional moduli in NOISE_FLOODING_MULTIPARTY mode +#if NATIVEINT == 128 + MULTIPARTY_MOD_SIZE = 60, +#else + MULTIPARTY_MOD_SIZE = MAX_MODULUS_SIZE, +#endif +}; + +// Defining the level to which the input ciphertext is brought to before +// interactive multi-party bootstrapping +enum COMPRESSION_LEVEL { // TODO (dsuponit): change it to camel case + // we don't support 0 or 1 compression levels + // do not change values here + + COMPACT = 2, // more efficient with stronger security assumption + SLACK = 3 // less efficient with weaker security assumption +}; + +} // namespace lbcrypto + +#endif // __CONSTANTS_DEFS_H__ diff --git a/src/pke/include/constants.h b/src/pke/include/constants.h index 4549aac9a..92cca1376 100644 --- a/src/pke/include/constants.h +++ b/src/pke/include/constants.h @@ -28,159 +28,61 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //================================================================================== - +// This is a collection of helper functions for the enum definitions in constants-defs.h. +// constatns.h was split because of a request to provide a better compatability with +// the Rust wrapper for OpenFHE. #ifndef _CONSTANTS_H_ #define _CONSTANTS_H_ -// #include "math/hal/basicint.h" -#include "math/math-hal.h" -#include "lattice/constants-lattice.h" +#include "constants-defs.h" // all enum definitions +#include "lattice/constants-lattice.h" // additional definitions #include #include namespace lbcrypto { -/** - * @brief Lists all features supported by public key encryption schemes - */ -enum PKESchemeFeature { - PKE = 0x01, - KEYSWITCH = 0x02, - PRE = 0x04, - LEVELEDSHE = 0x08, - ADVANCEDSHE = 0x10, - MULTIPARTY = 0x20, - FHE = 0x40, - SCHEMESWITCH = 0x80, -}; +//====================================================================================================================== std::ostream& operator<<(std::ostream& s, PKESchemeFeature f); - -enum ScalingTechnique { - FIXEDMANUAL = 0, - FIXEDAUTO, - FLEXIBLEAUTO, - FLEXIBLEAUTOEXT, - NORESCALE, - INVALID_RS_TECHNIQUE, // TODO (dsuponit): make this the first value -}; +//====================================================================================================================== ScalingTechnique convertToScalingTechnique(const std::string& str); ScalingTechnique convertToScalingTechnique(uint32_t num); std::ostream& operator<<(std::ostream& s, ScalingTechnique t); - -enum ProxyReEncryptionMode { - NOT_SET = 0, - INDCPA, - FIXED_NOISE_HRA, - NOISE_FLOODING_HRA, - DIVIDE_AND_ROUND_HRA, -}; +//====================================================================================================================== ProxyReEncryptionMode convertToProxyReEncryptionMode(const std::string& str); ProxyReEncryptionMode convertToProxyReEncryptionMode(uint32_t num); std::ostream& operator<<(std::ostream& s, ProxyReEncryptionMode p); - -enum MultipartyMode { - INVALID_MULTIPARTY_MODE = 0, - FIXED_NOISE_MULTIPARTY, - NOISE_FLOODING_MULTIPARTY, -}; +//====================================================================================================================== MultipartyMode convertToMultipartyMode(const std::string& str); MultipartyMode convertToMultipartyMode(uint32_t num); std::ostream& operator<<(std::ostream& s, MultipartyMode t); - -enum ExecutionMode { - EXEC_EVALUATION = 0, - EXEC_NOISE_ESTIMATION, -}; +//====================================================================================================================== ExecutionMode convertToExecutionMode(const std::string& str); ExecutionMode convertToExecutionMode(uint32_t num); std::ostream& operator<<(std::ostream& s, ExecutionMode t); - -enum DecryptionNoiseMode { - FIXED_NOISE_DECRYPT = 0, - NOISE_FLOODING_DECRYPT, -}; +//====================================================================================================================== DecryptionNoiseMode convertToDecryptionNoiseMode(const std::string& str); DecryptionNoiseMode convertToDecryptionNoiseMode(uint32_t num); std::ostream& operator<<(std::ostream& s, DecryptionNoiseMode t); - -enum KeySwitchTechnique { - INVALID_KS_TECH = 0, - BV, - HYBRID, -}; +//====================================================================================================================== KeySwitchTechnique convertToKeySwitchTechnique(const std::string& str); KeySwitchTechnique convertToKeySwitchTechnique(uint32_t num); std::ostream& operator<<(std::ostream& s, KeySwitchTechnique t); - -enum EncryptionTechnique { - STANDARD = 0, - EXTENDED, -}; +//====================================================================================================================== EncryptionTechnique convertToEncryptionTechnique(const std::string& str); EncryptionTechnique convertToEncryptionTechnique(uint32_t num); std::ostream& operator<<(std::ostream& s, EncryptionTechnique t); - -enum MultiplicationTechnique { - BEHZ = 0, - HPS, - HPSPOVERQ, - HPSPOVERQLEVELED, -}; +//====================================================================================================================== MultiplicationTechnique convertToMultiplicationTechnique(const std::string& str); MultiplicationTechnique convertToMultiplicationTechnique(uint32_t num); std::ostream& operator<<(std::ostream& s, MultiplicationTechnique t); - -enum PlaintextEncodings { - INVALID_ENCODING = 0, - COEF_PACKED_ENCODING, - PACKED_ENCODING, - STRING_ENCODING, - CKKS_PACKED_ENCODING, -}; +//====================================================================================================================== std::ostream& operator<<(std::ostream& s, PlaintextEncodings p); - -enum LargeScalingFactorConstants { - MAX_BITS_IN_WORD = 61, - MAX_LOG_STEP = 60, -}; - -/** - * @brief BASE_NUM_LEVELS_TO_DROP is the most common value for levels/towers to drop (do not make it a default argument - * as default arguments work differently for virtual functions) - */ -// TODO (dsuponit): remove BASE_NUM_LEVELS_TO_DROP -enum { - BASE_NUM_LEVELS_TO_DROP = 1, -}; - -enum NOISE_FLOODING { - // noise flooding distribution parameter for distributed decryption in threshold FHE - MP_SD = 1048576, - // noise flooding distribution parameter for fixed 20 bits noise multihop PRE - PRE_SD = 1048576, - // number of additional moduli in NOISE_FLOODING_MULTIPARTY mode - NUM_MODULI_MULTIPARTY = 2, -// modulus size for additional moduli in NOISE_FLOODING_MULTIPARTY mode -#if NATIVEINT == 128 - MULTIPARTY_MOD_SIZE = 60, -#else - MULTIPARTY_MOD_SIZE = MAX_MODULUS_SIZE, -#endif -}; // namespace NOISE_FLOODING - -// Defining the level to which the input ciphertext is brought to before -// interactive multi-party bootstrapping -enum COMPRESSION_LEVEL { - // we don't support 0 or 1 compression levels - // do not change values here - - COMPACT = 2, // more efficient with stronger security assumption - SLACK = 3 // less efficient with weaker security assumption -}; +//====================================================================================================================== COMPRESSION_LEVEL convertToCompressionLevel(const std::string& str); COMPRESSION_LEVEL convertToCompressionLevel(uint32_t num); std::ostream& operator<<(std::ostream& s, COMPRESSION_LEVEL t); +//====================================================================================================================== } // namespace lbcrypto diff --git a/src/pke/include/cryptocontext-ser.h b/src/pke/include/cryptocontext-ser.h index 60a46572d..e19edec35 100644 --- a/src/pke/include/cryptocontext-ser.h +++ b/src/pke/include/cryptocontext-ser.h @@ -164,6 +164,20 @@ bool DeserializeFromFile(const std::string& filename, CryptoContext& obj, con } return false; } + +template +std::string SerializeToString(const CryptoContext& obj) { + std::stringstream s; + Serial::Serialize(obj, s, SerType::JSON); + return s.str(); +} + +template +void DeserializeFromString(CryptoContext& obj, const std::string& json) { + std::stringstream s; + s << json; + Serial::Deserialize(obj, s, SerType::JSON); +} } // namespace Serial template void Serial::Deserialize(std::shared_ptr>& obj, std::istream& stream, diff --git a/src/pke/include/cryptocontext.h b/src/pke/include/cryptocontext.h index ef5cfeb4a..4302a6a75 100644 --- a/src/pke/include/cryptocontext.h +++ b/src/pke/include/cryptocontext.h @@ -65,6 +65,7 @@ #include #include #include +#include namespace lbcrypto { @@ -211,52 +212,79 @@ class CryptoContextImpl : public Serializable { Plaintext MakePlaintext(const PlaintextEncodings encoding, const std::vector& value, size_t depth, uint32_t level) const { const auto cryptoParams = std::dynamic_pointer_cast(GetCryptoParameters()); + if (level > 0) { - if (getSchemeId() == SCHEME::BFVRNS_SCHEME) { - std::string errorMsg("The level value should be zero for BFVRNS_SCHEME. Currently: level is [" + - std::to_string(level) + "]"); - OPENFHE_THROW(errorMsg); - } - // validation of level: We need to compare it to multiplicativeDepth, but multiplicativeDepth is not - // readily available. so, what we get is numModuli and use it for calculations size_t numModuli = cryptoParams->GetElementParams()->GetParams().size(); - uint32_t multiplicativeDepth = - (cryptoParams->GetScalingTechnique() == FLEXIBLEAUTOEXT) ? (numModuli - 2) : (numModuli - 1); - // we throw an exception if level >= numModuli. however, we use multiplicativeDepth in the error message, - // so the user can understand the error more easily. - if (level >= numModuli) { - std::string errorMsg; - if (cryptoParams->GetScalingTechnique() == FLEXIBLEAUTOEXT) - errorMsg = "The level value should be less than or equal to (multiplicativeDepth + 1)."; - else - errorMsg = "The level value should be less than or equal to multiplicativeDepth."; + if (!isBFVRNS(m_schemeId)) { + // we throw an exception if level >= numModuli. However, we use multiplicativeDepth in the error message, + // so the user can understand the error more easily. + if (level >= numModuli) { + uint32_t multiplicativeDepth = + (cryptoParams->GetScalingTechnique() == FLEXIBLEAUTOEXT) ? (numModuli - 2) : (numModuli - 1); + std::string errorMsg; + if (cryptoParams->GetScalingTechnique() == FLEXIBLEAUTOEXT) + errorMsg = "The level value should be less than or equal to (multiplicativeDepth + 1)."; + else + errorMsg = "The level value should be less than or equal to multiplicativeDepth."; + + errorMsg += " Currently: level is [" + std::to_string(level) + "] and multiplicativeDepth is [" + + std::to_string(multiplicativeDepth) + "]"; + OPENFHE_THROW(errorMsg); + } + } + else { + if ((cryptoParams->GetMultiplicationTechnique() == BEHZ) || + (cryptoParams->GetMultiplicationTechnique() == HPS)) { + OPENFHE_THROW( + "BFV: Encoding at level > 0 is not currently supported for BEHZ or HPS. Use one of the HPSPOVERQ* methods instead."); + } - errorMsg += " Currently: level is [" + std::to_string(level) + "] and multiplicativeDepth is [" + - std::to_string(multiplicativeDepth) + "]"; - OPENFHE_THROW(errorMsg); + if ((cryptoParams->GetEncryptionTechnique() == EXTENDED)) { + OPENFHE_THROW( + "BFV: Encoding at level > 0 is not currently supported for the EXTENDED encryption method. Use the STANDARD encryption method instead."); + } + if (level >= numModuli) { + std::string errorMsg = + "The level value should be less the current number of RNS limbs in the cryptocontext."; + errorMsg += " Currently: level is [" + std::to_string(level) + "] and number of RNS limbs is [" + + std::to_string(numModuli) + "]"; + OPENFHE_THROW(errorMsg); + } } } + // uses a parameter set with a reduced number of RNS limbs corresponding to the level + std::shared_ptr> elemParamsPtr; + if (level != 0) { + ILDCRTParams elemParams = *(cryptoParams->GetElementParams()); + for (uint32_t i = 0; i < level; i++) { + elemParams.PopLastParam(); + } + elemParamsPtr = std::make_shared>(elemParams); + } + else { + elemParamsPtr = cryptoParams->GetElementParams(); + } + Plaintext p; - if (getSchemeId() == SCHEME::BGVRNS_SCHEME && (cryptoParams->GetScalingTechnique() == FLEXIBLEAUTO || - cryptoParams->GetScalingTechnique() == FLEXIBLEAUTOEXT)) { + if (isBGVRNS(m_schemeId) && (cryptoParams->GetScalingTechnique() == FLEXIBLEAUTO || + cryptoParams->GetScalingTechnique() == FLEXIBLEAUTOEXT)) { NativeInteger scf; if (cryptoParams->GetScalingTechnique() == FLEXIBLEAUTOEXT && level == 0) { scf = cryptoParams->GetScalingFactorIntBig(level); - p = PlaintextFactory::MakePlaintext(value, encoding, this->GetElementParams(), - this->GetEncodingParams(), getSchemeId(), 1, level, scf); + p = PlaintextFactory::MakePlaintext(value, encoding, elemParamsPtr, this->GetEncodingParams(), + getSchemeId(), 1, level, scf); p->SetNoiseScaleDeg(2); } else { scf = cryptoParams->GetScalingFactorInt(level); - p = PlaintextFactory::MakePlaintext(value, encoding, this->GetElementParams(), - this->GetEncodingParams(), getSchemeId(), depth, level, scf); + p = PlaintextFactory::MakePlaintext(value, encoding, elemParamsPtr, this->GetEncodingParams(), + getSchemeId(), depth, level, scf); } } else { - auto elementParams = this->GetElementParams(); - p = PlaintextFactory::MakePlaintext(value, encoding, elementParams, this->GetEncodingParams(), - getSchemeId()); + p = PlaintextFactory::MakePlaintext(value, encoding, elemParamsPtr, this->GetEncodingParams(), + getSchemeId(), depth, level); } return p; @@ -281,6 +309,32 @@ class CryptoContextImpl : public Serializable { value2); } + /** + * @brief Get indices that do not have automorphism keys for the given secret key tag in the key map + * @param keyID - secret key tag + * @param indexList - array of specific indices to check the key map against + * @return indices that do not have automorphism keys associated with + */ + static std::set GetEvalAutomorphismNoKeyIndices(const std::string& keyID, + const std::set& indices) { + std::set existingIndices{CryptoContextImpl::GetExistingEvalAutomorphismKeyIndices(keyID)}; + // if no index found for the given keyID, then the entire set "indices" is returned + return (existingIndices.empty()) ? indices : + CryptoContextImpl::GetUniqueValues(existingIndices, indices); + } + /** + * Get automorphism keys for a specific secret key tag + */ + static std::shared_ptr>> GetEvalAutomorphismKeyMapPtr(const std::string& keyID); + /** + * @brief Get automorphism keys for a specific secret key tag and an array of specific indices + * @param keyID - secret key tag + * @param indexList - array of specific indices to retrieve key for + * @return shared_ptr to std::map where the map key/data pair is index/automorphism key + */ + static std::shared_ptr>> GetPartialEvalAutomorphismKeyMapPtr( + const std::string& keyID, const std::vector& indexList); + // cached evalmult keys, by secret key UID static std::map>> s_evalMultKeyMap; // cached evalautomorphism keys, by secret key UID @@ -784,6 +838,65 @@ class CryptoContextImpl : public Serializable { return true; } + /** + * @brief Serialize automorphism keys for an array of specific indices within a specific secret key tag + * @param ser - stream to serialize to + * @param sertype - type of serialization + * @param keyID - secret key tag + * @param indexList - array of specific indices to serialize key for + * @return true on success + */ + template + static bool SerializeEvalAutomorphismKey(std::ostream& ser, const ST& sertype, const std::string& keyID, + const std::vector& indexList) { + std::map>>> keyMap = { + {keyID, CryptoContextImpl::GetPartialEvalAutomorphismKeyMapPtr(keyID, indexList)}}; + + Serial::Serialize(keyMap, ser, sertype); + return true; + } + + /** + * @brief Deserialize automorphism keys for an array of specific indices within a specific secret key tag + * @param ser - stream to serialize from + * @param sertype - type of serialization + * @param keyID - secret key tag + * @param indexList - array of specific indices to serialize key for + * @return true on success + */ + template + static bool DeserializeEvalAutomorphismKey(std::ostream& ser, const ST& sertype, const std::string& keyID, + const std::vector& indexList) { + if (!indexList.size()) + OPENFHE_THROW("indexList may not be empty"); + if (keyID.empty()) + OPENFHE_THROW("keyID may not be empty"); + + std::map>>> allDeserKeys; + Serial::Deserialize(allDeserKeys, ser, sertype); + + const auto& keyMapIt = allDeserKeys.find(keyID); + if (keyMapIt == allDeserKeys.end()) { + OPENFHE_THROW("Deserialized automorphism keys are not generated for ID [" + keyID + "]."); + } + + // create a new map with evalkeys for the specified indices + std::map> newMap; + for (const uint32_t indx : indexList) { + const auto& key = keyMapIt->find(indx); + if (key == keyMapIt->end()) { + OPENFHE_THROW("No automorphism key generated for index [" + std::to_string(indx) + "] within keyID [" + + keyID + "]."); + } + newMap[indx] = key->second; + } + + CryptoContextImpl::InsertEvalAutomorphismKey( + std::make_shared>>(newMap), keyID); + + return true; + } + /** * DeserializeEvalAutomorphismKey deserialize all keys in the serialization * deserialized keys silently replace any existing matching keys @@ -957,12 +1070,9 @@ class CryptoContextImpl : public Serializable { /** * Get automorphism keys for a specific secret key tag */ - static std::shared_ptr>> GetEvalAutomorphismKeyMapPtr(const std::string& keyID); - static std::map>& GetEvalAutomorphismKeyMap(const std::string& keyID) { return *(CryptoContextImpl::GetEvalAutomorphismKeyMapPtr(keyID)); } - /** * Get a map of summation keys (each is composed of several automorphism keys) for all secret keys */ @@ -1079,7 +1189,7 @@ class CryptoContextImpl : public Serializable { * KeyGen generates a key pair using this algorithm's KeyGen method * @return a public/secret key pair */ - KeyPair KeyGen() { + KeyPair KeyGen() const { return GetScheme()->KeyGen(GetContextForPointer(this), false); } @@ -1089,7 +1199,7 @@ class CryptoContextImpl : public Serializable { * entropy, for use in special cases like Ring Reduction * @return a public/secret key pair */ - KeyPair SparseKeyGen() { + KeyPair SparseKeyGen() const { return GetScheme()->KeyGen(GetContextForPointer(this), true); } @@ -1926,8 +2036,15 @@ class CryptoContextImpl : public Serializable { if (!indexList.size()) OPENFHE_THROW("Input index vector is empty"); - auto evalKeys = GetScheme()->EvalAutomorphismKeyGen(privateKey, indexList); + // Do not generate duplicate keys that have been already generated and added to the static storage (map) + std::set allIndices(indexList.begin(), indexList.end()); + std::set indicesToGenerate{ + CryptoContextImpl::GetEvalAutomorphismNoKeyIndices(privateKey->GetKeyTag(), allIndices)}; + + std::vector newIndices(indicesToGenerate.begin(), indicesToGenerate.end()); + auto evalKeys = GetScheme()->EvalAutomorphismKeyGen(privateKey, newIndices); CryptoContextImpl::InsertEvalAutomorphismKey(evalKeys, privateKey->GetKeyTag()); + return evalKeys; } @@ -1946,8 +2063,7 @@ class CryptoContextImpl : public Serializable { * * @param ciphertext the input ciphertext. * @param i automorphism index - * @param &evalKeys - reference to the vector of evaluation keys generated by - * EvalAutomorphismKeyGen. + * @param &evalKeys - reference to the vector of evaluation keys generated by EvalAutomorphismKeyGen. * @return resulting ciphertext */ Ciphertext EvalAutomorphism(ConstCiphertext ciphertext, usint i, @@ -2675,13 +2791,13 @@ class CryptoContextImpl : public Serializable { * encoding * * @param ciphertext the input ciphertext. - * @param rowSize size of rows in the matrix + * @param numRows number of rows in the matrix * @param &evalSumKeyMap - reference to the map of evaluation keys generated by * @param subringDim the current cyclotomic order/subring dimension. If set to * 0, we use the full cyclotomic order. * @return resulting ciphertext */ - Ciphertext EvalSumRows(ConstCiphertext ciphertext, usint rowSize, + Ciphertext EvalSumRows(ConstCiphertext ciphertext, usint numRows, const std::map>& evalSumKeyMap, usint subringDim = 0) const; /** @@ -2689,11 +2805,11 @@ class CryptoContextImpl : public Serializable { * encoding * * @param ciphertext the input ciphertext. - * @param rowSize size of rows in the matrix + * @param numCols number of columns in the matrix * @param &evalSumKeyMap - reference to the map of evaluation keys generated by * @return resulting ciphertext */ - Ciphertext EvalSumCols(ConstCiphertext ciphertext, usint rowSize, + Ciphertext EvalSumCols(ConstCiphertext ciphertext, usint numCols, const std::map>& evalSumKeyMap) const; //------------------------------------------------------------------------------ @@ -3536,15 +3652,15 @@ class CryptoContextImpl : public Serializable { * @param keyTag map search id for the automorphism keys * @return vector with all indices in the map. if nothing is found for the given keyTag, then the vector is empty **/ - static std::vector GetExistingEvalAutomorphismKeyIndices(const std::string& keyTag); + static std::set GetExistingEvalAutomorphismKeyIndices(const std::string& keyTag); /** - * @brief GetUniqueValues compares 2 vectors to generate a vector with unique values from the 2nd vector - * @param oldValues vector of integers to compare against (passed by value) - * @param newValues vector of integers to find unique values from (passed by value) - * @return vector with unique values from newValues + * @brief GetUniqueValues compares 2 sets to generate a set with unique values from the 2nd set + * @param oldValues set of integers to compare against (passed by value) + * @param newValues set of integers to find unique values from (passed by value) + * @return set with the unique values from newValues **/ - static std::vector GetUniqueValues(std::vector oldValues, std::vector newValues); + static std::set GetUniqueValues(const std::set& oldValues, const std::set& newValues); template void save(Archive& ar, std::uint32_t const version) const { diff --git a/src/pke/include/encoding/ckkspackedencoding.h b/src/pke/include/encoding/ckkspackedencoding.h index f459a8e9c..cd30788e1 100644 --- a/src/pke/include/encoding/ckkspackedencoding.h +++ b/src/pke/include/encoding/ckkspackedencoding.h @@ -141,19 +141,19 @@ class CKKSPackedEncoding : public PlaintextImpl { CKKSPackedEncoding(CKKSPackedEncoding&& rhs) : PlaintextImpl(std::move(rhs)), value(std::move(rhs.value)), m_logError(rhs.m_logError) {} - bool Encode(); + bool Encode() override; - bool Decode() { + bool Decode() override { OPENFHE_THROW("CKKSPackedEncoding::Decode() is not implemented. Use CKKSPackedEncoding::Decode(...) instead."); } bool Decode(size_t depth, double scalingFactor, ScalingTechnique scalTech, ExecutionMode executionMode); - const std::vector>& GetCKKSPackedValue() const { + const std::vector>& GetCKKSPackedValue() const override { return value; } - const std::vector GetRealPackedValue() const { + std::vector GetRealPackedValue() const override { std::vector realValue(value.size()); std::transform(value.begin(), value.end(), realValue.begin(), [](std::complex da) { return da.real(); }); @@ -179,7 +179,7 @@ class CKKSPackedEncoding : public PlaintextImpl { * GetEncodingType * @return CKKS_PACKED_ENCODING */ - PlaintextEncodings GetEncodingType() const { + PlaintextEncodings GetEncodingType() const override { return CKKS_PACKED_ENCODING; } @@ -188,7 +188,7 @@ class CKKSPackedEncoding : public PlaintextImpl { * * @return the length of the plaintext in terms of the number of bits. */ - size_t GetLength() const { + size_t GetLength() const override { return value.size(); } @@ -196,14 +196,14 @@ class CKKSPackedEncoding : public PlaintextImpl { * Get method to return log2 of estimated standard deviation of approximation * error */ - double GetLogError() const { + double GetLogError() const override { return m_logError; } /** * Get method to return log2 of estimated precision */ - double GetLogPrecision() const { + double GetLogPrecision() const override { return encodingParams->GetPlaintextModulus() - m_logError; } @@ -211,7 +211,7 @@ class CKKSPackedEncoding : public PlaintextImpl { * SetLength of the plaintext to the given size * @param siz */ - void SetLength(size_t siz) { + void SetLength(size_t siz) override { value.resize(siz); } @@ -222,7 +222,7 @@ class CKKSPackedEncoding : public PlaintextImpl { * @param other - the other plaintext to compare to. * @return whether the two plaintext are equivalent. */ - bool CompareTo(const PlaintextImpl& other) const { + bool CompareTo(const PlaintextImpl& other) const override { const auto& rv = static_cast(other); return this->value == rv.value; } @@ -232,7 +232,7 @@ class CKKSPackedEncoding : public PlaintextImpl { */ static void Destroy(); - void PrintValue(std::ostream& out) const { + void PrintValue(std::ostream& out) const override { // for sanity's sake, trailing zeros get elided into "..." // out.precision(15); out << "("; diff --git a/src/pke/include/encoding/packedencoding.h b/src/pke/include/encoding/packedencoding.h index 8a8854064..97a02c4a0 100644 --- a/src/pke/include/encoding/packedencoding.h +++ b/src/pke/include/encoding/packedencoding.h @@ -224,6 +224,9 @@ class PackedEncoding : public PlaintextImpl { template void Pack(P* ring, const PlaintextModulus& modulus) const; + // Optimized version of packing designed for DCRTPoly and NativePoly + void PackNativeVector(const PlaintextModulus& modulus, uint32_t m, NativeVector* values) const; + /** * @brief Unpacks the data from aggregated plaintext to slot values. * diff --git a/src/pke/include/encoding/plaintext.h b/src/pke/include/encoding/plaintext.h index c02a6bec8..4b48ad022 100644 --- a/src/pke/include/encoding/plaintext.h +++ b/src/pke/include/encoding/plaintext.h @@ -363,7 +363,7 @@ class PlaintextImpl { virtual const std::vector>& GetCKKSPackedValue() const { OPENFHE_THROW("not a packed vector of complex numbers"); } - virtual const std::vector GetRealPackedValue() const { + virtual std::vector GetRealPackedValue() const { OPENFHE_THROW("not a packed vector of real numbers"); } virtual void SetStringValue(const std::string&) { diff --git a/src/pke/include/encoding/plaintextfactory.h b/src/pke/include/encoding/plaintextfactory.h index 7c55788c3..b3dc1b325 100644 --- a/src/pke/include/encoding/plaintextfactory.h +++ b/src/pke/include/encoding/plaintextfactory.h @@ -82,7 +82,7 @@ class PlaintextFactory { // Check if plaintext has got enough slots for data (value) usint ringDim = vp->GetRingDimension(); size_t valueSize = value.size(); - if (SCHEME::CKKSRNS_SCHEME == schemeID && valueSize > ringDim / 2) { + if (isCKKS(schemeID) && valueSize > ringDim / 2) { OPENFHE_THROW("The size [" + std::to_string(valueSize) + "] of the vector with values should not be greater than ringDim/2 [" + std::to_string(ringDim / 2) + "] if the scheme is CKKS"); @@ -111,7 +111,7 @@ class PlaintextFactory { // Check if plaintext has got enough slots for data (value) usint ringDim = vp->GetRingDimension(); size_t valueSize = value.size(); - if (SCHEME::CKKSRNS_SCHEME == schemeID && valueSize > ringDim / 2) { + if (isCKKS(schemeID) && valueSize > ringDim / 2) { OPENFHE_THROW("The size [" + std::to_string(valueSize) + "] of the vector with values should not be greater than ringDim/2 [" + std::to_string(ringDim / 2) + "] if the scheme is CKKS"); diff --git a/src/pke/include/gen-cryptocontext.h b/src/pke/include/gen-cryptocontext.h index cf365706b..1201b7a1e 100644 --- a/src/pke/include/gen-cryptocontext.h +++ b/src/pke/include/gen-cryptocontext.h @@ -35,7 +35,7 @@ /* * HOW TO GENERATE CRYPTOCONTEXT BY CALLING GenCryptoContext() -* +* * 1. Pick the scheme you want to use. I choose CKKS for our tutorial example. * 2. Your code must include this header file and the header with the scheme-specific * context generator (scheme//cryptocontext-.h): @@ -53,7 +53,7 @@ * 4. Adjust the parameters' values with set functions for CCParams> as * the object is created using default values from scheme/cryptocontextparams-defaults.h. * 5. Call GenCryptoContext() to generate cryptocontext. -* +* * Now your code should look like this: * #include "scheme/ckks/cryptocontext-ckks.h" * #include "gen-cryptocontext.h" @@ -64,14 +64,14 @@ * parameters.SetBatchSize(8); * parameters.SetSecurityLevel(HEStd_NotSet); * parameters.SetRingDim(16); -* +* * auto cryptoContext = GenCryptoContext(parameters); -* +* * cryptoContext->Enable(ENCRYPTION); * cryptoContext->Enable(KEYSWITCH); * cryptoContext->Enable(LEVELEDSHE); * ........................................... -* +* * More examples can be found in src/pke/unittest/UnitTestAutomorphism.cpp or in * src/pke/unittest/UnitTestEvalMult.cpp. */ diff --git a/src/pke/include/key/keypair.h b/src/pke/include/key/keypair.h index 2c60f07e7..25a68318e 100644 --- a/src/pke/include/key/keypair.h +++ b/src/pke/include/key/keypair.h @@ -52,9 +52,13 @@ class KeyPair { explicit KeyPair(PublicKeyImpl* a = nullptr, PrivateKeyImpl* b = nullptr) : publicKey(a), secretKey(b) {} - bool good() { + bool good() const { return publicKey && secretKey; } + + bool is_allocated() const { + return good(); + } }; } // namespace lbcrypto diff --git a/src/pke/include/scheme/bfvrns/bfvrns-pke.h b/src/pke/include/scheme/bfvrns/bfvrns-pke.h index 3e3c6ab63..f72f76f77 100644 --- a/src/pke/include/scheme/bfvrns/bfvrns-pke.h +++ b/src/pke/include/scheme/bfvrns/bfvrns-pke.h @@ -52,7 +52,7 @@ class PKEBFVRNS : public PKERNS { public: virtual ~PKEBFVRNS() {} - KeyPair KeyGenInternal(CryptoContext cc, bool makeSparse) override; + KeyPair KeyGenInternal(CryptoContext cc, bool makeSparse) const override; /** * Method for encrypting plaintext using LBC diff --git a/src/pke/include/scheme/bfvrns/bfvrns-ser.h b/src/pke/include/scheme/bfvrns/bfvrns-ser.h index eb276f182..6dae14fd9 100644 --- a/src/pke/include/scheme/bfvrns/bfvrns-ser.h +++ b/src/pke/include/scheme/bfvrns/bfvrns-ser.h @@ -41,7 +41,9 @@ CEREAL_REGISTER_TYPE(lbcrypto::CryptoParametersBFVRNS); CEREAL_REGISTER_TYPE(lbcrypto::SchemeBFVRNS); +CEREAL_REGISTER_TYPE(lbcrypto::FHEBFVRNS); CEREAL_REGISTER_POLYMORPHIC_RELATION(lbcrypto::CryptoParametersRNS, lbcrypto::CryptoParametersBFVRNS); +CEREAL_REGISTER_POLYMORPHIC_RELATION(lbcrypto::FHERNS, lbcrypto::FHEBFVRNS); #endif diff --git a/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h b/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h index 8295f8f5e..afb05cb8f 100644 --- a/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h +++ b/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns-params.h @@ -58,6 +58,40 @@ class CCParams : public Params { explicit CCParams(const std::vector& vals) : Params(vals) {} CCParams(const CCParams& obj) = default; CCParams(CCParams&& obj) = default; + + //================================================================================================================ + // DISABLE FUNCTIONS that are not applicable to BFVRNS + //================================================================================================================ + void SetScalingTechnique(ScalingTechnique scalTech0) override { + DISABLED_FOR_BFVRNS; + } + void SetFirstModSize(uint32_t firstModSize0) override { + DISABLED_FOR_BFVRNS; + } + void SetPRENumHops(uint32_t PRENumHops0) override { + DISABLED_FOR_BFVRNS; + } + void SetExecutionMode(ExecutionMode executionMode0) override { + DISABLED_FOR_BGVRNS; + } + void SetDecryptionNoiseMode(DecryptionNoiseMode decryptionNoiseMode0) override { + DISABLED_FOR_BFVRNS; + } + void SetNoiseEstimate(double noiseEstimate0) override { + DISABLED_FOR_BFVRNS; + } + void SetDesiredPrecision(double desiredPrecision0) override { + DISABLED_FOR_BFVRNS; + } + void SetStatisticalSecurity(uint32_t statisticalSecurity0) override { + DISABLED_FOR_BFVRNS; + } + void SetNumAdversarialQueries(uint32_t numAdversarialQueries0) override { + DISABLED_FOR_BFVRNS; + } + void SetInteractiveBootCompressionLevel(COMPRESSION_LEVEL interactiveBootCompressionLevel0) override { + DISABLED_FOR_BFVRNS; + } }; //==================================================================================================================== diff --git a/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns.h b/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns.h index c38a01404..7e10107ca 100644 --- a/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns.h +++ b/src/pke/include/scheme/bfvrns/gen-cryptocontext-bfvrns.h @@ -40,6 +40,7 @@ #include "scheme/bfvrns/gen-cryptocontext-bfvrns-params.h" #include "scheme/bfvrns/bfvrns-scheme.h" #include "scheme/bfvrns/bfvrns-cryptoparameters.h" +#include "scheme/gen-cryptocontext-params-validation.h" #include "cryptocontext-fwd.h" #include "lattice/lat-hal.h" @@ -58,6 +59,7 @@ class CryptoContextBFVRNS { using CryptoParams = CryptoParametersBFVRNS; static CryptoContext genCryptoContext(const CCParams& parameters) { + validateParametersForCryptocontext(parameters); return genCryptoContextBFVRNSInternal(parameters); } }; diff --git a/src/pke/include/scheme/bgvrns/bgvrns-parametergeneration.h b/src/pke/include/scheme/bgvrns/bgvrns-parametergeneration.h index e1c491bd6..ade5044ee 100644 --- a/src/pke/include/scheme/bgvrns/bgvrns-parametergeneration.h +++ b/src/pke/include/scheme/bgvrns/bgvrns-parametergeneration.h @@ -57,17 +57,16 @@ namespace lbcrypto { * @param noisePerLevel is the noise we wish to maintain at each level */ struct BGVNoiseEstimates { - const double Berr; - const double Bkey; - const double expansionFactor; - const double freshEncryptionNoise; - const double keySwitchingNoise; - const double modSwitchingNoise; - const double noisePerLevel; - - BGVNoiseEstimates(const double Berr0, const double Bkey0, const double expansionFactor0, - const double freshEncryptionNoise0, const double keySwitchingNoise0, - const double modSwitchingNoise0, double noisePerLevel0) + double Berr; + double Bkey; + double expansionFactor; + double freshEncryptionNoise; + double keySwitchingNoise; + double modSwitchingNoise; + double noisePerLevel; + + BGVNoiseEstimates(double Berr0, double Bkey0, double expansionFactor0, double freshEncryptionNoise0, + double keySwitchingNoise0, double modSwitchingNoise0, double noisePerLevel0) : Berr(Berr0), Bkey(Bkey0), expansionFactor(expansionFactor0), @@ -92,12 +91,12 @@ class ParameterGenerationBGVRNS : public ParameterGenerationRNS { * @param firstModSize is the approximate bit size of the first CRT modulus. * @param dcrtBits is the approximate bit size of the remaining CRT moduli. * @param numPartQ - * @param multihopQBound + * @param numHops numbers of hops for HRA-secure PRE * @return A boolean. */ bool ParamsGenBGVRNS(std::shared_ptr> cryptoParams, uint32_t evalAddCount, - uint32_t keySwitchCount, usint cyclOrder, usint numPrimes, usint firstModSize, usint dcrtBits, - uint32_t numPartQ, usint multihopQBound) const override; + uint32_t keySwitchCount, uint32_t cyclOrder, uint32_t numPrimes, uint32_t firstModSize, + uint32_t dcrtBits, uint32_t numPartQ, uint32_t numHops) const override; ///////////////////////////////////// // SERIALIZATION @@ -122,12 +121,12 @@ class ParameterGenerationBGVRNS : public ParameterGenerationRNS { * @param cyclOrder is the cyclotomic order, which is twice the ring dimension. * @return The ring dimension. */ - uint32_t computeRingDimension(std::shared_ptr> cryptoParams, uint32_t qBound, - usint cyclOrder) const; + uint32_t computeRingDimension(const std::shared_ptr>& cryptoParams, uint32_t qBound, + uint32_t cyclOrder) const; - BGVNoiseEstimates computeNoiseEstimates(std::shared_ptr> cryptoParams, + BGVNoiseEstimates computeNoiseEstimates(const std::shared_ptr>& cryptoParams, uint32_t ringDimension, uint32_t evalAddCount, uint32_t keySwitchCount, - uint32_t auxBits, usint numPrimes) const; + uint32_t auxTowers, uint32_t numPrimes) const; uint64_t getCyclicOrder(const uint32_t ringDimension, const int plainModulus, const ScalingTechnique scalTech) const; @@ -139,21 +138,23 @@ class ParameterGenerationBGVRNS : public ParameterGenerationRNS { * @param ringDimension is the dimension of the ring (n) * @param evalAddCount is the maximum number of additions per level. * @param keySwitchCount is the maximum number of key switches per level. - * @param auxBits is the size of the additional modulus P, used for hybrid key-switching. + * @param auxTowers is the number of RNS limbs in the additional modulus P, used for hybrid key-switching. * @param numPrimes Number of CRT moduli. * @return A pair containing: 1) a vector with the CRT moduli and 2) the total modulus size to be used for ensuring security compliance. */ std::pair, uint32_t> computeModuli( - std::shared_ptr> cryptoParams, uint32_t ringDimension, uint32_t evalAddCount, - uint32_t keySwitchCount, uint32_t auxBits, usint numPrimes) const; + const std::shared_ptr>& cryptoParams, uint32_t ringDimension, + uint32_t evalAddCount, uint32_t keySwitchCount, uint32_t auxTowers, uint32_t numPrimes) const; /* * Method that initializes the Discrete Gaussian Generator with flooding for PRE. * * @param cryptoParams contains parameters input by the user * @param numPrimes Number of CRT moduli. + * @param ringDimension ring dimension. */ - void InitializeFloodingDgg(std::shared_ptr> cryptoParams, usint numPrimes) const; + void InitializeFloodingDgg(const std::shared_ptr>& cryptoParams, uint32_t numPrimes, + uint32_t ringDimension) const; }; } // namespace lbcrypto diff --git a/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-internal.h b/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-internal.h index 59c8d3b81..97056c477 100644 --- a/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-internal.h +++ b/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-internal.h @@ -84,8 +84,9 @@ typename ContextGeneratorType::ContextType genCryptoContextBGVRNSInternal( // for BGV scheme noise scale is always set to plaintext modulus params->SetNoiseScale(parameters.GetPlaintextModulus()); - uint32_t numLargeDigits = - ComputeNumLargeDigits(parameters.GetNumLargeDigits(), parameters.GetMultiplicativeDepth()); + auto numLargeDigits = (parameters.GetMultiplicativeDepth() == 0) ? + ComputeNumLargeDigitsPRE(parameters.GetNumLargeDigits(), parameters.GetPRENumHops()) : + ComputeNumLargeDigits(parameters.GetNumLargeDigits(), parameters.GetMultiplicativeDepth()); auto scheme = std::make_shared(); scheme->SetKeySwitchingTechnique(parameters.GetKeySwitchTechnique()); @@ -98,7 +99,7 @@ typename ContextGeneratorType::ContextType genCryptoContextBGVRNSInternal( parameters.GetFirstModSize(), parameters.GetScalingModSize(), numLargeDigits, - parameters.GetMultiHopModSize()); + parameters.GetPRENumHops()); // clang-format on auto cc = ContextGeneratorType::Factory::GetContext(params, scheme); diff --git a/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h b/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h index 20eeb3639..de286b719 100644 --- a/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h +++ b/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns-params.h @@ -58,6 +58,31 @@ class CCParams : public Params { explicit CCParams(const std::vector& vals) : Params(vals) {} CCParams(const CCParams& obj) = default; CCParams(CCParams&& obj) = default; + + //================================================================================================================ + // DISABLE FUNCTIONS that are not applicable to BGVRNS + //================================================================================================================ + void SetEncryptionTechnique(EncryptionTechnique encryptionTechnique0) override { + DISABLED_FOR_BGVRNS; + } + void SetMultiplicationTechnique(MultiplicationTechnique multiplicationTechnique0) override { + DISABLED_FOR_BGVRNS; + } + void SetExecutionMode(ExecutionMode executionMode0) override { + DISABLED_FOR_BGVRNS; + } + void SetDecryptionNoiseMode(DecryptionNoiseMode decryptionNoiseMode0) override { + DISABLED_FOR_BGVRNS; + } + void SetNoiseEstimate(double noiseEstimate0) override { + DISABLED_FOR_BGVRNS; + } + void SetDesiredPrecision(double desiredPrecision0) override { + DISABLED_FOR_BGVRNS; + } + void SetInteractiveBootCompressionLevel(COMPRESSION_LEVEL interactiveBootCompressionLevel0) override { + DISABLED_FOR_BGVRNS; + } }; //==================================================================================================================== diff --git a/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns.h b/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns.h index 453169624..7277b97be 100644 --- a/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns.h +++ b/src/pke/include/scheme/bgvrns/gen-cryptocontext-bgvrns.h @@ -40,6 +40,7 @@ #include "scheme/bgvrns/gen-cryptocontext-bgvrns-params.h" #include "scheme/bgvrns/bgvrns-scheme.h" #include "scheme/bgvrns/bgvrns-cryptoparameters.h" +#include "scheme/gen-cryptocontext-params-validation.h" #include "cryptocontext-fwd.h" #include "lattice/lat-hal.h" @@ -58,6 +59,7 @@ class CryptoContextBGVRNS { using CryptoParams = CryptoParametersBGVRNS; static CryptoContext genCryptoContext(const CCParams& parameters) { + validateParametersForCryptocontext(parameters); return genCryptoContextBGVRNSInternal(parameters); } }; diff --git a/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-params.h b/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-params.h index eb057de34..396d777a1 100644 --- a/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-params.h +++ b/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns-params.h @@ -58,6 +58,34 @@ class CCParams : public Params { explicit CCParams(const std::vector& vals) : Params(vals) {} CCParams(const CCParams& obj) = default; CCParams(CCParams&& obj) = default; + + //================================================================================================================ + // DISABLE FUNCTIONS that are not applicable to CKKSRNS + //================================================================================================================ + void SetPlaintextModulus(PlaintextModulus ptModulus0) override { + DISABLED_FOR_CKKSRNS; + } + void SetEvalAddCount(uint32_t evalAddCount0) override { + DISABLED_FOR_CKKSRNS; + } + void SetKeySwitchCount(uint32_t keySwitchCount0) override { + DISABLED_FOR_CKKSRNS; + } + void SetEncryptionTechnique(EncryptionTechnique encryptionTechnique0) override { + DISABLED_FOR_CKKSRNS; + } + void SetMultiplicationTechnique(MultiplicationTechnique multiplicationTechnique0) override { + DISABLED_FOR_CKKSRNS; + } + void SetPRENumHops(uint32_t PRENumHops0) override { + DISABLED_FOR_CKKSRNS; + } + void SetMultipartyMode(MultipartyMode multipartyMode0) override { + DISABLED_FOR_CKKSRNS; + } + void SetThresholdNumOfParties(uint32_t thresholdNumOfParties0) override { + DISABLED_FOR_CKKSRNS; + } }; //==================================================================================================================== diff --git a/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns.h b/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns.h index fe17fe922..a15b2f82a 100644 --- a/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns.h +++ b/src/pke/include/scheme/ckksrns/gen-cryptocontext-ckksrns.h @@ -41,6 +41,7 @@ #include "scheme/ckksrns/gen-cryptocontext-ckksrns-params.h" #include "scheme/ckksrns/ckksrns-cryptoparameters.h" #include "scheme/ckksrns/ckksrns-scheme.h" +#include "scheme/gen-cryptocontext-params-validation.h" #include "cryptocontextfactory.h" namespace lbcrypto { @@ -55,6 +56,7 @@ class CryptoContextCKKSRNS { using CryptoParams = CryptoParametersCKKSRNS; static CryptoContext genCryptoContext(const CCParams& parameters) { + validateParametersForCryptocontext(parameters); return genCryptoContextCKKSRNSInternal(parameters); } }; diff --git a/src/pke/include/scheme/gen-cryptocontext-params-defaults.h b/src/pke/include/scheme/gen-cryptocontext-params-defaults.h index 81d6b468f..4d3f977e4 100644 --- a/src/pke/include/scheme/gen-cryptocontext-params-defaults.h +++ b/src/pke/include/scheme/gen-cryptocontext-params-defaults.h @@ -46,37 +46,37 @@ namespace lbcrypto { namespace CKKSRNS_SCHEME_DEFAULTS { constexpr SCHEME scheme = CKKSRNS_SCHEME; constexpr PlaintextModulus ptModulus = 0; -constexpr usint digitSize = 0; -constexpr float standardDeviation = 3.19; +constexpr uint32_t digitSize = 0; +constexpr float standardDeviation = 3.19f; constexpr SecretKeyDist secretKeyDist = UNIFORM_TERNARY; -constexpr int maxRelinSkDeg = 2; +constexpr uint32_t maxRelinSkDeg = 2; constexpr KeySwitchTechnique ksTech = HYBRID; // Backend-specific settings for CKKS #if NATIVEINT == 128 && !defined(__EMSCRIPTEN__) constexpr ScalingTechnique scalTech = FIXEDAUTO; -constexpr usint firstModSize = 105; -constexpr usint scalingModSize = 78; +constexpr uint32_t firstModSize = 89; +constexpr uint32_t scalingModSize = 78; #else constexpr ScalingTechnique scalTech = FLEXIBLEAUTOEXT; -constexpr usint firstModSize = 60; -constexpr usint scalingModSize = 59; +constexpr uint32_t firstModSize = 60; +constexpr uint32_t scalingModSize = 50; #endif -constexpr usint batchSize = 0; +constexpr uint32_t batchSize = 0; constexpr uint32_t numLargeDigits = 0; -constexpr usint multiplicativeDepth = 1; +constexpr uint32_t multiplicativeDepth = 1; constexpr SecurityLevel securityLevel = HEStd_128_classic; -constexpr usint ringDim = 0; -constexpr usint evalAddCount = 0; -constexpr usint keySwitchCount = 0; +constexpr uint32_t ringDim = 0; +constexpr uint32_t evalAddCount = 0; +constexpr uint32_t keySwitchCount = 0; constexpr EncryptionTechnique encryptionTechnique = STANDARD; constexpr MultiplicationTechnique multiplicationTechnique = HPS; -constexpr usint multiHopModSize = 0; +constexpr uint32_t PRENumHops = 0; constexpr ProxyReEncryptionMode PREMode = INDCPA; constexpr MultipartyMode multipartyMode = FIXED_NOISE_MULTIPARTY; constexpr ExecutionMode executionMode = EXEC_EVALUATION; constexpr DecryptionNoiseMode decryptionNoiseMode = FIXED_NOISE_DECRYPT; -constexpr double noiseEstimate = 0; -constexpr double desiredPrecision = 25; +constexpr double noiseEstimate = 0.0; +constexpr double desiredPrecision = 25.0; constexpr uint32_t statisticalSecurity = 30; constexpr uint32_t numAdversarialQueries = 1; constexpr uint32_t thresholdNumOfParties = 1; @@ -84,42 +84,38 @@ constexpr COMPRESSION_LEVEL interactiveBootCompressionLevel = SLACK; }; // namespace CKKSRNS_SCHEME_DEFAULTS namespace BFVRNS_SCHEME_DEFAULTS { -constexpr SCHEME scheme = BFVRNS_SCHEME; -constexpr PlaintextModulus ptModulus = 0; -constexpr usint digitSize = 0; -constexpr float standardDeviation = 3.19; -constexpr SecretKeyDist secretKeyDist = UNIFORM_TERNARY; -constexpr int maxRelinSkDeg = 2; -constexpr KeySwitchTechnique ksTech = BV; -constexpr ScalingTechnique scalTech = NORESCALE; +constexpr SCHEME scheme = BFVRNS_SCHEME; +constexpr PlaintextModulus ptModulus = 0; +constexpr uint32_t digitSize = 0; +constexpr float standardDeviation = 3.19f; +constexpr SecretKeyDist secretKeyDist = UNIFORM_TERNARY; +constexpr uint32_t maxRelinSkDeg = 2; +constexpr KeySwitchTechnique ksTech = BV; +constexpr ScalingTechnique scalTech = NORESCALE; +constexpr uint32_t firstModSize = 0; +constexpr uint32_t batchSize = 0; +constexpr uint32_t numLargeDigits = 0; +constexpr uint32_t multiplicativeDepth = 1; #if defined(HAVE_INT128) || NATIVEINT != 64 -constexpr usint firstModSize = 60; +constexpr uint32_t scalingModSize = 60; #else -constexpr usint firstModSize = 57; -#endif -constexpr usint batchSize = 0; -constexpr uint32_t numLargeDigits = 0; -constexpr usint multiplicativeDepth = 1; -#if defined(HAVE_INT128) || NATIVEINT != 64 -constexpr usint scalingModSize = 60; -#else -constexpr usint scalingModSize = 57; +constexpr uint32_t scalingModSize = 57; #endif constexpr SecurityLevel securityLevel = HEStd_128_classic; -constexpr usint ringDim = 0; -constexpr usint evalAddCount = 0; -constexpr usint keySwitchCount = 0; +constexpr uint32_t ringDim = 0; +constexpr uint32_t evalAddCount = 0; +constexpr uint32_t keySwitchCount = 0; constexpr EncryptionTechnique encryptionTechnique = STANDARD; constexpr MultiplicationTechnique multiplicationTechnique = HPSPOVERQLEVELED; -constexpr usint multiHopModSize = 0; +constexpr uint32_t PRENumHops = 0; constexpr ProxyReEncryptionMode PREMode = INDCPA; constexpr MultipartyMode multipartyMode = FIXED_NOISE_MULTIPARTY; constexpr ExecutionMode executionMode = EXEC_EVALUATION; constexpr DecryptionNoiseMode decryptionNoiseMode = FIXED_NOISE_DECRYPT; -constexpr double noiseEstimate = 0; -constexpr double desiredPrecision = 0; -constexpr uint32_t statisticalSecurity = 30; -constexpr uint32_t numAdversarialQueries = 1; +constexpr double noiseEstimate = 0.0; +constexpr double desiredPrecision = 0.0; +constexpr uint32_t statisticalSecurity = 0; +constexpr uint32_t numAdversarialQueries = 0; constexpr uint32_t thresholdNumOfParties = 1; constexpr COMPRESSION_LEVEL interactiveBootCompressionLevel = SLACK; }; // namespace BFVRNS_SCHEME_DEFAULTS @@ -127,30 +123,30 @@ constexpr COMPRESSION_LEVEL interactiveBootCompressionLevel = SLACK; namespace BGVRNS_SCHEME_DEFAULTS { constexpr SCHEME scheme = BGVRNS_SCHEME; constexpr PlaintextModulus ptModulus = 0; -constexpr usint digitSize = 0; -constexpr float standardDeviation = 3.19; +constexpr uint32_t digitSize = 0; +constexpr float standardDeviation = 3.19f; constexpr SecretKeyDist secretKeyDist = UNIFORM_TERNARY; -constexpr int maxRelinSkDeg = 2; +constexpr uint32_t maxRelinSkDeg = 2; constexpr KeySwitchTechnique ksTech = HYBRID; constexpr ScalingTechnique scalTech = FLEXIBLEAUTOEXT; -constexpr usint firstModSize = 0; -constexpr usint batchSize = 0; +constexpr uint32_t firstModSize = 0; +constexpr uint32_t batchSize = 0; constexpr uint32_t numLargeDigits = 0; -constexpr usint multiplicativeDepth = 1; -constexpr usint scalingModSize = 0; +constexpr uint32_t multiplicativeDepth = 1; +constexpr uint32_t scalingModSize = 0; constexpr SecurityLevel securityLevel = HEStd_128_classic; -constexpr usint ringDim = 0; -constexpr usint evalAddCount = 5; -constexpr usint keySwitchCount = 3; +constexpr uint32_t ringDim = 0; +constexpr uint32_t evalAddCount = 5; +constexpr uint32_t keySwitchCount = 3; constexpr EncryptionTechnique encryptionTechnique = STANDARD; constexpr MultiplicationTechnique multiplicationTechnique = HPS; -constexpr usint multiHopModSize = 0; +constexpr uint32_t PRENumHops = 0; constexpr ProxyReEncryptionMode PREMode = INDCPA; constexpr MultipartyMode multipartyMode = FIXED_NOISE_MULTIPARTY; constexpr ExecutionMode executionMode = EXEC_EVALUATION; constexpr DecryptionNoiseMode decryptionNoiseMode = FIXED_NOISE_DECRYPT; -constexpr double noiseEstimate = 0; -constexpr double desiredPrecision = 0; +constexpr double noiseEstimate = 0.0; +constexpr double desiredPrecision = 0.0; constexpr uint32_t statisticalSecurity = 30; constexpr uint32_t numAdversarialQueries = 1; constexpr uint32_t thresholdNumOfParties = 1; diff --git a/src/pke/include/scheme/gen-cryptocontext-params-validation.h b/src/pke/include/scheme/gen-cryptocontext-params-validation.h new file mode 100644 index 000000000..ddb6cc64f --- /dev/null +++ b/src/pke/include/scheme/gen-cryptocontext-params-validation.h @@ -0,0 +1,46 @@ +//================================================================================== +// BSD 2-Clause License +// +// Copyright (c) 2014-2024, NJIT, Duality Technologies Inc. and other contributors +// +// All rights reserved. +// +// Author TPOC: contact@openfhe.org +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//================================================================================== +#ifndef __GEN_CRYPTOCONTEXT_PARAMS_VALIDATION_H__ +#define __GEN_CRYPTOCONTEXT_PARAMS_VALIDATION_H__ + +#include "scheme/gen-cryptocontext-params.h" + +namespace lbcrypto { +/** + * @brief Validate parameters for generating cryptocontext. Doesn't validate the parameters which set functions + * are disabled as they cannot be set by users + * @param parameters scheme-specific parameters to generate cryptocontext + */ +void validateParametersForCryptocontext(const Params& parameters); + +} // namespace lbcrypto + +#endif // __GEN_CRYPTOCONTEXT_PARAMS_VALIDATION_H__ diff --git a/src/pke/include/scheme/gen-cryptocontext-params.h b/src/pke/include/scheme/gen-cryptocontext-params.h index 61a553582..29fdd2e30 100644 --- a/src/pke/include/scheme/gen-cryptocontext-params.h +++ b/src/pke/include/scheme/gen-cryptocontext-params.h @@ -62,7 +62,7 @@ class Params { PlaintextModulus ptModulus; // digitSize is used in BV Key Switching only (KeySwitchTechnique = BV) and impacts noise growth - usint digitSize; + uint32_t digitSize; // standardDeviation is used for Gaussian error generation float standardDeviation; @@ -71,7 +71,7 @@ class Params { SecretKeyDist secretKeyDist; // Max relinearization degree of secret key polynomial (used for lazy relinearization) - usint maxRelinSkDeg; + uint32_t maxRelinSkDeg; // key switching technique: BV or HYBRID currently // For BV we do not have extra modulus, so the security depends on ciphertext modulus Q. @@ -86,7 +86,7 @@ class Params { ScalingTechnique scalTech; // max batch size of messages to be packed in encoding (number of slots) - usint batchSize; + uint32_t batchSize; // PRE security mode ProxyReEncryptionMode PREMode; @@ -113,28 +113,28 @@ class Params { // Statistical security of CKKS in NOISE_FLOODING_DECRYPT mode. This is the bound on the probability of success // that any adversary can have. Specifically, they a probability of success of at most 2^(-statisticalSecurity). - usint statisticalSecurity; + uint32_t statisticalSecurity; // This is the number of adversarial queries a user is expecting for their application, which we use to ensure // security of CKKS in NOISE_FLOODING_DECRYPT mode. - usint numAdversarialQueries; + uint32_t numAdversarialQueries; // This is the number of parties in a threshold application, which is used for bound on the joint secret key - usint thresholdNumOfParties; + uint32_t thresholdNumOfParties; // firstModSize and scalingModSize are used to calculate ciphertext modulus. The ciphertext modulus should be seen as: // Q = q_0 * q_1 * ... * q_n * q' // where q_0 is first prime, and it's number of bits is firstModSize // other q_i have same number of bits and is equal to scalingModSize // the prime q' is not explicitly given, // but it is used internally in CKKS and BGV schemes (in *EXT scaling methods) - usint firstModSize; - usint scalingModSize; + uint32_t firstModSize; + uint32_t scalingModSize; // see KeySwitchTechnique - number of digits in HYBRID key switching - usint numLargeDigits; + uint32_t numLargeDigits; // multiplicative depth - usint multiplicativeDepth; + uint32_t multiplicativeDepth; // security level: // We use the values from the security standard at @@ -144,16 +144,16 @@ class Params { SecurityLevel securityLevel; // ring dimension N of the scheme : the ring is Z_Q[x] / (X^N+1) - usint ringDim; + uint32_t ringDim; // number of additions (used for setting noise in BGV and BFV) - usint evalAddCount; + uint32_t evalAddCount; // number of key switching operations (used for setting noise in BGV and BFV) - usint keySwitchCount; + uint32_t keySwitchCount; // size of moduli used for PRE in the provable HRA setting - usint multiHopModSize; + uint32_t PRENumHops; // STANDARD or EXTENDED mode for BFV encryption // EXTENDED slightly reduces the size of Q (by few bits) but makes encryption somewhat slower @@ -172,8 +172,27 @@ class Params { void SetToDefaults(SCHEME scheme); - void ValidateRingDim(usint ringDim); - void ValidateMultiplicativeDepth(usint multiplicativeDepth); +protected: + // How to disable a particular setter for a particular scheme and get an exception thrown if a user tries to call it: + // 1. The set function should be declared virtual in this file + // 2. The same function should be re-defined in the scheme-specific derived file using macros DISABLED_FOR_xxxxRNS defined below. + // + // Example: + // the original setter defined in gen-cryptocontext-params.h: + // + // virtual void SetPlaintextModulus(PlaintextModulus ptModulus0) { + // ptModulus = ptModulus0; + // } + // + // the setter re-defined and disabled in gen-cryptocontext-ckksrns-params.h: + // + // void SetPlaintextModulus(PlaintextModulus ptModulus0) override { + // DISABLED_FOR_CKKS; + // } + +#define DISABLED_FOR_CKKSRNS OPENFHE_THROW("This function is not available for CKKSRNS."); +#define DISABLED_FOR_BGVRNS OPENFHE_THROW("This function is not available for BGVRNS."); +#define DISABLED_FOR_BFVRNS OPENFHE_THROW("This function is not available for BFVRNS."); public: explicit Params(SCHEME scheme0 = INVALID_SCHEME) { @@ -221,7 +240,7 @@ class Params { "keySwitchCount", "encryptionTechnique", "multiplicationTechnique", - "multiHopModSize", + "PRENumHops", "PREMode", "multipartyMode", "executionMode", @@ -241,7 +260,7 @@ class Params { PlaintextModulus GetPlaintextModulus() const { return ptModulus; } - usint GetDigitSize() const { + uint32_t GetDigitSize() const { return digitSize; } float GetStandardDeviation() const { @@ -250,7 +269,7 @@ class Params { SecretKeyDist GetSecretKeyDist() const { return secretKeyDist; } - usint GetMaxRelinSkDeg() const { + uint32_t GetMaxRelinSkDeg() const { return maxRelinSkDeg; } ProxyReEncryptionMode GetPREMode() const { @@ -278,7 +297,7 @@ class Params { return numAdversarialQueries; } - usint GetThresholdNumOfParties() const { + uint32_t GetThresholdNumOfParties() const { return thresholdNumOfParties; } @@ -288,31 +307,31 @@ class Params { ScalingTechnique GetScalingTechnique() const { return scalTech; } - usint GetBatchSize() const { + uint32_t GetBatchSize() const { return batchSize; } - usint GetFirstModSize() const { + uint32_t GetFirstModSize() const { return firstModSize; } uint32_t GetNumLargeDigits() const { return numLargeDigits; } - usint GetMultiplicativeDepth() const { + uint32_t GetMultiplicativeDepth() const { return multiplicativeDepth; } - usint GetScalingModSize() const { + uint32_t GetScalingModSize() const { return scalingModSize; } SecurityLevel GetSecurityLevel() const { return securityLevel; } - usint GetRingDim() const { + uint32_t GetRingDim() const { return ringDim; } - usint GetEvalAddCount() const { + uint32_t GetEvalAddCount() const { return evalAddCount; } - usint GetKeySwitchCount() const { + uint32_t GetKeySwitchCount() const { return keySwitchCount; } EncryptionTechnique GetEncryptionTechnique() const { @@ -321,106 +340,100 @@ class Params { MultiplicationTechnique GetMultiplicationTechnique() const { return multiplicationTechnique; } - usint GetMultiHopModSize() const { - return multiHopModSize; + uint32_t GetPRENumHops() const { + return PRENumHops; } COMPRESSION_LEVEL GetInteractiveBootCompressionLevel() const { return interactiveBootCompressionLevel; } // setters - void SetPlaintextModulus(PlaintextModulus ptModulus0) { + // They all must be virtual, so any of them can be disabled in the derived class + virtual void SetPlaintextModulus(PlaintextModulus ptModulus0) { ptModulus = ptModulus0; } - void SetDigitSize(usint digitSize0) { + virtual void SetDigitSize(uint32_t digitSize0) { digitSize = digitSize0; } - void SetStandardDeviation(float standardDeviation0) { + virtual void SetStandardDeviation(float standardDeviation0) { standardDeviation = standardDeviation0; } - void SetSecretKeyDist(SecretKeyDist secretKeyDist0) { + virtual void SetSecretKeyDist(SecretKeyDist secretKeyDist0) { secretKeyDist = secretKeyDist0; } - void SetMaxRelinSkDeg(usint maxRelinSkDeg0) { + virtual void SetMaxRelinSkDeg(uint32_t maxRelinSkDeg0) { maxRelinSkDeg = maxRelinSkDeg0; } - void SetPREMode(ProxyReEncryptionMode PREMode0) { + virtual void SetPREMode(ProxyReEncryptionMode PREMode0) { PREMode = PREMode0; } - void SetMultipartyMode(MultipartyMode multipartyMode0) { + virtual void SetMultipartyMode(MultipartyMode multipartyMode0) { multipartyMode = multipartyMode0; } - void SetExecutionMode(ExecutionMode executionMode0) { + virtual void SetExecutionMode(ExecutionMode executionMode0) { executionMode = executionMode0; } - void SetDecryptionNoiseMode(DecryptionNoiseMode decryptionNoiseMode0) { + virtual void SetDecryptionNoiseMode(DecryptionNoiseMode decryptionNoiseMode0) { decryptionNoiseMode = decryptionNoiseMode0; } - void SetNoiseEstimate(double noiseEstimate0) { + virtual void SetNoiseEstimate(double noiseEstimate0) { noiseEstimate = noiseEstimate0; } - void SetDesiredPrecision(double desiredPrecision0) { + virtual void SetDesiredPrecision(double desiredPrecision0) { desiredPrecision = desiredPrecision0; } - void SetStatisticalSecurity(uint32_t statisticalSecurity0) { + virtual void SetStatisticalSecurity(uint32_t statisticalSecurity0) { statisticalSecurity = statisticalSecurity0; } - void SetNumAdversarialQueries(uint32_t numAdversarialQueries0) { + virtual void SetNumAdversarialQueries(uint32_t numAdversarialQueries0) { numAdversarialQueries = numAdversarialQueries0; } - - void SetThresholdNumOfParties(uint32_t thresholdNumOfParties0) { + virtual void SetThresholdNumOfParties(uint32_t thresholdNumOfParties0) { thresholdNumOfParties = thresholdNumOfParties0; } - void SetKeySwitchTechnique(KeySwitchTechnique ksTech0) { + virtual void SetKeySwitchTechnique(KeySwitchTechnique ksTech0) { ksTech = ksTech0; } - void SetScalingTechnique(ScalingTechnique scalTech0) { + virtual void SetScalingTechnique(ScalingTechnique scalTech0) { scalTech = scalTech0; } - void SetBatchSize(usint batchSize0) { + virtual void SetBatchSize(uint32_t batchSize0) { batchSize = batchSize0; } - void SetFirstModSize(usint firstModSize0) { + virtual void SetFirstModSize(uint32_t firstModSize0) { firstModSize = firstModSize0; } - void SetNumLargeDigits(uint32_t numLargeDigits0) { + virtual void SetNumLargeDigits(uint32_t numLargeDigits0) { numLargeDigits = numLargeDigits0; } - void SetMultiplicativeDepth(usint multiplicativeDepth0) { - // TODO (dsuponit): move the check below ValidateMultiplicativeDepth() to a separate validating function. see - // https://github.com/openfheorg/openfhe-development/issues/400 - ValidateMultiplicativeDepth(multiplicativeDepth0); + virtual void SetMultiplicativeDepth(uint32_t multiplicativeDepth0) { multiplicativeDepth = multiplicativeDepth0; } - void SetScalingModSize(usint scalingModSize0) { + virtual void SetScalingModSize(uint32_t scalingModSize0) { scalingModSize = scalingModSize0; } - void SetSecurityLevel(SecurityLevel securityLevel0) { + virtual void SetSecurityLevel(SecurityLevel securityLevel0) { securityLevel = securityLevel0; } - void SetRingDim(usint ringDim0) { - // TODO (dsuponit): move the check below ValidateRingDim() to a separate validating function. see - // https://github.com/openfheorg/openfhe-development/issues/400 - ValidateRingDim(ringDim0); + virtual void SetRingDim(uint32_t ringDim0) { ringDim = ringDim0; } - void SetEvalAddCount(usint evalAddCount0) { + virtual void SetEvalAddCount(uint32_t evalAddCount0) { evalAddCount = evalAddCount0; } - void SetKeySwitchCount(usint keySwitchCount0) { + virtual void SetKeySwitchCount(uint32_t keySwitchCount0) { keySwitchCount = keySwitchCount0; } - void SetEncryptionTechnique(EncryptionTechnique encryptionTechnique0) { + virtual void SetEncryptionTechnique(EncryptionTechnique encryptionTechnique0) { encryptionTechnique = encryptionTechnique0; } - void SetMultiplicationTechnique(MultiplicationTechnique multiplicationTechnique0) { + virtual void SetMultiplicationTechnique(MultiplicationTechnique multiplicationTechnique0) { multiplicationTechnique = multiplicationTechnique0; } - void SetMultiHopModSize(usint multiHopModSize0) { - multiHopModSize = multiHopModSize0; + virtual void SetPRENumHops(uint32_t PRENumHops0) { + PRENumHops = PRENumHops0; } - void SetInteractiveBootCompressionLevel(COMPRESSION_LEVEL interactiveBootCompressionLevel0) { + virtual void SetInteractiveBootCompressionLevel(COMPRESSION_LEVEL interactiveBootCompressionLevel0) { interactiveBootCompressionLevel = interactiveBootCompressionLevel0; } diff --git a/src/pke/include/scheme/scheme-utils.h b/src/pke/include/scheme/scheme-utils.h index 41adc26bc..3cde1f7d5 100644 --- a/src/pke/include/scheme/scheme-utils.h +++ b/src/pke/include/scheme/scheme-utils.h @@ -1,7 +1,7 @@ //================================================================================== // BSD 2-Clause License // -// Copyright (c) 2014-2022, NJIT, Duality Technologies Inc. and other contributors +// Copyright (c) 2014-2024, NJIT, Duality Technologies Inc. and other contributors // // All rights reserved. // @@ -32,16 +32,24 @@ #ifndef _SCHEME_UTILS_H_ #define _SCHEME_UTILS_H_ -inline uint32_t ComputeNumLargeDigits(uint32_t numLargeDigits, usint multDepth) { - if (!numLargeDigits) { // Choose one of the default values - if (multDepth > 3) // If more than 4 towers, use 3 digits - numLargeDigits = 3; - else if (multDepth == 0) // if there is only 1 tower, use one digit - numLargeDigits = 1; - else // If 2, 3 or 4 towers, use 2 digits (1 <= multiplicativeDepth <=3 ) - numLargeDigits = 2; - } - return numLargeDigits; +inline uint32_t ComputeNumLargeDigits(uint32_t numLargeDigits, uint32_t multDepth) { + if (numLargeDigits > 0) + return numLargeDigits; + if (multDepth > 3) // if more than 4 towers, use 3 digits + return 3; + if (multDepth > 0) // if 2, 3 or 4 towers, use 2 digits + return 2; + return 1; // if 1 tower, use one digit +} + +inline uint32_t ComputeNumLargeDigitsPRE(uint32_t numLargeDigits, uint32_t numHops) { + if (numLargeDigits > 0) + return numLargeDigits; + if (numHops > 4) + return 3; + if (numHops > 1) + return 2; + return 1; } #endif diff --git a/src/pke/include/schemebase/base-advancedshe.h b/src/pke/include/schemebase/base-advancedshe.h index fe3f2ba48..77b013cb7 100644 --- a/src/pke/include/schemebase/base-advancedshe.h +++ b/src/pke/include/schemebase/base-advancedshe.h @@ -44,6 +44,7 @@ #include #include #include +#include /** * @namespace lbcrypto @@ -224,8 +225,8 @@ class AdvancedSHEBase { * @return returns the evaluation keys */ virtual std::shared_ptr>> EvalSumRowsKeyGen(const PrivateKey privateKey, - const PublicKey publicKey, - usint rowSize, usint subringDim) const; + usint rowSize, usint subringDim, + std::vector& indices) const; /** * Virtual function to generate the automorphism keys for EvalSumCols; works @@ -235,84 +236,70 @@ class AdvancedSHEBase { * @param publicKey public key. * @return returns the evaluation keys */ - virtual std::shared_ptr>> EvalSumColsKeyGen( - const PrivateKey privateKey, const PublicKey publicKey) const; + virtual std::shared_ptr>> EvalSumColsKeyGen(const PrivateKey privateKey, + std::vector& indices) const; /** - * Sums all elements in log (batch size) time - works only with packed - * encoding - * - * @param ciphertext the input ciphertext. - * @param batchSize size of the batch to be summed up - * @param &evalKeys - reference to the map of evaluation keys generated by - * EvalAutomorphismKeyGen. - * @return resulting ciphertext - */ + * @brief Sums all elements in log (batch size) time - works only with packedvencoding + * @param ciphertext the input ciphertext. + * @param batchSize size of the batch to be summed up + * @param evalKeys - reference to the map of evaluation keys generated by EvalAutomorphismKeyGen. + * @return resulting ciphertext + */ virtual Ciphertext EvalSum(ConstCiphertext ciphertext, usint batchSize, const std::map>& evalSumKeyMap) const; /** - * Sums all elements over row-vectors in a matrix - works only with packed - * encoding - * - * @param ciphertext the input ciphertext. - * @param rowSize size of rows in the matrix - * @param &evalKeys - reference to the map of evaluation keys generated by - * @param subringDim the current cyclotomic order/subring dimension. If set to - * 0, we use the full cyclotomic order. EvalAutomorphismKeyGen. - * @return resulting ciphertext - */ - virtual Ciphertext EvalSumRows(ConstCiphertext ciphertext, usint rowSize, - const std::map>& evalSumRowsKeyMap, - usint subringDim) const; + * @brief Sums all elements over row-vectors in a matrix - works only with packed encoding. + * @param ciphertext the input ciphertext. + * @param numRows number of rows in the matrix + * @param evalSumKeys - reference to the map of evaluation keys generated by EvalAutomorphismKeyGen. + * @param subringDim the current cyclotomic order/subring dimension. If set to 0, we use the full cyclotomic order. + * @return resulting ciphertext + */ + virtual Ciphertext EvalSumRows(ConstCiphertext ciphertext, uint32_t numRows, + const std::map>& evalSumKeys, + uint32_t subringDim) const; /** - * Sums all elements over column-vectors in a matrix - works only with - * packed encoding - * - * @param ciphertext the input ciphertext. - * @param rowSize size of rows in the matrixs - * @param &evalKeys - reference to the map of evaluation keys generated by - * EvalAutomorphismKeyGen. - * @return resulting ciphertext - */ - virtual Ciphertext EvalSumCols(ConstCiphertext ciphertext, usint batchSize, - const std::map>& evalSumColsKeyMap, - const std::map>& rightEvalKeys) const; + * @brief Sums all elements over column-vectors in a matrix - works only with packed encoding. The code is + * implemented according to the specifications in https://eprint.iacr.org/2018/662.pdf + * @param ciphertext the input ciphertext. + * @param numCols number of columns in the matrixs + * @param evalSumKeys - reference to the map of evaluation keys generated by EvalAutomorphismKeyGen. + * @param rightEvalKeys - reference to the map of + * @return resulting ciphertext + */ + virtual Ciphertext EvalSumCols(ConstCiphertext ciphertext, uint32_t numCols, + const std::map>& evalSumKeys, + const std::map>& rightEvalKeys) const; //------------------------------------------------------------------------------ // Advanced SHE EVAL INNER PRODUCT //------------------------------------------------------------------------------ /** - * Evaluates inner product in batched encoding - * - * @param ciphertext1 first vector. - * @param ciphertext2 second vector. - * @param batchSize size of the batch to be summed up - * @param &evalSumKeys - reference to the map of evaluation keys generated - * by EvalAutomorphismKeyGen. - * @param &evalMultKey - reference to the evaluation key generated by - * EvalMultKeyGen. - * @return resulting ciphertext - */ + * @brief Evaluates inner product in batched encoding + * @param ciphertext1 first vector. + * @param ciphertext2 second vector. + * @param batchSize size of the batch to be summed up + * @param evalSumKeys - reference to the map of evaluation keys generated by EvalAutomorphismKeyGen. + * @param evalMultKey - reference to the evaluation key generated by EvalMultKeyGen. + * @return resulting ciphertext + */ virtual Ciphertext EvalInnerProduct(ConstCiphertext ciphertext1, ConstCiphertext ciphertext2, usint batchSize, const std::map>& evalKeyMap, const EvalKey evalMultKey) const; /** - * Evaluates inner product in batched encoding - * - * @param ciphertext1 first vector. - * @param plaintext plaintext. - * @param batchSize size of the batch to be summed up - * @param &evalSumKeys - reference to the map of evaluation keys generated - * by EvalAutomorphismKeyGen. - * @param &evalMultKey - reference to the evaluation key generated by - * EvalMultKeyGen. - * @return resulting ciphertext - */ + * @brief Evaluates inner product in batched encoding + * @param ciphertext first vector. + * @param plaintext plaintext. + * @param batchSize size of the batch to be summed up + * @param evalSumKeys - reference to the map of evaluation keys generated by EvalAutomorphismKeyGen. + * @return resulting ciphertext + */ virtual Ciphertext EvalInnerProduct(ConstCiphertext ciphertext, ConstPlaintext plaintext, usint batchSize, const std::map>& evalKeyMap) const; @@ -348,13 +335,15 @@ class AdvancedSHEBase { //------------------------------------------------------------------------------ protected: - std::vector GenerateIndices_2n(usint batchSize, usint m) const; + std::set GenerateIndices_2n(usint batchSize, usint m) const; + + std::set GenerateIndices2nComplex(usint batchSize, usint m) const; - std::vector GenerateIndices2nComplex(usint batchSize, usint m) const; + std::set GenerateIndices2nComplexRows(usint rowSize, usint m) const; - std::vector GenerateIndices2nComplexRows(usint rowSize, usint m) const; + std::set GenerateIndices2nComplexCols(usint batchSize, usint m) const; - std::vector GenerateIndices2nComplexCols(usint batchSize, usint m) const; + std::set GenerateIndexListForEvalSum(const PrivateKey& privateKey) const; Ciphertext EvalSum_2n(ConstCiphertext ciphertext, usint batchSize, usint m, const std::map>& evalKeyMap) const; diff --git a/src/pke/include/schemebase/base-leveledshe.h b/src/pke/include/schemebase/base-leveledshe.h index 0fda2cd03..2ab99daa4 100644 --- a/src/pke/include/schemebase/base-leveledshe.h +++ b/src/pke/include/schemebase/base-leveledshe.h @@ -569,8 +569,7 @@ class LeveledSHEBase { * * @param ciphertext the input ciphertext. * @param i automorphism index - * @param &evalKeys - reference to the vector of evaluation keys generated - * by EvalAutomorphismKeyGen. + * @param &evalKeys - reference to the vector of evaluation keys generated by EvalAutomorphismKeyGen. * @return resulting ciphertext */ virtual Ciphertext EvalAutomorphism(ConstCiphertext ciphertext, usint i, @@ -784,6 +783,10 @@ class LeveledSHEBase { ///////////////////////////////////////// // CORE OPERATIONS ///////////////////////////////////////// + void VerifyNumOfTowers(const ConstCiphertext& ciphertext1, const ConstCiphertext& ciphertext, + CALLER_INFO_ARGS_HDR) const; + void VerifyNumOfTowers(const ConstCiphertext& ciphertext, const Element& plaintext, + CALLER_INFO_ARGS_HDR) const; /** * Internal function for in-place homomorphic addition of ciphertexts. @@ -838,17 +841,17 @@ class LeveledSHEBase { Ciphertext EvalSquareCore(ConstCiphertext ciphertext) const; - virtual Ciphertext EvalAddCore(ConstCiphertext ciphertext, const Element plaintext) const; + virtual Ciphertext EvalAddCore(ConstCiphertext ciphertext, const Element& plaintext) const; - void EvalAddCoreInPlace(Ciphertext& ciphertext, const Element plaintext) const; + void EvalAddCoreInPlace(Ciphertext& ciphertext, const Element& plaintext) const; - virtual Ciphertext EvalSubCore(ConstCiphertext ciphertext1, const Element plaintext) const; + virtual Ciphertext EvalSubCore(ConstCiphertext ciphertext1, const Element& plaintext) const; - void EvalSubCoreInPlace(Ciphertext& ciphertext1, const Element plaintext) const; + void EvalSubCoreInPlace(Ciphertext& ciphertext1, const Element& plaintext) const; - Ciphertext EvalMultCore(ConstCiphertext ciphertext, const Element plaintext) const; + Ciphertext EvalMultCore(ConstCiphertext ciphertext, const Element& plaintext) const; - void EvalMultCoreInPlace(Ciphertext& ciphertext, const Element plaintext) const; + void EvalMultCoreInPlace(Ciphertext& ciphertext, const Element& plaintext) const; }; } // namespace lbcrypto diff --git a/src/pke/include/schemebase/base-parametergeneration.h b/src/pke/include/schemebase/base-parametergeneration.h index 028a85f40..4621f6576 100644 --- a/src/pke/include/schemebase/base-parametergeneration.h +++ b/src/pke/include/schemebase/base-parametergeneration.h @@ -95,8 +95,8 @@ class ParameterGenerationBase { * @param firstModSize the bit-size of the first modulus * @param numPartQ number of partitions of Q for HYBRID key switching */ - virtual bool ParamsGenCKKSRNS(std::shared_ptr> cryptoParams, usint cyclOrder, - usint numPrimes, usint scalingModSize, usint firstModSize, uint32_t numPartQ, + virtual bool ParamsGenCKKSRNS(std::shared_ptr> cryptoParams, uint32_t cyclOrder, + uint32_t numPrimes, uint32_t scalingModSize, uint32_t firstModSize, uint32_t numPartQ, COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel) const { OPENFHE_THROW("This signature for ParamsGen is not supported for this scheme."); } @@ -113,11 +113,11 @@ class ParameterGenerationBase { * @param firstModSize the bit-size of the first modulus * @param dcrtBits the bit-width of moduli * @param numPartQ number of partitions of Q for HYBRID key switching - * @param multihopQBound bound for the HRA-secure mode of PRE + * @param PRENumHops bound for the HRA-secure mode of PRE */ virtual bool ParamsGenBGVRNS(std::shared_ptr> cryptoParams, uint32_t evalAddCount, - uint32_t keySwitchCount, usint cyclOrder, usint numPrimes, usint firstModSize, - usint dcrtBits, uint32_t numPartQ, usint multihopQBound) const { + uint32_t keySwitchCount, uint32_t cyclOrder, uint32_t numPrimes, uint32_t firstModSize, + uint32_t dcrtBits, uint32_t numPartQ, uint32_t PRENumHops) const { OPENFHE_THROW("This signature for ParamsGen is not supported for this scheme."); } diff --git a/src/pke/include/schemebase/base-pke.h b/src/pke/include/schemebase/base-pke.h index 5e49038e4..ab00ae904 100644 --- a/src/pke/include/schemebase/base-pke.h +++ b/src/pke/include/schemebase/base-pke.h @@ -71,7 +71,7 @@ class PKEBase { * @param &privateKey private key used for decryption. * @return function ran correctly. */ - virtual KeyPair KeyGenInternal(CryptoContext cc, bool makeSparse); + virtual KeyPair KeyGenInternal(CryptoContext cc, bool makeSparse) const; // virtual KeyPair KeyGen(CryptoContext cc, // bool makeSparse, diff --git a/src/pke/include/schemebase/base-scheme.h b/src/pke/include/schemebase/base-scheme.h index 715d4c69b..736a7edcb 100644 --- a/src/pke/include/schemebase/base-scheme.h +++ b/src/pke/include/schemebase/base-scheme.h @@ -203,8 +203,8 @@ class SchemeBase { n, numPartQ); } - virtual bool ParamsGenCKKSRNS(std::shared_ptr> cryptoParams, usint cyclOrder, - usint numPrimes, usint scalingModSize, usint firstModSize, uint32_t numPartQ, + virtual bool ParamsGenCKKSRNS(std::shared_ptr> cryptoParams, uint32_t cyclOrder, + uint32_t numPrimes, uint32_t scalingModSize, uint32_t firstModSize, uint32_t numPartQ, COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel) const { if (!m_ParamsGen) OPENFHE_THROW("m_ParamsGen is nullptr"); @@ -213,19 +213,19 @@ class SchemeBase { } virtual bool ParamsGenBGVRNS(std::shared_ptr> cryptoParams, uint32_t evalAddCount, - uint32_t keySwitchCount, usint cyclOrder, usint numPrimes, usint firstModSize, - usint dcrtBits, uint32_t numPartQ, usint multihopQBound) const { + uint32_t keySwitchCount, uint32_t cyclOrder, uint32_t numPrimes, uint32_t firstModSize, + uint32_t dcrtBits, uint32_t numPartQ, uint32_t PRENumHops) const { if (!m_ParamsGen) OPENFHE_THROW("m_ParamsGen is nullptr"); return m_ParamsGen->ParamsGenBGVRNS(cryptoParams, evalAddCount, keySwitchCount, cyclOrder, numPrimes, - firstModSize, dcrtBits, numPartQ, multihopQBound); + firstModSize, dcrtBits, numPartQ, PRENumHops); } ///////////////////////////////////////// // PKE WRAPPER ///////////////////////////////////////// - virtual KeyPair KeyGen(CryptoContext cc, bool makeSparse) { + virtual KeyPair KeyGen(CryptoContext cc, bool makeSparse) const { VerifyPKEEnabled(__func__); return m_PKE->KeyGenInternal(cc, makeSparse); } @@ -822,14 +822,14 @@ class SchemeBase { return m_LeveledSHE->EvalMultMutable(ciphertext, plaintext); } - virtual Ciphertext MultByMonomial(ConstCiphertext ciphertext, usint power) const { + virtual Ciphertext MultByMonomial(ConstCiphertext ciphertext, uint32_t power) const { VerifyLeveledSHEEnabled(__func__); if (!ciphertext) OPENFHE_THROW("Input ciphertext is nullptr"); return m_LeveledSHE->MultByMonomial(ciphertext, power); } - virtual void MultByMonomialInPlace(Ciphertext& ciphertext, usint power) const { + virtual void MultByMonomialInPlace(Ciphertext& ciphertext, uint32_t power) const { VerifyLeveledSHEEnabled(__func__); if (!ciphertext) OPENFHE_THROW("Input ciphertext is nullptr"); @@ -871,15 +871,15 @@ class SchemeBase { // SHE AUTOMORPHISM Wrapper ///////////////////////////////////////// - virtual std::shared_ptr>> EvalAutomorphismKeyGen( - const PrivateKey privateKey, const std::vector& indexList) const; + virtual std::shared_ptr>> EvalAutomorphismKeyGen( + const PrivateKey privateKey, const std::vector& indexList) const; - virtual std::shared_ptr>> EvalAutomorphismKeyGen( + virtual std::shared_ptr>> EvalAutomorphismKeyGen( const PublicKey publicKey, const PrivateKey privateKey, - const std::vector& indexList) const; + const std::vector& indexList) const; - virtual Ciphertext EvalAutomorphism(ConstCiphertext ciphertext, usint i, - const std::map>& evalKeyMap, + virtual Ciphertext EvalAutomorphism(ConstCiphertext ciphertext, uint32_t i, + const std::map>& evalKeyMap, CALLER_INFO_ARGS_HDR) const { if (m_LeveledSHE) { if (!ciphertext) @@ -893,7 +893,8 @@ class SchemeBase { OPENFHE_THROW(errorMsg); } - virtual Ciphertext EvalFastRotation(ConstCiphertext ciphertext, const usint index, const usint m, + virtual Ciphertext EvalFastRotation(ConstCiphertext ciphertext, const uint32_t index, + const uint32_t m, const std::shared_ptr> digits) const { VerifyLeveledSHEEnabled(__func__); if (!ciphertext) @@ -920,9 +921,9 @@ class SchemeBase { * @param addFirst if true, the the first element c0 is also computed (otherwise ignored) * @return resulting ciphertext */ - virtual Ciphertext EvalFastRotationExt(ConstCiphertext ciphertext, usint index, + virtual Ciphertext EvalFastRotationExt(ConstCiphertext ciphertext, uint32_t index, const std::shared_ptr> digits, bool addFirst, - const std::map>& evalKeys) const { + const std::map>& evalKeys) const { VerifyLeveledSHEEnabled(__func__); if (!ciphertext) OPENFHE_THROW("Input ciphertext is nullptr"); @@ -950,12 +951,12 @@ class SchemeBase { return m_KeySwitch->KeySwitchExt(ciphertext, addFirst); } - virtual std::shared_ptr>> EvalAtIndexKeyGen( + virtual std::shared_ptr>> EvalAtIndexKeyGen( const PublicKey publicKey, const PrivateKey privateKey, const std::vector& indexList) const; - virtual Ciphertext EvalAtIndex(ConstCiphertext ciphertext, usint i, - const std::map>& evalKeyMap) const { + virtual Ciphertext EvalAtIndex(ConstCiphertext ciphertext, uint32_t i, + const std::map>& evalKeyMap) const { VerifyLeveledSHEEnabled(__func__); if (!ciphertext) OPENFHE_THROW("Input ciphertext is nullptr"); @@ -964,7 +965,7 @@ class SchemeBase { return m_LeveledSHE->EvalAtIndex(ciphertext, i, evalKeyMap); } - virtual usint FindAutomorphismIndex(usint index, usint m) { + virtual uint32_t FindAutomorphismIndex(uint32_t index, uint32_t m) { VerifyLeveledSHEEnabled(__func__); return m_LeveledSHE->FindAutomorphismIndex(index, m); } @@ -1184,18 +1185,18 @@ class SchemeBase { // Advanced SHE EVAL SUM ///////////////////////////////////// - virtual std::shared_ptr>> EvalSumKeyGen(const PrivateKey privateKey, - const PublicKey publicKey) const; + virtual std::shared_ptr>> EvalSumKeyGen( + const PrivateKey privateKey, const PublicKey publicKey) const; - virtual std::shared_ptr>> EvalSumRowsKeyGen(const PrivateKey privateKey, - const PublicKey publicKey, - usint rowSize, usint subringDim) const; + virtual std::shared_ptr>> EvalSumRowsKeyGen( + const PrivateKey privateKey, uint32_t rowSize, uint32_t subringDim, + std::vector& indices) const; - virtual std::shared_ptr>> EvalSumColsKeyGen( - const PrivateKey privateKey, const PublicKey publicKey) const; + virtual std::shared_ptr>> EvalSumColsKeyGen( + const PrivateKey privateKey, std::vector& indices) const; - virtual Ciphertext EvalSum(ConstCiphertext ciphertext, usint batchSize, - const std::map>& evalKeyMap) const { + virtual Ciphertext EvalSum(ConstCiphertext ciphertext, uint32_t batchSize, + const std::map>& evalKeyMap) const { VerifyAdvancedSHEEnabled(__func__); if (!ciphertext) OPENFHE_THROW("Input ciphertext is nullptr"); @@ -1204,9 +1205,9 @@ class SchemeBase { return m_AdvancedSHE->EvalSum(ciphertext, batchSize, evalKeyMap); } - virtual Ciphertext EvalSumRows(ConstCiphertext ciphertext, usint rowSize, - const std::map>& evalKeyMap, - usint subringDim) const { + virtual Ciphertext EvalSumRows(ConstCiphertext ciphertext, uint32_t rowSize, + const std::map>& evalKeyMap, + uint32_t subringDim) const { VerifyAdvancedSHEEnabled(__func__); if (!ciphertext) OPENFHE_THROW("Input ciphertext is nullptr"); @@ -1215,9 +1216,9 @@ class SchemeBase { return m_AdvancedSHE->EvalSumRows(ciphertext, rowSize, evalKeyMap, subringDim); } - virtual Ciphertext EvalSumCols(ConstCiphertext ciphertext, usint batchSize, - const std::map>& evalKeyMap, - const std::map>& rightEvalKeyMap) const { + virtual Ciphertext EvalSumCols(ConstCiphertext ciphertext, uint32_t batchSize, + const std::map>& evalKeyMap, + const std::map>& rightEvalKeyMap) const { VerifyAdvancedSHEEnabled(__func__); if (!evalKeyMap.size()) OPENFHE_THROW("Input first evaluation key map is empty"); @@ -1231,13 +1232,13 @@ class SchemeBase { ///////////////////////////////////// virtual Ciphertext EvalInnerProduct(ConstCiphertext ciphertext1, - ConstCiphertext ciphertext2, usint batchSize, - const std::map>& evalSumKeyMap, + ConstCiphertext ciphertext2, uint32_t batchSize, + const std::map>& evalSumKeyMap, const EvalKey evalMultKey) const; virtual Ciphertext EvalInnerProduct(ConstCiphertext ciphertext, ConstPlaintext plaintext, - usint batchSize, - const std::map>& evalSumKeyMap) const { + uint32_t batchSize, + const std::map>& evalSumKeyMap) const { VerifyAdvancedSHEEnabled(__func__); if (!ciphertext) OPENFHE_THROW("Input first ciphertext is nullptr"); @@ -1256,7 +1257,7 @@ class SchemeBase { } virtual Ciphertext EvalMerge(const std::vector>& ciphertextVec, - const std::map>& evalKeyMap) const { + const std::map>& evalKeyMap) const { VerifyAdvancedSHEEnabled(__func__); if (!ciphertextVec.size()) OPENFHE_THROW("Input ciphertext vector is empty"); @@ -1302,16 +1303,18 @@ class SchemeBase { const PrivateKey newPrivateKey, const EvalKey evalKey) const; - virtual std::shared_ptr>> MultiEvalAutomorphismKeyGen( - const PrivateKey privateKey, const std::shared_ptr>> evalAutoKeyMap, - const std::vector& indexList, const std::string& keyId); + virtual std::shared_ptr>> MultiEvalAutomorphismKeyGen( + const PrivateKey privateKey, + const std::shared_ptr>> evalAutoKeyMap, + const std::vector& indexList, const std::string& keyId); - virtual std::shared_ptr>> MultiEvalAtIndexKeyGen( - const PrivateKey privateKey, const std::shared_ptr>> evalAutoKeyMap, + virtual std::shared_ptr>> MultiEvalAtIndexKeyGen( + const PrivateKey privateKey, + const std::shared_ptr>> evalAutoKeyMap, const std::vector& indexList, const std::string& keyId); - virtual std::shared_ptr>> MultiEvalSumKeyGen( - const PrivateKey privateKey, const std::shared_ptr>> evalSumKeyMap, + virtual std::shared_ptr>> MultiEvalSumKeyGen( + const PrivateKey privateKey, const std::shared_ptr>> evalSumKeyMap, const std::string& keyId = ""); virtual EvalKey MultiAddEvalKeys(EvalKey evalKey1, EvalKey evalKey2, @@ -1320,13 +1323,13 @@ class SchemeBase { virtual EvalKey MultiMultEvalKey(PrivateKey privateKey, EvalKey evalKey, const std::string& keyId); - virtual std::shared_ptr>> MultiAddEvalSumKeys( - const std::shared_ptr>> evalSumKeyMap1, - const std::shared_ptr>> evalSumKeyMap2, const std::string& keyId); + virtual std::shared_ptr>> MultiAddEvalSumKeys( + const std::shared_ptr>> evalSumKeyMap1, + const std::shared_ptr>> evalSumKeyMap2, const std::string& keyId); - virtual std::shared_ptr>> MultiAddEvalAutomorphismKeys( - const std::shared_ptr>> evalSumKeyMap1, - const std::shared_ptr>> evalSumKeyMap2, const std::string& keyId); + virtual std::shared_ptr>> MultiAddEvalAutomorphismKeys( + const std::shared_ptr>> evalSumKeyMap1, + const std::shared_ptr>> evalSumKeyMap2, const std::string& keyId); virtual PublicKey MultiAddPubKeys(PublicKey publicKey1, PublicKey publicKey2, const std::string& keyId); @@ -1387,8 +1390,8 @@ class SchemeBase { return; } - std::shared_ptr>> EvalBootstrapKeyGen(const PrivateKey privateKey, - uint32_t slots) { + std::shared_ptr>> EvalBootstrapKeyGen(const PrivateKey privateKey, + uint32_t slots) { VerifyFHEEnabled(__func__); return m_FHE->EvalBootstrapKeyGen(privateKey, slots); } @@ -1412,8 +1415,8 @@ class SchemeBase { return m_SchemeSwitch->EvalCKKStoFHEWSetup(params); } - std::shared_ptr>> EvalCKKStoFHEWKeyGen(const KeyPair& keyPair, - ConstLWEPrivateKey& lwesk) { + std::shared_ptr>> EvalCKKStoFHEWKeyGen(const KeyPair& keyPair, + ConstLWEPrivateKey& lwesk) { VerifySchemeSwitchEnabled(__func__); return m_SchemeSwitch->EvalCKKStoFHEWKeyGen(keyPair, lwesk); } @@ -1436,11 +1439,11 @@ class SchemeBase { return; } - std::shared_ptr>> EvalFHEWtoCKKSKeyGen(const KeyPair& keyPair, - ConstLWEPrivateKey& lwesk, - uint32_t numSlots = 0, - uint32_t numCtxts = 0, uint32_t dim1 = 0, - uint32_t L = 0) { + std::shared_ptr>> EvalFHEWtoCKKSKeyGen(const KeyPair& keyPair, + ConstLWEPrivateKey& lwesk, + uint32_t numSlots = 0, + uint32_t numCtxts = 0, uint32_t dim1 = 0, + uint32_t L = 0) { VerifySchemeSwitchEnabled(__func__); return m_SchemeSwitch->EvalFHEWtoCKKSKeyGen(keyPair, lwesk, numSlots, numCtxts, dim1, L); } @@ -1464,8 +1467,8 @@ class SchemeBase { return m_SchemeSwitch->EvalSchemeSwitchingSetup(params); } - std::shared_ptr>> EvalSchemeSwitchingKeyGen(const KeyPair& keyPair, - ConstLWEPrivateKey& lwesk) { + std::shared_ptr>> EvalSchemeSwitchingKeyGen(const KeyPair& keyPair, + ConstLWEPrivateKey& lwesk) { VerifySchemeSwitchEnabled(__func__); return m_SchemeSwitch->EvalSchemeSwitchingKeyGen(keyPair, lwesk); } @@ -1563,18 +1566,20 @@ class SchemeBase { // only works for JSON encoding // m_FHE was added in v1.1.2 try { - ar(::cereal::make_nvp("fhe", m_FHE)); - } catch(cereal::Exception&) { - m_FHE = nullptr; + ar(::cereal::make_nvp("fhe", m_FHE)); + } + catch (cereal::Exception&) { + m_FHE = nullptr; } // try-catch is used for backwards compatibility down to 1.0.x // only works for JSON encoding // m_SchemeSwitch was added in v1.1.3 try { - ar(::cereal::make_nvp("schswitch", m_SchemeSwitch)); - } catch(cereal::Exception&) { - m_SchemeSwitch = nullptr; + ar(::cereal::make_nvp("schswitch", m_SchemeSwitch)); + } + catch (cereal::Exception&) { + m_SchemeSwitch = nullptr; } uint32_t enabled = 0; diff --git a/src/pke/include/schemerns/rns-cryptoparameters.h b/src/pke/include/schemerns/rns-cryptoparameters.h index 869b104b4..2c2692c76 100644 --- a/src/pke/include/schemerns/rns-cryptoparameters.h +++ b/src/pke/include/schemerns/rns-cryptoparameters.h @@ -157,6 +157,30 @@ class CryptoParametersRNS : public CryptoParametersRLWE { virtual uint64_t FindAuxPrimeStep() const; + /* + * Estimates the extra modulus bitsize needed for hybrid key swithing (used for finding the minimum secure ring dimension). + * + * @param numPartQ number of digits in hybrid key switching + * @param firstModulusSize bit size of first modulus + * @param dcrtBits bit size for other moduli + * @param extraModulusSize bit size for extra modulus in FLEXIBLEAUTOEXT (CKKS and BGV only) + * @param numPrimes number of moduli witout extraModulus + * @param auxBits size of auxiliar moduli used for hybrid key switching + * + * @return log2 of the modulus and number of RNS limbs. + */ + static std::pair EstimateLogP(uint32_t numPartQ, double firstModulusSize, double dcrtBits, + double extraModulusSize, uint32_t numPrimes, uint32_t auxBits); + + /* + * Estimates the extra modulus bitsize needed for threshold FHE noise flooding (only for BGV and BFV) + * + * @return number of extra bits needed for noise flooding + */ + static constexpr double EstimateMultipartyFloodingLogQ() { + return static_cast(NoiseFlooding::MULTIPARTY_MOD_SIZE * NoiseFlooding::NUM_MODULI_MULTIPARTY); + } + /** * == operator to compare to this instance of CryptoParametersBase object. * @@ -625,12 +649,12 @@ class CryptoParametersRNS : public CryptoParametersRLWE { // BFVrns : Encrypt : POverQ ///////////////////////////////////// - const NativeInteger GetNegQModt() const { - return m_negQModt; + const NativeInteger GetNegQModt(uint32_t i = 0) const { + return m_negQModt[i]; } - const NativeInteger GetNegQModtPrecon() const { - return m_negQModtPrecon; + const NativeInteger GetNegQModtPrecon(uint32_t i = 0) const { + return m_negQModtPrecon[i]; } const NativeInteger GetNegQrModt() const { @@ -731,6 +755,14 @@ class CryptoParametersRNS : public CryptoParametersRLWE { return m_negRlQHatInvModqPrecon[l]; } + const std::vector& GetmNegRlQlHatInvModq(usint l = 0) const { + return m_negRlQlHatInvModq[l]; + } + + const std::vector& GetmNegRlQlHatInvModqPrecon(usint l = 0) const { + return m_negRlQlHatInvModqPrecon[l]; + } + const std::vector>& GetqInvModr() const { return m_qInvModr; } @@ -1464,8 +1496,8 @@ class CryptoParametersRNS : public CryptoParametersRLWE { // BFVrns : Encrypt ///////////////////////////////////// - NativeInteger m_negQModt; - NativeInteger m_negQModtPrecon; + std::vector m_negQModt; + std::vector m_negQModtPrecon; std::vector m_tInvModq; std::vector m_tInvModqPrecon; std::vector m_tInvModqr; @@ -1580,6 +1612,10 @@ class CryptoParametersRNS : public CryptoParametersRLWE { std::vector> m_negRlQHatInvModqPrecon; + std::vector> m_negRlQlHatInvModq; + + std::vector> m_negRlQlHatInvModqPrecon; + std::vector> m_qInvModr; ///////////////////////////////////// @@ -1774,8 +1810,9 @@ class CryptoParametersRNS : public CryptoParametersRLWE { // m_MPIntBootCiphertextCompressionLevel was added in v1.1.0 try { ar(cereal::make_nvp("ccl", m_MPIntBootCiphertextCompressionLevel)); - } catch(cereal::Exception&) { - m_MPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK; + } + catch (cereal::Exception&) { + m_MPIntBootCiphertextCompressionLevel = COMPRESSION_LEVEL::SLACK; } } diff --git a/src/pke/include/schemerns/rns-parametergeneration.h b/src/pke/include/schemerns/rns-parametergeneration.h index 16aa6925e..d7fadd179 100644 --- a/src/pke/include/schemerns/rns-parametergeneration.h +++ b/src/pke/include/schemerns/rns-parametergeneration.h @@ -87,8 +87,8 @@ class ParameterGenerationRNS : public ParameterGenerationBase { * @param numPartQ number of partitions of Q for HYBRID key switching * */ - bool ParamsGenCKKSRNS(std::shared_ptr> cryptoParams, usint cyclOrder, - usint numPrimes, usint scalingModSize, usint firstModSize, uint32_t mulPartQ, + bool ParamsGenCKKSRNS(std::shared_ptr> cryptoParams, uint32_t cyclOrder, + uint32_t numPrimes, uint32_t scalingModSize, uint32_t firstModSize, uint32_t mulPartQ, COMPRESSION_LEVEL mPIntBootCiphertextCompressionLevel) const override { OPENFHE_THROW("This signature for ParamsGen is not supported for this scheme."); } @@ -109,8 +109,8 @@ class ParameterGenerationRNS : public ParameterGenerationBase { * @param dcrtBits the bit-width of moduli. */ bool ParamsGenBGVRNS(std::shared_ptr> cryptoParams, uint32_t evalAddCount, - uint32_t keySwitchCount, usint cyclOrder, usint numPrimes, usint firstModSize, usint dcrtBits, - uint32_t numPartQ, usint multihopQBound) const override { + uint32_t keySwitchCount, uint32_t cyclOrder, uint32_t numPrimes, uint32_t firstModSize, + uint32_t dcrtBits, uint32_t numPartQ, uint32_t PRENumHops) const override { OPENFHE_THROW("This signature for ParamsGen is not supported for this scheme."); } diff --git a/src/pke/lib/constants-impl.cpp b/src/pke/lib/constants-impl.cpp index e8f826d15..2b99b81c4 100644 --- a/src/pke/lib/constants-impl.cpp +++ b/src/pke/lib/constants-impl.cpp @@ -138,8 +138,6 @@ ProxyReEncryptionMode convertToProxyReEncryptionMode(const std::string& str) { return FIXED_NOISE_HRA; else if (str == "NOISE_FLOODING_HRA") return NOISE_FLOODING_HRA; - else if (str == "DIVIDE_AND_ROUND_HRA") - return DIVIDE_AND_ROUND_HRA; std::string errMsg(std::string("Unknown ProxyReEncryptionMode ") + str); OPENFHE_THROW(errMsg); @@ -151,7 +149,6 @@ ProxyReEncryptionMode convertToProxyReEncryptionMode(uint32_t num) { case INDCPA: case FIXED_NOISE_HRA: case NOISE_FLOODING_HRA: - case DIVIDE_AND_ROUND_HRA: return encrMode; default: break; @@ -174,9 +171,6 @@ std::ostream& operator<<(std::ostream& s, ProxyReEncryptionMode p) { case NOISE_FLOODING_HRA: s << "NOISE_FLOODING_HRA"; break; - case DIVIDE_AND_ROUND_HRA: - s << "DIVIDE_AND_ROUND_HRA"; - break; default: s << "UNKNOWN"; break; diff --git a/src/pke/lib/cryptocontext.cpp b/src/pke/lib/cryptocontext.cpp index 823177c5c..e51e8fabc 100644 --- a/src/pke/lib/cryptocontext.cpp +++ b/src/pke/lib/cryptocontext.cpp @@ -145,10 +145,11 @@ std::shared_ptr>> CryptoContextImpl::E OPENFHE_THROW("Public key passed to EvalSumKeyGen does not match private key"); } - auto evalKeys = GetScheme()->EvalSumRowsKeyGen(privateKey, publicKey, rowSize, subringDim); + std::vector indices; + auto evalKeys = GetScheme()->EvalSumRowsKeyGen(privateKey, rowSize, subringDim, indices); CryptoContextImpl::InsertEvalAutomorphismKey(evalKeys, privateKey->GetKeyTag()); - return evalKeys; + return CryptoContextImpl::GetPartialEvalAutomorphismKeyMapPtr(privateKey->GetKeyTag(), indices); } template @@ -159,10 +160,11 @@ std::shared_ptr>> CryptoContextImpl::E OPENFHE_THROW("Public key passed to EvalSumKeyGen does not match private key"); } - auto evalKeys = GetScheme()->EvalSumColsKeyGen(privateKey, publicKey); + std::vector indices; + auto evalKeys = GetScheme()->EvalSumColsKeyGen(privateKey, indices); CryptoContextImpl::InsertEvalAutomorphismKey(evalKeys, privateKey->GetKeyTag()); - return evalKeys; // TODO (dsuponit): the return statement will stay for some time to ensure backward compatibility + return CryptoContextImpl::GetPartialEvalAutomorphismKeyMapPtr(privateKey->GetKeyTag(), indices); } template @@ -196,14 +198,32 @@ std::shared_ptr>> CryptoContextImpl::G const std::string& keyID) { auto ekv = CryptoContextImpl::s_evalAutomorphismKeyMap.find(keyID); if (ekv == CryptoContextImpl::s_evalAutomorphismKeyMap.end()) { - std::string errMsg( - std::string("Call EvalAutomorphismKeyGen() to have EvalAutomorphismKeys available for ID [") + keyID + - "]."); - OPENFHE_THROW(errMsg); + OPENFHE_THROW("EvalAutomorphismKeys are not generated for ID [" + keyID + "]."); } return ekv->second; } +template +std::shared_ptr>> CryptoContextImpl::GetPartialEvalAutomorphismKeyMapPtr( + const std::string& keyID, const std::vector& indexList) { + if (!indexList.size()) + OPENFHE_THROW("indexList is empty"); + + std::shared_ptr>> keyMap = + CryptoContextImpl::GetEvalAutomorphismKeyMapPtr(keyID); + + // create a return map if specific indices are provided + std::map> retMap; + for (uint32_t indx : indexList) { + const auto it = keyMap->find(indx); + if (it == keyMap->end()) { + OPENFHE_THROW("Key is not generated for index [" + std::to_string(indx) + "] and keyID [" + keyID + "]"); + } + retMap.emplace(indx, it->second); + } + return std::make_shared>>(retMap); +} + template std::map>>>& CryptoContextImpl::GetAllEvalSumKeys() { @@ -285,34 +305,30 @@ void CryptoContextImpl::ClearEvalAutomorphismKeys(const CryptoContext -std::vector CryptoContextImpl::GetExistingEvalAutomorphismKeyIndices(const std::string& keyTag) { +std::set CryptoContextImpl::GetExistingEvalAutomorphismKeyIndices(const std::string& keyTag) { auto keyMapIt = CryptoContextImpl::s_evalAutomorphismKeyMap.find(keyTag); if (keyMapIt == CryptoContextImpl::s_evalAutomorphismKeyMap.end()) // there is no keys for the given id, return empty vector - return std::vector(); + return std::set(); // get all inidices from the existing automorphism key map auto& keyMap = *(keyMapIt->second); - std::vector indices(keyMap.size()); + std::set indices; for (const auto& [key, _] : keyMap) { - indices.push_back(key); + indices.insert(key); } return indices; } template -std::vector CryptoContextImpl::GetUniqueValues(std::vector oldValues, - std::vector newValues) { - // sort both vectors - std::sort(oldValues.begin(), oldValues.end()); - std::sort(newValues.begin(), newValues.end()); - - std::vector uniqueValues; +std::set CryptoContextImpl::GetUniqueValues(const std::set& oldValues, + const std::set& newValues) { + std::set newUniqueValues; std::set_difference(newValues.begin(), newValues.end(), oldValues.begin(), oldValues.end(), - std::inserter(uniqueValues, uniqueValues.begin())); + std::inserter(newUniqueValues, newUniqueValues.begin())); - return uniqueValues; + return newUniqueValues; } template @@ -325,21 +341,21 @@ void CryptoContextImpl::InsertEvalAutomorphismKey( auto mapToInsertIt = mapToInsert->begin(); const std::string id = (keyTag.empty()) ? mapToInsertIt->second->GetKeyTag() : keyTag; - std::vector existingIndices{CryptoContextImpl::GetExistingEvalAutomorphismKeyIndices(id)}; + std::set existingIndices{CryptoContextImpl::GetExistingEvalAutomorphismKeyIndices(id)}; if (existingIndices.empty()) { // there is no keys for the given id, so we insert full mapToInsert CryptoContextImpl::s_evalAutomorphismKeyMap[id] = mapToInsert; } else { // get all indices from mapToInsert - std::vector newIndices(mapToInsert->size()); + std::set newIndices; for (const auto& [key, _] : *mapToInsert) { - newIndices.push_back(key); + newIndices.insert(key); } // find all indices in mapToInsert that are not in the exising map and // insert those new indices and their corresponding keys to the existing map - std::vector indicesToInsert{CryptoContextImpl::GetUniqueValues(existingIndices, newIndices)}; + std::set indicesToInsert{CryptoContextImpl::GetUniqueValues(existingIndices, newIndices)}; auto keyMapIt = CryptoContextImpl::s_evalAutomorphismKeyMap.find(id); auto& keyMap = *(keyMapIt->second); for (uint32_t indx : indicesToInsert) { @@ -358,23 +374,23 @@ Ciphertext CryptoContextImpl::EvalSum(ConstCiphertext } template -Ciphertext CryptoContextImpl::EvalSumRows(ConstCiphertext ciphertext, usint rowSize, +Ciphertext CryptoContextImpl::EvalSumRows(ConstCiphertext ciphertext, usint numRows, const std::map>& evalSumKeys, usint subringDim) const { ValidateCiphertext(ciphertext); - auto rv = GetScheme()->EvalSumRows(ciphertext, rowSize, evalSumKeys, subringDim); + auto rv = GetScheme()->EvalSumRows(ciphertext, numRows, evalSumKeys, subringDim); return rv; } template Ciphertext CryptoContextImpl::EvalSumCols( - ConstCiphertext ciphertext, usint rowSize, + ConstCiphertext ciphertext, usint numCols, const std::map>& evalSumKeysRight) const { ValidateCiphertext(ciphertext); auto evalSumKeys = CryptoContextImpl::GetEvalAutomorphismKeyMap(ciphertext->GetKeyTag()); - auto rv = GetScheme()->EvalSumCols(ciphertext, rowSize, evalSumKeys, evalSumKeysRight); + auto rv = GetScheme()->EvalSumCols(ciphertext, numCols, evalSumKeys, evalSumKeysRight); return rv; } diff --git a/src/pke/lib/encoding/coefpackedencoding.cpp b/src/pke/lib/encoding/coefpackedencoding.cpp index 2daed9f89..afd9f4865 100644 --- a/src/pke/lib/encoding/coefpackedencoding.cpp +++ b/src/pke/lib/encoding/coefpackedencoding.cpp @@ -53,7 +53,7 @@ inline static void encodeVec(P& poly, const PlaintextModulus& mod, int64_t lb, i typename P::Integer entry{value[i]}; if (value[i] < 0) { - if (schemeID == SCHEME::BFVRNS_SCHEME) { + if (isBFVRNS(schemeID)) { // TODO: Investigate why this doesn't work with q instead of t. uint64_t adjustedVal{mod - static_cast(llabs(value[i]))}; entry = typename P::Integer(adjustedVal); @@ -88,6 +88,7 @@ bool CoefPackedEncoding::Encode() { if (this->typeFlag == IsDCRTPoly) { this->encodedVectorDCRT = this->encodedVector; encodedVectorDCRT = encodedVectorDCRT.Times(scalingFactorInt); + this->encodedVectorDCRT.SetFormat(Format::EVALUATION); } this->isEncoded = true; diff --git a/src/pke/lib/encoding/packedencoding.cpp b/src/pke/lib/encoding/packedencoding.cpp index 4c98780af..62a4b26e9 100644 --- a/src/pke/lib/encoding/packedencoding.cpp +++ b/src/pke/lib/encoding/packedencoding.cpp @@ -54,81 +54,84 @@ bool PackedEncoding::Encode() { auto mod = this->encodingParams->GetPlaintextModulus(); if ((this->typeFlag == IsNativePoly) || (this->typeFlag == IsDCRTPoly)) { - NativeInteger q; - - NativeVector temp; - if (this->typeFlag == IsNativePoly) { - q = this->GetElementModulus().ConvertToInt(); - temp = NativeVector(this->GetElementRingDimension(), this->GetElementModulus().ConvertToInt()); - } - else { - q = this->encodedVectorDCRT.GetParams()->GetParams()[0]->GetModulus().ConvertToInt(); - temp = NativeVector(this->GetElementRingDimension(), q); - if (q < mod) - OPENFHE_THROW( - "the plaintext modulus size is larger than the size of " - "CRT moduli; either decrease the plaintext modulus or " - "increase the CRT moduli."); - } - size_t i; + NativeVector tempVector = NativeVector(this->GetElementRingDimension(), mod); + NativeInteger originalSF = scalingFactorInt; for (size_t j = 1; j < noiseScaleDeg; j++) { scalingFactorInt = scalingFactorInt.ModMul(originalSF, mod); } for (i = 0; i < value.size(); i++) { - NativeInteger entry; - - if ((PlaintextModulus)llabs(value[i]) >= mod) + if ((PlaintextModulus)llabs(value[i]) >= mod) { OPENFHE_THROW("Cannot encode integer " + std::to_string(value[i]) + " at position " + std::to_string(i) + " that is > plaintext modulus " + std::to_string(mod)); + } if (value[i] < 0) { // It is more efficient to encode negative numbers using the ciphertext // modulus no noise growth occurs - entry = NativeInteger(mod) - NativeInteger((uint64_t)llabs(value[i])); + tempVector[i] = NativeInteger(mod) - NativeInteger((uint64_t)llabs(value[i])); } else { - entry = NativeInteger(value[i]); + tempVector[i] = NativeInteger(value[i]); } - - temp[i] = entry.ModMul(scalingFactorInt, mod); } - for (; i < this->GetElementRingDimension(); i++) - temp[i] = NativeInteger(0); - this->isEncoded = true; + // no need to do extra multiplications for many scenarios when the scaling factor is 1, e.g., in BFV + if (scalingFactorInt != 1) { + tempVector.ModMulEq(scalingFactorInt); + } if (this->typeFlag == IsNativePoly) { - // the input plaintext data is in the evaluation format - this->GetElement().SetValues(std::move(temp), Format::EVALUATION); - // ilVector coefficients are packed and resulting ilVector is in - // COEFFICIENT form. - this->Pack(&this->GetElement(), this->encodingParams->GetPlaintextModulus()); + PlaintextModulus q = this->GetElementModulus().ConvertToInt(); + if (q < mod) { + OPENFHE_THROW( + "the plaintext modulus size is larger than the size of " + "NativePoly modulus; increase the NativePoly modulus."); + } + + // Calls the inverse NTT mod plaintext modulus + this->PackNativeVector(this->encodingParams->GetPlaintextModulus(), + this->encodedNativeVector.GetCyclotomicOrder(), &tempVector); + tempVector.SetModulus(q); + this->encodedNativeVector.SetValues(std::move(tempVector), Format::COEFFICIENT); } else { + PlaintextModulus q = this->encodedVectorDCRT.GetParams()->GetParams()[0]->GetModulus().ConvertToInt(); + if (q < mod) { + OPENFHE_THROW( + "the plaintext modulus size is larger than the size of " + "CRT moduli; either decrease the plaintext modulus or " + "increase the CRT moduli."); + } + + // Calls the inverse NTT mod plaintext modulus + this->PackNativeVector(this->encodingParams->GetPlaintextModulus(), + this->encodedVectorDCRT.GetCyclotomicOrder(), &tempVector); + // Switches from plaintext modulus to the modulus of the first RNS limb + tempVector.SetModulus(q); NativePoly firstElement = this->GetElement().GetElementAtIndex(0); - // the input plaintext data is in the evaluation format - firstElement.SetValues(std::move(temp), Format::EVALUATION); - // ilVector coefficients are packed and resulting ilVector is in - // COEFFICIENT form. - this->Pack(&firstElement, this->encodingParams->GetPlaintextModulus()); - this->encodedVectorDCRT.SetElementAtIndex(0, firstElement); + firstElement.SetValues(std::move(tempVector), Format::COEFFICIENT); const std::shared_ptr> params = this->encodedVectorDCRT.GetParams(); const std::vector>& nativeParams = params->GetParams(); + // Sets the values for all other RNS limbs for (size_t ii = 1; ii < nativeParams.size(); ii++) { - NativePoly temp(firstElement); + NativePoly tempPoly(firstElement); - temp.SwitchModulus(nativeParams[ii]->GetModulus(), nativeParams[ii]->GetRootOfUnity(), - nativeParams[ii]->GetBigModulus(), nativeParams[ii]->GetBigRootOfUnity()); + tempPoly.SwitchModulus(nativeParams[ii]->GetModulus(), nativeParams[ii]->GetRootOfUnity(), + nativeParams[ii]->GetBigModulus(), nativeParams[ii]->GetBigRootOfUnity()); - this->encodedVectorDCRT.SetElementAtIndex(ii, std::move(temp)); + this->encodedVectorDCRT.SetElementAtIndex(ii, std::move(tempPoly)); } + // Setting the first limb at the end make sure firstElement is available during the main loop + this->encodedVectorDCRT.SetElementAtIndex(0, std::move(firstElement)); + this->encodedVectorDCRT.SetFormat(Format::EVALUATION); } + this->isEncoded = true; } else { BigVector temp(this->GetElementRingDimension(), BigInteger(this->GetElementModulus())); @@ -157,7 +160,6 @@ bool PackedEncoding::Encode() { for (; i < this->GetElementRingDimension(); i++) temp[i] = BigInteger(0); - this->isEncoded = true; // the input plaintext data is in the evaluation format this->GetElement().SetValues(std::move(temp), Format::EVALUATION); @@ -165,6 +167,8 @@ bool PackedEncoding::Encode() { // ilVector coefficients are packed and resulting ilVector is in COEFFICIENT // form. this->Pack(&this->GetElement(), this->encodingParams->GetPlaintextModulus()); + + this->isEncoded = true; } return true; @@ -383,9 +387,51 @@ void PackedEncoding::Pack(P* ring, const PlaintextModulus& modulus) const { } ring->SetValues(std::move(slotValuesRing), Format::COEFFICIENT); + OPENFHE_DEBUG(*ring); } +void PackedEncoding::PackNativeVector(const PlaintextModulus& modulus, uint32_t m, NativeVector* values) const { + NativeVector& slotValues = *values; + NativeInteger modulusNI(modulus); // native int modulus + usint phim = slotValues.GetLength(); + + const ModulusM modulusM = {modulusNI, m}; + + // Do the precomputation if not initialized + if (this->m_initRoot[modulusM].GetMSB() == 0) { + SetParams(m, EncodingParams(std::make_shared(modulus))); + } + + // Transform Eval to Coeff + if (IsPowerOfTwo(m)) { + if (m_toCRTPerm[m].size() > 0) { + // Permute to CRT Order + NativeVector permutedSlots(phim, modulusNI); + + for (usint i = 0; i < phim; i++) { + permutedSlots[i] = slotValues[m_toCRTPerm[m][i]]; + } + ChineseRemainderTransformFTT().InverseTransformFromBitReverse( + permutedSlots, m_initRoot[modulusM], m, &slotValues); + } + else { + ChineseRemainderTransformFTT().InverseTransformFromBitReverse( + slotValues, m_initRoot[modulusM], m, &slotValues); + } + } + else { // Arbitrary cyclotomic + // Permute to CRT Order + NativeVector permutedSlots(phim, modulusNI); + for (usint i = 0; i < phim; i++) { + permutedSlots[i] = slotValues[m_toCRTPerm[m][i]]; + } + + slotValues = ChineseRemainderTransformArb().InverseTransform( + permutedSlots, m_initRoot[modulusM], m_bigModulus[modulusM], m_bigRoot[modulusM], m); + } +} + template void PackedEncoding::Unpack(P* ring, const PlaintextModulus& modulus) const { OPENFHE_DEBUG_FLAG(false); diff --git a/src/pke/lib/scheme/bfvrns/bfvrns-cryptoparameters.cpp b/src/pke/lib/scheme/bfvrns/bfvrns-cryptoparameters.cpp index 50ee180a3..a3f3a297b 100644 --- a/src/pke/lib/scheme/bfvrns/bfvrns-cryptoparameters.cpp +++ b/src/pke/lib/scheme/bfvrns/bfvrns-cryptoparameters.cpp @@ -76,9 +76,20 @@ void CryptoParametersBFVRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scal NativeInteger modulusr = PreviousPrime(moduliQ[sizeQ - 1], 2 * n); NativeInteger rootr = RootOfUnity(2 * n, modulusr); - m_negQModt = modulusQ.Mod(BigInteger(GetPlaintextModulus())).ConvertToInt(); - m_negQModt = t.Sub(m_negQModt); - m_negQModtPrecon = m_negQModt.PrepModMulConst(t); + BigInteger tmpModulusQ = modulusQ; + + m_negQModt.clear(); + m_negQModtPrecon.clear(); + m_negQModt.resize(sizeQ); + m_negQModtPrecon.resize(sizeQ); + for (size_t l = 0; l < sizeQ; l++) { + if (l > 0) + tmpModulusQ = tmpModulusQ / BigInteger(moduliQ[sizeQ - l]); + + m_negQModt[l] = tmpModulusQ.Mod(BigInteger(GetPlaintextModulus())).ConvertToInt(); + m_negQModt[l] = t.Sub(m_negQModt[l]); + m_negQModtPrecon[l] = m_negQModt[l].PrepModMulConst(t); + } // BFVrns : Encrypt : With extra if (encTech == EXTENDED) { @@ -134,7 +145,7 @@ void CryptoParametersBFVRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scal // Pre-compute values [Ql/q_i]_{r_j} // Pre-compute values [(Ql/q_i)^{-1}]_{q_i} - BigInteger tmpModulusQ = modulusQ; + tmpModulusQ = modulusQ; if (multTech == HPSPOVERQLEVELED || multTech == HPSPOVERQ) { m_QlHatInvModq.resize(sizeQ); @@ -477,6 +488,7 @@ void CryptoParametersBFVRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scal ///////////////////////////////////// if (multTech == HPSPOVERQ || multTech == HPSPOVERQLEVELED) { + // Scenario when we go from Q to P_l m_negRlQHatInvModq.resize(sizeR); m_negRlQHatInvModqPrecon.resize(sizeR); for (usint l = sizeR; l > 0; l--) { @@ -490,6 +502,23 @@ void CryptoParametersBFVRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scal m_negRlQHatInvModqPrecon[l - 1][i] = m_negRlQHatInvModq[l - 1][i].PrepModMulConst(moduliQ[i]); } } + + // Scenario when we go from Q_l to P_l + m_negRlQlHatInvModq.resize(sizeR); + m_negRlQlHatInvModqPrecon.resize(sizeR); + BigInteger modulusQtmp = modulusQ; + for (usint l = sizeR; l > 0; l--) { + m_negRlQlHatInvModq[l - 1].resize(l); + m_negRlQlHatInvModqPrecon[l - 1].resize(l); + for (usint i = 0; i < l; i++) { + BigInteger QlHati = modulusQtmp / BigInteger(moduliQ[i]); + BigInteger QlHatInvModqi = QlHati.ModInverse(moduliQ[i]); + m_negRlQlHatInvModq[l - 1][i] = Rl[l].ModMul(QlHatInvModqi, moduliQ[i]).ConvertToInt(); + m_negRlQlHatInvModq[l - 1][i] = moduliQ[i].Sub(m_negRlQlHatInvModq[l - 1][i]); + m_negRlQlHatInvModqPrecon[l - 1][i] = m_negRlQlHatInvModq[l - 1][i].PrepModMulConst(moduliQ[i]); + } + modulusQtmp = modulusQtmp / BigInteger(moduliQ[l - 1]); + } } m_qInvModr.resize(sizeQ); @@ -506,7 +535,7 @@ void CryptoParametersBFVRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scal // BFVrns : Mult : ScaleAndRoundP ///////////////////////////////////// - if (multTech == HPS || multTech == HPSPOVERQ) { + if (multTech == HPS) { m_tQlSlHatInvModsDivsFrac.resize(1); m_tQlSlHatInvModsDivsFrac[0].resize(sizeR); @@ -533,7 +562,7 @@ void CryptoParametersBFVRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scal m_tQlSlHatInvModsDivsModq[0][i][sizeR] = tQlSlHatInvModsDivs.Mod(qi).ConvertToInt(); } } - else if (multTech == HPSPOVERQLEVELED) { + else if ((multTech == HPSPOVERQ) || (multTech == HPSPOVERQLEVELED)) { m_tQlSlHatInvModsDivsFrac.resize(sizeQ); m_tQlSlHatInvModsDivsModq.resize(sizeQ); diff --git a/src/pke/lib/scheme/bfvrns/bfvrns-leveledshe.cpp b/src/pke/lib/scheme/bfvrns/bfvrns-leveledshe.cpp index 446ddf84b..48b7c8d9b 100644 --- a/src/pke/lib/scheme/bfvrns/bfvrns-leveledshe.cpp +++ b/src/pke/lib/scheme/bfvrns/bfvrns-leveledshe.cpp @@ -45,36 +45,48 @@ BFV implementation. See https://eprint.iacr.org/2021/204 for details. namespace lbcrypto { void LeveledSHEBFVRNS::EvalAddInPlace(Ciphertext& ciphertext, ConstPlaintext plaintext) const { - const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); - std::vector& cv = ciphertext->GetElements(); + const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); - DCRTPoly pt = plaintext->GetElement(); + auto pt = plaintext->GetElement(); pt.SetFormat(COEFFICIENT); - const NativeInteger& NegQModt = cryptoParams->GetNegQModt(); - const NativeInteger& NegQModtPrecon = cryptoParams->GetNegQModtPrecon(); - const std::vector& tInvModq = cryptoParams->GettInvModq(); - const NativeInteger t = cryptoParams->GetPlaintextModulus(); + + // enables encoding of plaintexts using a smaller number of RNS limbs + auto sizeQ = cryptoParams->GetElementParams()->GetParams().size(); + auto sizeP = pt.GetParams()->GetParams().size(); + auto level = sizeQ - sizeP; + + auto&& NegQModt = cryptoParams->GetNegQModt(level); + auto&& NegQModtPrecon = cryptoParams->GetNegQModtPrecon(level); + auto&& tInvModq = cryptoParams->GettInvModq(); + auto&& t = cryptoParams->GetPlaintextModulus(); pt.TimesQovert(cryptoParams->GetElementParams(), tInvModq, t, NegQModt, NegQModtPrecon); pt.SetFormat(EVALUATION); - cv[0] += pt; + + ciphertext->GetElements()[0] += pt; } void LeveledSHEBFVRNS::EvalSubInPlace(Ciphertext& ciphertext, ConstPlaintext plaintext) const { - const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); - std::vector& cv = ciphertext->GetElements(); + const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); - DCRTPoly pt = plaintext->GetElement(); + auto pt = plaintext->GetElement(); pt.SetFormat(COEFFICIENT); - const NativeInteger& NegQModt = cryptoParams->GetNegQModt(); - const NativeInteger& NegQModtPrecon = cryptoParams->GetNegQModtPrecon(); - const std::vector& tInvModq = cryptoParams->GettInvModq(); - const NativeInteger t = cryptoParams->GetPlaintextModulus(); + + // enables encoding of plaintexts using a smaller number of RNS limbs + auto sizeQ = cryptoParams->GetElementParams()->GetParams().size(); + auto sizeP = pt.GetParams()->GetParams().size(); + auto level = sizeQ - sizeP; + + auto&& NegQModt = cryptoParams->GetNegQModt(level); + auto&& NegQModtPrecon = cryptoParams->GetNegQModtPrecon(level); + auto&& tInvModq = cryptoParams->GettInvModq(); + auto&& t = cryptoParams->GetPlaintextModulus(); pt.TimesQovert(cryptoParams->GetElementParams(), tInvModq, t, NegQModt, NegQModtPrecon); pt.SetFormat(EVALUATION); - cv[0] -= pt; + + ciphertext->GetElements()[0] -= pt; } -uint32_t FindLevelsToDrop(usint multiplicativeDepth, std::shared_ptr> cryptoParams, +uint32_t FindLevelsToDrop(uint32_t multiplicativeDepth, std::shared_ptr> cryptoParams, uint32_t dcrtBits, bool keySwitch = false) { const auto cryptoParamsBFVrns = std::dynamic_pointer_cast(cryptoParams); double sigma = cryptoParamsBFVrns->GetDistributionParameter(); @@ -90,17 +102,17 @@ uint32_t FindLevelsToDrop(usint multiplicativeDepth, std::shared_ptrGetThresholdNumOfParties(); // Bound of the Gaussian error polynomial - double Berr = sigma * sqrt(alpha); + double Berr = sigma * std::sqrt(alpha); // Bkey set to thresholdParties * 1 for ternary distribution const double Bkey = - (cryptoParamsBFVrns->GetSecretKeyDist() == GAUSSIAN) ? sqrt(thresholdParties) * Berr : thresholdParties; + (cryptoParamsBFVrns->GetSecretKeyDist() == GAUSSIAN) ? std::sqrt(thresholdParties) * Berr : thresholdParties; - double w = relinWindow == 0 ? pow(2, dcrtBits) : pow(2, relinWindow); + double w = std::pow(2, relinWindow == 0 ? dcrtBits : relinWindow); // expansion factor delta auto delta = [](uint32_t n) -> double { - return (2. * sqrt(n)); + return (2. * std::sqrt(n)); }; // norm of fresh ciphertext polynomial (for EXTENDED the noise is reduced to modulus switching noise) @@ -113,9 +125,11 @@ uint32_t FindLevelsToDrop(usint multiplicativeDepth, std::shared_ptr double { if (scalTechnique == HYBRID) - return k * (numPartQ * delta(n) * Berr + delta(n) * Bkey + 1.0) / 2; - else - return delta(n) * (floor(logqPrev / (log(2) * dcrtBits)) + 1) * w * Berr; + return k * (numPartQ * delta(n) * Berr + delta(n) * Bkey + 1.0) / 2.0; + else { + double numDigitsPerTower = (relinWindow == 0) ? 1 : ((dcrtBits / relinWindow) + 1); + return delta(n) * numDigitsPerTower * (floor(logqPrev / (log(2) * dcrtBits)) + 1) * w * Berr / 2.0; + } }; // function used in the EvalMult constraint @@ -180,10 +194,13 @@ Ciphertext LeveledSHEBFVRNS::EvalMult(ConstCiphertext cipher std::vector cv1 = ciphertext1->GetElements(); std::vector cv2 = ciphertext2->GetElements(); - size_t cv1Size = cv1.size(); - size_t cv2Size = cv2.size(); - size_t cvMultSize = cv1Size + cv2Size - 1; - size_t sizeQ = cv1[0].GetNumOfElements(); + size_t cv1Size = cv1.size(); + size_t cv2Size = cv2.size(); + size_t cvMultSize = cv1Size + cv2Size - 1; + size_t sizeQ = cv1[0].GetNumOfElements(); + const auto elementParams = cryptoParams->GetElementParams(); + // Maximum number of RNS limbs in the crypto context + size_t sizeQM = elementParams->GetParams().size(); // l is index corresponding to leveled parameters in cryptoParameters precomputations in HPSPOVERQLEVELED size_t l = 0; @@ -205,9 +222,10 @@ Ciphertext LeveledSHEBFVRNS::EvalMult(ConstCiphertext cipher cryptoParams->GetModrBarrettMu(), cryptoParams->GetqInv(), Format::EVALUATION); } } - else if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQ) { + else if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQ) || + ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQ < sizeQM))) { for (size_t i = 0; i < cv1Size; i++) { - // Expand ciphertext1 from basis Q to PQ. + // Expand ciphertext1 from basis Q to PQ (from Q_l to P_l*Q_l if manual compress/lower-level-encode was called) cv1[i].ExpandCRTBasis(cryptoParams->GetParamsQlRl(sizeQ - 1), cryptoParams->GetParamsRl(sizeQ - 1), cryptoParams->GetQlHatInvModq(sizeQ - 1), cryptoParams->GetQlHatInvModqPrecon(sizeQ - 1), cryptoParams->GetQlHatModr(sizeQ - 1), @@ -215,24 +233,22 @@ Ciphertext LeveledSHEBFVRNS::EvalMult(ConstCiphertext cipher cryptoParams->GetqInv(), Format::EVALUATION); } - size_t sizeQ = cv2[0].GetNumOfElements(); - DCRTPoly::CRTBasisExtensionPrecomputations basisPQ( cryptoParams->GetParamsQlRl(sizeQ - 1), cryptoParams->GetParamsRl(sizeQ - 1), - cryptoParams->GetParamsQl(sizeQ - 1), cryptoParams->GetmNegRlQHatInvModq(sizeQ - 1), - cryptoParams->GetmNegRlQHatInvModqPrecon(sizeQ - 1), cryptoParams->GetqInvModr(), + cryptoParams->GetParamsQl(sizeQ - 1), cryptoParams->GetmNegRlQlHatInvModq(sizeQ - 1), + cryptoParams->GetmNegRlQlHatInvModqPrecon(sizeQ - 1), cryptoParams->GetqInvModr(), cryptoParams->GetModrBarrettMu(), cryptoParams->GetRlHatInvModr(sizeQ - 1), cryptoParams->GetRlHatInvModrPrecon(sizeQ - 1), cryptoParams->GetRlHatModq(sizeQ - 1), cryptoParams->GetalphaRlModq(sizeQ - 1), cryptoParams->GetModqBarrettMu(), cryptoParams->GetrInv()); for (size_t i = 0; i < cv2Size; i++) { cv2[i].SetFormat(Format::COEFFICIENT); - // Switch ciphertext2 from basis Q to P to PQ. + // Switch ciphertext2 from basis Q to P to PQ (from Q_l to P_l to P_l*Q_l if manual compress/lower-level-encode was called). cv2[i].FastExpandCRTBasisPloverQ(basisPQ); cv2[i].SetFormat(Format::EVALUATION); } } - else if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) { + else if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQ == sizeQM)) { size_t c1depth = ciphertext1->GetNoiseScaleDeg(); size_t c2depth = ciphertext2->GetNoiseScaleDeg(); @@ -251,7 +267,7 @@ Ciphertext LeveledSHEBFVRNS::EvalMult(ConstCiphertext cipher cv1[i].ScaleAndRound(cryptoParams->GetParamsQl(l), cryptoParams->GetQlQHatInvModqDivqModq(l), cryptoParams->GetQlQHatInvModqDivqFrac(l), cryptoParams->GetModqBarrettMu()); } - // Expand ciphertext1 from basis Q_l to PQ_l. + // Expand ciphertext1 from basis Q_l to P_l*Q_l. cv1[i].ExpandCRTBasis(cryptoParams->GetParamsQlRl(l), cryptoParams->GetParamsRl(l), cryptoParams->GetQlHatInvModq(l), cryptoParams->GetQlHatInvModqPrecon(l), cryptoParams->GetQlHatModr(l), cryptoParams->GetalphaQlModr(l), @@ -267,7 +283,7 @@ Ciphertext LeveledSHEBFVRNS::EvalMult(ConstCiphertext cipher for (size_t i = 0; i < cv2Size; i++) { cv2[i].SetFormat(Format::COEFFICIENT); - // Switch ciphertext2 from basis Q to P to PQ. + // Switch ciphertext2 from basis Q to P_l to P_l*Q_l. cv2[i].FastExpandCRTBasisPloverQ(basisPQ); cv2[i].SetFormat(Format::EVALUATION); } @@ -354,21 +370,23 @@ Ciphertext LeveledSHEBFVRNS::EvalMult(ConstCiphertext cipher cryptoParams->GetrInv()); } } - else if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQ) { + else if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQ) || + ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQ < sizeQM))) { + l = sizeQ - 1; for (size_t i = 0; i < cvMultSize; i++) { cvMult[i].SetFormat(COEFFICIENT); // Performs the scaling by t/P followed by rounding; the result is in the - // CRT basis Q + // CRT basis Q (Q_l if compress/lower-level encode was used) cvMult[i] = - cvMult[i].ScaleAndRound(cryptoParams->GetElementParams(), cryptoParams->GettQlSlHatInvModsDivsModq(0), - cryptoParams->GettQlSlHatInvModsDivsFrac(0), cryptoParams->GetModqBarrettMu()); + cvMult[i].ScaleAndRound(cryptoParams->GetParamsQl(l), cryptoParams->GettQlSlHatInvModsDivsModq(l), + cryptoParams->GettQlSlHatInvModsDivsFrac(l), cryptoParams->GetModqBarrettMu()); } } - else if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) { + else if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQ == sizeQM)) { for (size_t i = 0; i < cvMultSize; i++) { cvMult[i].SetFormat(COEFFICIENT); // Performs the scaling by t/P followed by rounding; the result is in the - // CRT basis Q + // CRT basis Ql cvMult[i] = cvMult[i].ScaleAndRound(cryptoParams->GetParamsQl(l), cryptoParams->GettQlSlHatInvModsDivsModq(l), cryptoParams->GettQlSlHatInvModsDivsFrac(l), cryptoParams->GetModqBarrettMu()); @@ -415,9 +433,13 @@ Ciphertext LeveledSHEBFVRNS::EvalSquare(ConstCiphertext ciph std::vector cv = ciphertext->GetElements(); - size_t cvSize = cv.size(); - size_t cvSqSize = 2 * cvSize - 1; - size_t sizeQ = cv[0].GetNumOfElements(); + size_t cvSize = cv.size(); + size_t cvSqSize = 2 * cvSize - 1; + size_t sizeQ = cv[0].GetNumOfElements(); + const auto elementParams = cryptoParams->GetElementParams(); + // Maximum number of RNS limbs in the crypto context + size_t sizeQM = elementParams->GetParams().size(); + // l is index corresponding to leveled parameters in cryptoParameters precomputations in HPSPOVERQLEVELED size_t l = 0; @@ -430,7 +452,8 @@ Ciphertext LeveledSHEBFVRNS::EvalSquare(ConstCiphertext ciph cryptoParams->GetModrBarrettMu(), cryptoParams->GetqInv(), Format::EVALUATION); } } - else if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQ) { + else if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQ) || + ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQ < sizeQM))) { cvPoverQ = cv; for (size_t i = 0; i < cvSize; i++) { // Expand ciphertext1 from basis Q to PQ. @@ -443,20 +466,20 @@ Ciphertext LeveledSHEBFVRNS::EvalSquare(ConstCiphertext ciph DCRTPoly::CRTBasisExtensionPrecomputations basisPQ( cryptoParams->GetParamsQlRl(sizeQ - 1), cryptoParams->GetParamsRl(sizeQ - 1), - cryptoParams->GetParamsQl(sizeQ - 1), cryptoParams->GetmNegRlQHatInvModq(sizeQ - 1), - cryptoParams->GetmNegRlQHatInvModqPrecon(sizeQ - 1), cryptoParams->GetqInvModr(), + cryptoParams->GetParamsQl(sizeQ - 1), cryptoParams->GetmNegRlQlHatInvModq(sizeQ - 1), + cryptoParams->GetmNegRlQlHatInvModqPrecon(sizeQ - 1), cryptoParams->GetqInvModr(), cryptoParams->GetModrBarrettMu(), cryptoParams->GetRlHatInvModr(sizeQ - 1), cryptoParams->GetRlHatInvModrPrecon(sizeQ - 1), cryptoParams->GetRlHatModq(sizeQ - 1), cryptoParams->GetalphaRlModq(sizeQ - 1), cryptoParams->GetModqBarrettMu(), cryptoParams->GetrInv()); for (size_t i = 0; i < cvSize; i++) { cvPoverQ[i].SetFormat(Format::COEFFICIENT); - // Switch ciphertext2 from basis Q to P to PQ. + // Switch ciphertext2 from basis Q to P to PQ (from Q_l to P_l to P_l*Q_l if manual compress/lower-level-encode was called). cvPoverQ[i].FastExpandCRTBasisPloverQ(basisPQ); cvPoverQ[i].SetFormat(Format::EVALUATION); } } - else if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) { + else if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQ == sizeQM)) { size_t cdepth = ciphertext->GetNoiseScaleDeg(); size_t levels = cdepth - 1; double dcrtBits = cv[0].GetElementAtIndex(0).GetModulus().GetMSB(); @@ -538,8 +561,8 @@ Ciphertext LeveledSHEBFVRNS::EvalSquare(ConstCiphertext ciph DCRTPoly cvtemp; if (cryptoParams->GetMultiplicationTechnique() == HPS || cryptoParams->GetMultiplicationTechnique() == BEHZ) { - for (size_t i = 0; i < cv.size(); i++) { - for (size_t j = i; j < cv.size(); j++) { + for (size_t i = 0; i < cvSize; i++) { + for (size_t j = i; j < cvSize; j++) { if (isFirstAdd[i + j] == true) { if (j == i) { cvSquare[i + j] = cv[i] * cv[j]; @@ -583,8 +606,8 @@ Ciphertext LeveledSHEBFVRNS::EvalSquare(ConstCiphertext ciph DCRTPoly cvtemp; if (cryptoParams->GetMultiplicationTechnique() == HPS || cryptoParams->GetMultiplicationTechnique() == BEHZ) { - for (size_t i = 0; i < cv.size(); i++) { - for (size_t j = i; j < cv.size(); j++) { + for (size_t i = 0; i < cvSize; i++) { + for (size_t j = i; j < cvSize; j++) { if (isFirstAdd[i + j] == true) { if (j == i) { cvSquare[i + j] = cv[i] * cv[j]; @@ -641,17 +664,19 @@ Ciphertext LeveledSHEBFVRNS::EvalSquare(ConstCiphertext ciph cryptoParams->GetModqBarrettMu(), cryptoParams->GetrInv()); } } - else if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQ) { + else if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQ) || + ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQ < sizeQM))) { + l = sizeQ - 1; for (size_t i = 0; i < cvSqSize; i++) { cvSquare[i].SetFormat(COEFFICIENT); // Performs the scaling by t/P followed by rounding; the result is in the - // CRT basis Q + // CRT basis Q (Q_l if compress/lower-level encode was used) cvSquare[i] = cvSquare[i].ScaleAndRound( - cryptoParams->GetElementParams(), cryptoParams->GettQlSlHatInvModsDivsModq(0), - cryptoParams->GettQlSlHatInvModsDivsFrac(0), cryptoParams->GetModqBarrettMu()); + cryptoParams->GetParamsQl(l), cryptoParams->GettQlSlHatInvModsDivsModq(l), + cryptoParams->GettQlSlHatInvModsDivsFrac(l), cryptoParams->GetModqBarrettMu()); } } - else if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) { + else if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQ == sizeQM)) { for (size_t i = 0; i < cvSqSize; i++) { cvSquare[i].SetFormat(COEFFICIENT); // Performs the scaling by t/P followed by rounding; the result is in the @@ -723,36 +748,25 @@ void LeveledSHEBFVRNS::EvalSquareInPlace(Ciphertext& ciphertext, const void LeveledSHEBFVRNS::EvalMultCoreInPlace(Ciphertext& ciphertext, const NativeInteger& constant) const { const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); - - std::vector& cv = ciphertext->GetElements(); - for (usint i = 0; i < cv.size(); ++i) { - cv[i] *= constant; - } - const NativeInteger t(cryptoParams->GetPlaintextModulus()); - + for (auto& cvi : ciphertext->GetElements()) + cvi *= constant; ciphertext->SetNoiseScaleDeg(ciphertext->GetNoiseScaleDeg() + 1); } -Ciphertext LeveledSHEBFVRNS::EvalAutomorphism(ConstCiphertext ciphertext, usint i, - const std::map>& evalKeyMap, +Ciphertext LeveledSHEBFVRNS::EvalAutomorphism(ConstCiphertext ciphertext, uint32_t i, + const std::map>& evalKeyMap, CALLER_INFO_ARGS_CPP) const { - const std::vector& cv = ciphertext->GetElements(); - - usint N = cv[0].GetRingDimension(); + uint32_t N = ciphertext->GetElements()[0].GetRingDimension(); - std::vector vec(N); + std::vector vec(N); PrecomputeAutoMap(N, i, &vec); - auto algo = ciphertext->GetCryptoContext()->GetScheme(); - - Ciphertext result = ciphertext->Clone(); - + auto result = ciphertext->Clone(); RelinearizeCore(result, evalKeyMap.at(i)); - std::vector& rcv = result->GetElements(); - - rcv[0] = rcv[0].AutomorphismTransform(i, vec); - rcv[1] = rcv[1].AutomorphismTransform(i, vec); + auto& rcv = result->GetElements(); + rcv[0] = rcv[0].AutomorphismTransform(i, vec); + rcv[1] = rcv[1].AutomorphismTransform(i, vec); return result; } @@ -762,28 +776,36 @@ std::shared_ptr> LeveledSHEBFVRNS::EvalFastRotationPrecomp const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); auto algo = ciphertext->GetCryptoContext()->GetScheme(); - if (cryptoParams->GetMultiplicationTechnique() != HPSPOVERQLEVELED) { + size_t sizeQ = ciphertext->GetElements()[0].GetNumOfElements(); + const auto elementParams = cryptoParams->GetElementParams(); + // Maximum number of RNS limbs in the crypto context + size_t sizeQM = elementParams->GetParams().size(); + + // in the HPSPOVERQLEVELED mode (without manually calling compress-like operations), + // an extra step of modulus reduction is needed + // otherwise, run the shared implemented of EvalKeySwitchPrecomputeCore for all RNS schemes + if (!((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQ == sizeQM))) { return algo->EvalKeySwitchPrecomputeCore(ciphertext->GetElements()[1], ciphertext->GetCryptoParameters()); } + else { + DCRTPoly c1 = ciphertext->GetElements()[1]; + size_t levels = ciphertext->GetNoiseScaleDeg() - 1; + double dcrtBits = c1.GetElementAtIndex(0).GetModulus().GetMSB(); + // how many levels to drop + uint32_t levelsDropped = FindLevelsToDrop(levels, cryptoParams, dcrtBits, true); + // l is index corresponding to leveled parameters in cryptoParameters precomputations in HPSPOVERQLEVELED + uint32_t l = levelsDropped > 0 ? sizeQ - 1 - levelsDropped : sizeQ - 1; + c1.SetFormat(COEFFICIENT); + c1 = c1.ScaleAndRound(cryptoParams->GetParamsQl(l), cryptoParams->GetQlQHatInvModqDivqModq(l), + cryptoParams->GetQlQHatInvModqDivqFrac(l), cryptoParams->GetModqBarrettMu()); + c1.SetFormat(EVALUATION); - DCRTPoly c1 = ciphertext->GetElements()[1]; - size_t levels = ciphertext->GetNoiseScaleDeg() - 1; - size_t sizeQ = c1.GetNumOfElements(); - double dcrtBits = c1.GetElementAtIndex(0).GetModulus().GetMSB(); - // how many levels to drop - uint32_t levelsDropped = FindLevelsToDrop(levels, cryptoParams, dcrtBits, true); - // l is index corresponding to leveled parameters in cryptoParameters precomputations in HPSPOVERQLEVELED - uint32_t l = levelsDropped > 0 ? sizeQ - 1 - levelsDropped : sizeQ - 1; - c1.SetFormat(COEFFICIENT); - c1 = c1.ScaleAndRound(cryptoParams->GetParamsQl(l), cryptoParams->GetQlQHatInvModqDivqModq(l), - cryptoParams->GetQlQHatInvModqDivqFrac(l), cryptoParams->GetModqBarrettMu()); - c1.SetFormat(EVALUATION); - - return algo->EvalKeySwitchPrecomputeCore(c1, ciphertext->GetCryptoParameters()); + return algo->EvalKeySwitchPrecomputeCore(c1, ciphertext->GetCryptoParameters()); + } } -Ciphertext LeveledSHEBFVRNS::EvalFastRotation(ConstCiphertext ciphertext, const usint index, - const usint m, +Ciphertext LeveledSHEBFVRNS::EvalFastRotation(ConstCiphertext ciphertext, const uint32_t index, + const uint32_t m, const std::shared_ptr> digits) const { if (index == 0) { return ciphertext->Clone(); @@ -791,7 +813,7 @@ Ciphertext LeveledSHEBFVRNS::EvalFastRotation(ConstCiphertextGetCryptoContext(); - usint autoIndex = FindAutomorphismIndex(index, m); + uint32_t autoIndex = FindAutomorphismIndex(index, m); auto evalKeyMap = cc->GetEvalAutomorphismKeyMap(ciphertext->GetKeyTag()); // verify if the key autoIndex exists in the evalKeyMap @@ -806,26 +828,27 @@ Ciphertext LeveledSHEBFVRNS::EvalFastRotation(ConstCiphertext(ciphertext->GetCryptoParameters()); - /* In the HPSOVERQLEVELED mode, we do modulus switching to a smaller modulus before we start key switching. - The modulus switching was already done when computing the ciphertext digits using EvalFastRotationPrecompute. - The goal of the "if branch" below is to extract the current modulus Ql from the element parameters of one of - the digit polynomials (by removing the auxiliary moduli added for hybrid key switching). - ATTN: elemParams should not be a shared_ptr because it would modify digits. */ + // We remove all auxiliary moduli P_i in the case of hybrid key switching + // ATTN: elemParams should not be a shared_ptr because it would modify digits. // TODO (dsuponit): wrap the lines below in a function to return elemParams as an object auto elemParams = *((*digits)[0].GetParams()); - if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) { - if (cryptoParams->GetKeySwitchTechnique() == HYBRID) { - size_t sizeP = cryptoParams->GetParamsP()->GetParams().size(); - for (size_t i = 0; i < sizeP; ++i) { - elemParams.PopLastParam(); - } + if (cryptoParams->GetKeySwitchTechnique() == HYBRID) { + size_t sizeP = cryptoParams->GetParamsP()->GetParams().size(); + for (size_t i = 0; i < sizeP; ++i) { + elemParams.PopLastParam(); } } std::shared_ptr> ba = algo->EvalFastKeySwitchCore(digits, evalKey, std::make_shared(elemParams)); - if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) { + size_t sizeQ = ciphertext->GetElements()[0].GetNumOfElements(); + const auto elementParams = cryptoParams->GetElementParams(); + // Maximum number of RNS limbs in the crypto context + size_t sizeQM = elementParams->GetParams().size(); + + // In the HPSPOVERQLEVELED mode, we need to increase the modulus back to Q + if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQ == sizeQM)) { size_t sizeQ = cv[0].GetNumOfElements(); // l is index corresponding to leveled parameters in cryptoParameters precomputations in HPSPOVERQLEVELED, after the level dropping uint32_t l = elemParams.GetParams().size() - 1; @@ -836,8 +859,8 @@ Ciphertext LeveledSHEBFVRNS::EvalFastRotation(ConstCiphertextGetQlHatModqPrecon(l), sizeQ); } - usint N = cryptoParams->GetElementParams()->GetRingDimension(); - std::vector vec(N); + uint32_t N = cryptoParams->GetElementParams()->GetRingDimension(); + std::vector vec(N); PrecomputeAutoMap(N, autoIndex, &vec); (*ba)[0] += cv[0]; @@ -852,7 +875,7 @@ Ciphertext LeveledSHEBFVRNS::EvalFastRotation(ConstCiphertext& ciphertext, const E auto algo = ciphertext->GetCryptoContext()->GetScheme(); size_t sel = 1 + !isKeySwitch; - if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) { + size_t sizeQ = cv[0].GetNumOfElements(); + const auto elementParams = cryptoParams->GetElementParams(); + // Maximum number of RNS limbs in the crypto context + size_t sizeQM = elementParams->GetParams().size(); + + if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQM == sizeQ)) { size_t levels = ciphertext->GetNoiseScaleDeg() - 1; - size_t sizeQ = cv[0].GetNumOfElements(); double dcrtBits = cv[0].GetElementAtIndex(0).GetModulus().GetMSB(); // how many levels to drop @@ -882,7 +909,7 @@ void LeveledSHEBFVRNS::RelinearizeCore(Ciphertext& ciphertext, const E cv[sel].SetFormat(Format::EVALUATION); auto ab = algo->KeySwitchCore(cv[sel], evalKey); - if (cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) { + if ((cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) && (sizeQM == sizeQ)) { size_t sizeQ = cv[0].GetNumOfElements(); (*ab)[0].ExpandCRTBasisQlHat(cryptoParams->GetElementParams(), cryptoParams->GetQlHatModq(l), cryptoParams->GetQlHatModqPrecon(l), sizeQ); @@ -905,15 +932,16 @@ void LeveledSHEBFVRNS::RelinearizeCore(Ciphertext& ciphertext, const E } Ciphertext LeveledSHEBFVRNS::Compress(ConstCiphertext ciphertext, size_t towersLeft) const { - if (towersLeft != 1) { + const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); + + if ((cryptoParams->GetMultiplicationTechnique() == BEHZ) || (cryptoParams->GetMultiplicationTechnique() == HPS)) { OPENFHE_THROW( - "BFV Compress is currently supported only for the case when one RNS tower is left after compression."); + "BFV Compress is not currently supported for BEHZ or HPS. Use one of the HPSPOVERQ* methods instead."); } - const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); - - if (cryptoParams->GetMultiplicationTechnique() == BEHZ) { - OPENFHE_THROW("BFV Compress is not currently supported for BEHZ. Use one of the HPS* methods instead."); + if ((cryptoParams->GetEncryptionTechnique() == EXTENDED)) { + OPENFHE_THROW( + "BFV Compress is not currently supported for the EXTENDED encryption method. Use the STANDARD encryption method instead."); } Ciphertext result = std::make_shared>(*ciphertext); diff --git a/src/pke/lib/scheme/bfvrns/bfvrns-multiparty.cpp b/src/pke/lib/scheme/bfvrns/bfvrns-multiparty.cpp index 56ecc47fc..3a94dd551 100644 --- a/src/pke/lib/scheme/bfvrns/bfvrns-multiparty.cpp +++ b/src/pke/lib/scheme/bfvrns/bfvrns-multiparty.cpp @@ -149,12 +149,14 @@ DecryptResult MultipartyBFVRNS::MultipartyDecryptFusion(const std::vector 1) { + const auto elementParams = cryptoParams->GetElementParams(); + size_t sizeQ = elementParams->GetParams().size(); + + // use RNS procedures only if the number of RNS limbs is the same as for fresh ciphertexts + if (sizeQl == sizeQ) { + b.SetFormat(Format::COEFFICIENT); if (cryptoParams->GetMultiplicationTechnique() == HPS || cryptoParams->GetMultiplicationTechnique() == HPSPOVERQ || cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) { @@ -172,6 +174,16 @@ DecryptResult MultipartyBFVRNS::MultipartyDecryptFusion(const std::vectorGetQlQlInvModqlDivqlModq(diffQl + l), + cryptoParams->GetqlInvModq(diffQl + l)); + } + + b.SetFormat(Format::COEFFICIENT); + const NativeInteger t = cryptoParams->GetPlaintextModulus(); NativePoly element = b.GetElementAtIndex(0); const NativeInteger q = element.GetModulus(); diff --git a/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp b/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp index e0ac85a48..ca20f32e4 100644 --- a/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/bfvrns/bfvrns-parametergeneration.cpp @@ -74,12 +74,13 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr(cryptoParamsBFVRNS->GetPlaintextModulus()); uint32_t digitSize = cryptoParamsBFVRNS->GetDigitSize(); SecurityLevel stdLevel = cryptoParamsBFVRNS->GetStdLevel(); + uint32_t auxBits = DCRT_MODULUS::MAX_SIZE; // Bound of the Gaussian error polynomial - double Berr = sigma * sqrt(alpha); + double Berr = sigma * std::sqrt(alpha); // Bound of the key polynomial - double Bkey; + double Bkey = 0; DistributionType distType; @@ -87,7 +88,7 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptrGetSecretKeyDist() == GAUSSIAN) { - Bkey = sqrt(thresholdParties) * sigma * sqrt(alpha); + Bkey = std::sqrt(thresholdParties) * Berr; distType = HEStd_error; } else { @@ -98,7 +99,7 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr double { - return (2. * sqrt(n)); + return (2. * std::sqrt(n)); }; // norm of fresh ciphertext polynomial (for EXTENDED the noise is reduced to modulus switching noise) @@ -115,21 +116,35 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptrEstimateMultipartyFloodingLogQ(); + // adds logP in the case of HYBRID key switching + if (ksTech == HYBRID) { + // number of RNS limbs + uint32_t k = static_cast(std::ceil(std::ceil(logq) / dcrtBits)); + // set the number of digits + uint32_t numPartQ = ComputeNumLargeDigits(numDigits, k - 1); + auto hybridKSInfo = CryptoParametersRNS::EstimateLogP(numPartQ, dcrtBits, dcrtBits, 0, k, auxBits); + logq += std::get<0>(hybridKSInfo); + } return static_cast( - StdLatticeParm::FindRingDim(distType, stdLevel, static_cast(std::ceil(logq / log(2))))); + StdLatticeParm::FindRingDim(distType, stdLevel, static_cast(std::ceil(logq)))); } }; auto noiseKS = [&](uint32_t n, double logqPrev, double w, bool mult) -> double { - if ((ksTech == HYBRID) && (!mult)) - return (delta(n) * Berr + delta(n) * Bkey + 1.0) / 2; - else if ((ksTech == HYBRID) && (mult)) + if (ksTech == HYBRID) { // conservative estimate for HYBRID to avoid the use of method of // iterative approximations; we do not know the number - // of moduli at this point and use an upper bound for numDigits - return (multiplicativeDepth + 1) * delta(n) * Berr; - else - return delta(n) * (floor(logqPrev / (log(2) * dcrtBits)) + 1) * w * Berr; + // of digits and moduli at this point and use upper bounds + double numTowers = std::ceil(logqPrev / dcrtBits); + return numTowers * (delta(n) * Berr + delta(n) * Bkey + 1.0) / 2.0; + } + else { + double numDigitsPerTower = (digitSize == 0) ? 1 : ((dcrtBits / digitSize) + 1); + return delta(n) * numDigitsPerTower * (floor(logqPrev / (dcrtBits)) + 1) * w * Berr / 2.0; + } }; // initial values @@ -145,7 +160,7 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr double { - return log(p * (4 * ((evalAddCount + 1) * Vnorm(n) + evalAddCount) + p)); + return std::log2(p * (4 * ((evalAddCount + 1) * Vnorm(n) + evalAddCount) + p)); }; // initial value @@ -158,30 +173,30 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr(std::ceil((std::ceil(logq / log(2)) + 1.0) / dcrtBits)); + int32_t k = static_cast(std::ceil(std::ceil(logq) / dcrtBits)); - double logqCeil = k * dcrtBits * log(2); + double logqCeil = k * dcrtBits; while (nRLWE(logqCeil) > n) { n = 2 * n; logq = logqBFV(n); - k = static_cast(std::ceil((std::ceil(logq / log(2)) + 1.0) / dcrtBits)); - logqCeil = k * dcrtBits * log(2); + k = static_cast(std::ceil(std::ceil(logq) / dcrtBits)); + logqCeil = k * dcrtBits; } } else if ((multiplicativeDepth == 0) && (keySwitchCount > 0) && (evalAddCount == 0)) { // this case supports automorphism w/o any other operations // base for relinearization - double w = digitSize == 0 ? pow(2, dcrtBits) : pow(2, digitSize); + double w = std::pow(2, (digitSize == 0 ? dcrtBits : digitSize)); // Correctness constraint auto logqBFV = [&](uint32_t n, double logqPrev) -> double { - return log(p * (4 * (Vnorm(n) + keySwitchCount * noiseKS(n, logqPrev, w, false)) + p)); + return std::log2(p * (4 * (Vnorm(n) + keySwitchCount * noiseKS(n, logqPrev, w, false)) + p)); }; // initial values - double logqPrev = 6. * log(10); + double logqPrev = 6. * std::log2(10); logq = logqBFV(n, logqPrev); logqPrev = logq; @@ -195,23 +210,23 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr log(1.001)) { + while (std::fabs(logq - logqPrev) > std::log2(1.001)) { logqPrev = logq; logq = logqBFV(n, logqPrev); } // this code updates n and q to account for the discrete size of CRT // moduli = dcrtBits - int32_t k = static_cast(std::ceil((std::ceil(logq / log(2)) + 1.0) / dcrtBits)); + int32_t k = static_cast(std::ceil(std::ceil(logq) / dcrtBits)); - double logqCeil = k * dcrtBits * log(2); + double logqCeil = k * dcrtBits; logqPrev = logqCeil; while (nRLWE(logqCeil) > n) { n = 2 * n; logq = logqBFV(n, logqPrev); - k = static_cast(std::ceil((std::ceil(logq / log(2)) + 1.0) / dcrtBits)); - logqCeil = k * dcrtBits * log(2); + k = static_cast(std::ceil(std::ceil(logq) / dcrtBits)); + logqCeil = k * dcrtBits; logqPrev = logqCeil; } } @@ -221,7 +236,7 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr double { @@ -235,12 +250,12 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr double { - return log(4 * p) + (multiplicativeDepth - 1) * log(C1(n)) + - log(C1(n) * Vnorm(n) + multiplicativeDepth * C2(n, logqPrev)); + return log2(4 * p) + (multiplicativeDepth - 1) * log2(C1(n)) + + log2(C1(n) * Vnorm(n) + multiplicativeDepth * C2(n, logqPrev)); }; // initial values - double logqPrev = 6. * log(10); + double logqPrev = 6. * std::log2(10); logq = logqBFV(n, logqPrev); logqPrev = logq; @@ -254,7 +269,7 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr log(1.001)) { + while (std::fabs(logq - logqPrev) > std::log2(1.001)) { logqPrev = logq; logq = logqBFV(n, logqPrev); } @@ -262,16 +277,16 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr(std::ceil((std::ceil(logq / log(2)) + 1.0) / dcrtBits)); + int32_t k = static_cast(std::ceil(std::ceil(logq) / dcrtBits)); - double logqCeil = k * dcrtBits * log(2); + double logqCeil = k * dcrtBits; logqPrev = logqCeil; while (nRLWE(logqCeil) > n) { n = 2 * n; logq = logqBFV(n, logqPrev); - k = static_cast(std::ceil((std::ceil(logq / log(2)) + 1.0) / dcrtBits)); - logqCeil = k * dcrtBits * log(2); + k = static_cast(std::ceil(std::ceil(logq) / dcrtBits)); + logqCeil = k * dcrtBits; logqPrev = logqCeil; } } @@ -291,31 +306,30 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptr(std::ceil((std::ceil(logq / log(2)) + 1.0) / dcrtBits)); + const size_t numInitialModuli = static_cast(std::ceil(std::ceil(logq) / dcrtBits)); if (numInitialModuli < 1) OPENFHE_THROW("numInitialModuli must be greater than 0."); const size_t sizeQ = multipartyMode == NOISE_FLOODING_MULTIPARTY ? - numInitialModuli + NOISE_FLOODING::NUM_MODULI_MULTIPARTY : + numInitialModuli + NoiseFlooding::NUM_MODULI_MULTIPARTY : numInitialModuli; std::vector moduliQ(sizeQ); std::vector rootsQ(sizeQ); - // makes sure the first integer is less than 2^60-1 to take advantage of NTL - // optimizations + // makes sure the first integer is less than 2^60-1 moduliQ[0] = LastPrime(dcrtBits, 2 * n); rootsQ[0] = RootOfUnity(2 * n, moduliQ[0]); NativeInteger lastModulus = moduliQ[0]; if (multipartyMode == NOISE_FLOODING_MULTIPARTY) { - moduliQ[1] = LastPrime(NOISE_FLOODING::MULTIPARTY_MOD_SIZE, 2 * n); + moduliQ[1] = LastPrime(NoiseFlooding::MULTIPARTY_MOD_SIZE, 2 * n); if (moduliQ[1] == lastModulus) { moduliQ[1] = PreviousPrime(moduliQ[1], 2 * n); lastModulus = moduliQ[1]; } rootsQ[1] = RootOfUnity(2 * n, moduliQ[1]); - for (size_t i = 2; i < 1 + NOISE_FLOODING::NUM_MODULI_MULTIPARTY; i++) { + for (size_t i = 2; i < 1 + NoiseFlooding::NUM_MODULI_MULTIPARTY; i++) { moduliQ[i] = PreviousPrime(moduliQ[i - 1], 2 * n); rootsQ[i] = RootOfUnity(2 * n, moduliQ[i]); if (lastModulus != moduliQ[0]) @@ -357,7 +371,28 @@ bool ParameterGenerationBFVRNS::ParamsGenBFVRNS(std::shared_ptrPrecomputeCRTTables(ksTech, scalTech, encTech, multTech, numPartQ, 60, 0); + cryptoParamsBFVRNS->PrecomputeCRTTables(ksTech, scalTech, encTech, multTech, numPartQ, auxBits, 0); + + // Validate the ring dimension found using estimated logQ(P) against actual logQ(P) + if (stdLevel != HEStd_NotSet) { + uint32_t logActualQ = 0; + if (ksTech == HYBRID) { + logActualQ = cryptoParamsBFVRNS->GetParamsQP()->GetModulus().GetMSB(); + } + else { + logActualQ = cryptoParamsBFVRNS->GetElementParams()->GetModulus().GetMSB(); + } + + uint32_t nActual = StdLatticeParm::FindRingDim(distType, stdLevel, logActualQ); + if (n < nActual) { + std::string errMsg("The ring dimension found using estimated logQ(P) ["); + errMsg += std::to_string(n) + "] does does not meet security requirements. "; + errMsg += "Report this problem to OpenFHE developers and set the ring dimension manually to "; + errMsg += std::to_string(nActual) + "."; + + OPENFHE_THROW(errMsg); + } + } return true; } diff --git a/src/pke/lib/scheme/bfvrns/bfvrns-pke.cpp b/src/pke/lib/scheme/bfvrns/bfvrns-pke.cpp index 04927371b..e57b69dd8 100644 --- a/src/pke/lib/scheme/bfvrns/bfvrns-pke.cpp +++ b/src/pke/lib/scheme/bfvrns/bfvrns-pke.cpp @@ -43,7 +43,7 @@ BFV implementation. See https://eprint.iacr.org/2021/204 for details. namespace lbcrypto { -KeyPair PKEBFVRNS::KeyGenInternal(CryptoContext cc, bool makeSparse) { +KeyPair PKEBFVRNS::KeyGenInternal(CryptoContext cc, bool makeSparse) const { KeyPair keyPair(std::make_shared>(cc), std::make_shared>(cc)); @@ -102,7 +102,13 @@ Ciphertext PKEBFVRNS::Encrypt(DCRTPoly ptxt, const PrivateKey(privateKey->GetCryptoParameters()); const auto elementParams = cryptoParams->GetElementParams(); - auto encParams = elementParams; + size_t sizeQ = elementParams->GetParams().size(); + + auto encParams = ptxt.GetParams(); + size_t sizeP = encParams->GetParams().size(); + + // enables encoding of plaintexts using a smaller number of RNS limbs + size_t level = sizeQ - sizeP; std::vector tInvModq = cryptoParams->GettInvModq(); if (cryptoParams->GetEncryptionTechnique() == EXTENDED) { @@ -117,8 +123,8 @@ Ciphertext PKEBFVRNS::Encrypt(DCRTPoly ptxt, const PrivateKey> ba = EncryptZeroCore(privateKey, encParams); - NativeInteger NegQModt = cryptoParams->GetNegQModt(); - NativeInteger NegQModtPrecon = cryptoParams->GetNegQModtPrecon(); + NativeInteger NegQModt = cryptoParams->GetNegQModt(level); + NativeInteger NegQModtPrecon = cryptoParams->GetNegQModtPrecon(level); if (cryptoParams->GetEncryptionTechnique() == EXTENDED) { NegQModt = cryptoParams->GetNegQrModt(); @@ -154,7 +160,13 @@ Ciphertext PKEBFVRNS::Encrypt(DCRTPoly ptxt, const PublicKey const auto cryptoParams = std::dynamic_pointer_cast(publicKey->GetCryptoParameters()); const auto elementParams = cryptoParams->GetElementParams(); - auto encParams = elementParams; + size_t sizeQ = elementParams->GetParams().size(); + + auto encParams = ptxt.GetParams(); + size_t sizeP = encParams->GetParams().size(); + + // enables encoding of plaintexts using a smaller number of RNS limbs + size_t level = sizeQ - sizeP; std::vector tInvModq = cryptoParams->GettInvModq(); if (cryptoParams->GetEncryptionTechnique() == EXTENDED) { @@ -169,8 +181,8 @@ Ciphertext PKEBFVRNS::Encrypt(DCRTPoly ptxt, const PublicKey std::shared_ptr> ba = EncryptZeroCore(publicKey, encParams); - NativeInteger NegQModt = cryptoParams->GetNegQModt(); - NativeInteger NegQModtPrecon = cryptoParams->GetNegQModtPrecon(); + NativeInteger NegQModt = cryptoParams->GetNegQModt(level); + NativeInteger NegQModtPrecon = cryptoParams->GetNegQModtPrecon(level); if (cryptoParams->GetEncryptionTechnique() == EXTENDED) { NegQModt = cryptoParams->GetNegQrModt(); @@ -206,12 +218,15 @@ DecryptResult PKEBFVRNS::Decrypt(ConstCiphertext ciphertext, const Pri const std::vector& cv = ciphertext->GetElements(); DCRTPoly b = DecryptCore(cv, privateKey); - b.SetFormat(Format::COEFFICIENT); size_t sizeQl = b.GetNumOfElements(); - // use RNS procedures only if the number of RNS limbs is larger than 1 - if (sizeQl > 1) { + const auto elementParams = cryptoParams->GetElementParams(); + size_t sizeQ = elementParams->GetParams().size(); + + // use RNS procedures only if the number of RNS limbs is the same as for fresh ciphertexts + if (sizeQl == sizeQ) { + b.SetFormat(Format::COEFFICIENT); if (cryptoParams->GetMultiplicationTechnique() == HPS || cryptoParams->GetMultiplicationTechnique() == HPSPOVERQ || cryptoParams->GetMultiplicationTechnique() == HPSPOVERQLEVELED) { @@ -229,6 +244,16 @@ DecryptResult PKEBFVRNS::Decrypt(ConstCiphertext ciphertext, const Pri } } else { + // for the case when compress was called, we automatically reduce the polynomial to 1 RNS limb + size_t diffQl = sizeQ - sizeQl; + size_t levels = sizeQl - 1; + for (size_t l = 0; l < levels; ++l) { + b.DropLastElementAndScale(cryptoParams->GetQlQlInvModqlDivqlModq(diffQl + l), + cryptoParams->GetqlInvModq(diffQl + l)); + } + + b.SetFormat(Format::COEFFICIENT); + const NativeInteger t = cryptoParams->GetPlaintextModulus(); NativePoly element = b.GetElementAtIndex(0); const NativeInteger q = element.GetModulus(); diff --git a/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp b/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp index 55e4a11b8..8fb1340d1 100644 --- a/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/bgvrns/bgvrns-parametergeneration.cpp @@ -41,35 +41,31 @@ BGV implementation. See https://eprint.iacr.org/2021/204 for details. namespace lbcrypto { -uint32_t ParameterGenerationBGVRNS::computeRingDimension(std::shared_ptr> cryptoParams, - uint32_t qBound, usint cyclOrder) const { +uint32_t ParameterGenerationBGVRNS::computeRingDimension( + const std::shared_ptr>& cryptoParams, uint32_t qBound, uint32_t cyclOrder) const { const auto cryptoParamsBGVRNS = std::dynamic_pointer_cast(cryptoParams); - //// HE Standards compliance logic/check - SecurityLevel stdLevel = cryptoParamsBGVRNS->GetStdLevel(); - - uint32_t ringDimension = cyclOrder / 2; // GAUSSIAN security constraint DistributionType distType = (cryptoParamsBGVRNS->GetSecretKeyDist() == GAUSSIAN) ? HEStd_error : HEStd_ternary; - auto nRLWE = [&](usint q) -> uint32_t { - return StdLatticeParm::FindRingDim(distType, stdLevel, q); - }; + + // HE Standards compliance logic/check + SecurityLevel stdLevel = cryptoParamsBGVRNS->GetStdLevel(); + + uint32_t ringDimension = cyclOrder / 2; // Case 1: SecurityLevel specified as HEStd_NotSet -> Do nothing if (stdLevel != HEStd_NotSet) { + auto he_std_n = StdLatticeParm::FindRingDim(distType, stdLevel, qBound); if (ringDimension == 0) { // Case 2: SecurityLevel specified, but ring dimension not specified // Choose ring dimension based on security standards - ringDimension = nRLWE(qBound); + ringDimension = he_std_n; } - else { + else if (ringDimension < he_std_n) { // Case 3: Both SecurityLevel and ring dimension specified // Check whether particular selection is standards-compliant - auto he_std_n = nRLWE(qBound); - if (he_std_n > ringDimension) { - OPENFHE_THROW("The specified ring dimension (" + std::to_string(ringDimension) + - ") does not comply with HE standards recommendation (" + std::to_string(he_std_n) + ")."); - } + OPENFHE_THROW("The specified ring dimension (" + std::to_string(ringDimension) + + ") does not comply with HE standards recommendation (" + std::to_string(he_std_n) + ")."); } } else if (ringDimension == 0) { @@ -79,28 +75,27 @@ uint32_t ParameterGenerationBGVRNS::computeRingDimension(std::shared_ptr> cryptoParams, uint32_t ringDimension, uint32_t evalAddCount, - uint32_t keySwitchCount, uint32_t auxBits, usint numPrimes) const { + const std::shared_ptr>& cryptoParams, uint32_t ringDimension, uint32_t evalAddCount, + uint32_t keySwitchCount, uint32_t auxTowers, uint32_t numPrimes) const { const auto cryptoParamsBGVRNS = std::dynamic_pointer_cast(cryptoParams); - usint digitSize = cryptoParamsBGVRNS->GetDigitSize(); + uint32_t digitSize = cryptoParamsBGVRNS->GetDigitSize(); KeySwitchTechnique ksTech = cryptoParamsBGVRNS->GetKeySwitchTechnique(); ScalingTechnique scalTech = cryptoParamsBGVRNS->GetScalingTechnique(); double sigma = cryptoParamsBGVRNS->GetDistributionParameter(); double alpha = cryptoParamsBGVRNS->GetAssuranceMeasure(); // Bound of the Gaussian error polynomial - double Berr = sigma * sqrt(alpha); + double Berr = sigma * std::sqrt(alpha); // Bound of the key polynomial // supports both discrete Gaussian (GAUSSIAN) and ternary uniform distribution // (UNIFORM_TERNARY) cases uint32_t thresholdParties = cryptoParamsBGVRNS->GetThresholdNumOfParties(); // Bkey set to thresholdParties * 1 for ternary distribution - double Bkey = (cryptoParamsBGVRNS->GetSecretKeyDist() == GAUSSIAN) ? sqrt(thresholdParties) * sigma * sqrt(alpha) : - thresholdParties; - + double Bkey = + (cryptoParamsBGVRNS->GetSecretKeyDist() == GAUSSIAN) ? std::sqrt(thresholdParties) * Berr : thresholdParties; // delta - auto expansionFactor = 2. * sqrt(ringDimension); + auto expansionFactor = 2. * std::sqrt(ringDimension); // Vnorm auto freshEncryptionNoise = Berr * (1. + 2. * expansionFactor * Bkey); @@ -109,16 +104,16 @@ BGVNoiseEstimates ParameterGenerationBGVRNS::computeNoiseEstimates( if (digitSize == 0) { OPENFHE_THROW("digitSize is not allowed to be 0 for BV key switching in BGV when scalingModSize = 0."); } - int relinBase = pow(2.0, digitSize); - int modSizeEstimate = DCRT_MODULUS::MAX_SIZE; - int numWindows = floor(modSizeEstimate / log(relinBase)) + 1; - keySwitchingNoise = numWindows * numPrimes * expansionFactor * relinBase * Berr / 2.0; + double relinBase = std::pow(2.0, digitSize); + uint32_t modSizeEstimate = DCRT_MODULUS::MAX_SIZE; + uint32_t numWindows = (modSizeEstimate / digitSize) + 1; + keySwitchingNoise = numWindows * numPrimes * expansionFactor * relinBase * Berr / 2.0; } else { double numTowersPerDigit = cryptoParamsBGVRNS->GetNumPerPartQ(); - int numDigits = cryptoParamsBGVRNS->GetNumPartQ(); + double numDigits = cryptoParamsBGVRNS->GetNumPartQ(); keySwitchingNoise = numTowersPerDigit * numDigits * expansionFactor * Berr / 2.0; - keySwitchingNoise += auxBits * (1 + expansionFactor * Bkey) / 2.0; + keySwitchingNoise += auxTowers * (1 + expansionFactor * Bkey) / 2.0; } // V_ms @@ -140,14 +135,14 @@ BGVNoiseEstimates ParameterGenerationBGVRNS::computeNoiseEstimates( uint64_t ParameterGenerationBGVRNS::getCyclicOrder(const uint32_t ringDimension, const int plainModulus, const ScalingTechnique scalTech) const { // Moduli need to be primes that are 1 (mod 2n) - usint cyclOrder = 2 * ringDimension; + uint32_t cyclOrder = 2 * ringDimension; uint64_t lcmCyclOrderPtm = 0; if (scalTech == FIXEDAUTO) { // In FIXEDAUTO, moduli also need to be 1 (mod t) - usint plaintextModulus = plainModulus; - usint pow2ptm = 1; // The largest power of 2 dividing ptm (check whether it - // is larger than cyclOrder or not) + uint32_t plaintextModulus = plainModulus; + uint32_t pow2ptm = 1; // The largest power of 2 dividing ptm (check whether it + // is larger than cyclOrder or not) while (plaintextModulus % 2 == 0) { plaintextModulus >>= 1; pow2ptm <<= 1; @@ -165,8 +160,8 @@ uint64_t ParameterGenerationBGVRNS::getCyclicOrder(const uint32_t ringDimension, } std::pair, uint32_t> ParameterGenerationBGVRNS::computeModuli( - std::shared_ptr> cryptoParams, uint32_t ringDimension, uint32_t evalAddCount, - uint32_t keySwitchCount, uint32_t auxBits, usint numPrimes) const { + const std::shared_ptr>& cryptoParams, uint32_t ringDimension, uint32_t evalAddCount, + uint32_t keySwitchCount, uint32_t auxTowers, uint32_t numPrimes) const { if (numPrimes < 1) { OPENFHE_THROW("numPrimes must be at least 1"); } @@ -181,7 +176,7 @@ std::pair, uint32_t> ParameterGenerationBGVRNS::compu NativeInteger plainModulusInt = NativeInteger(plainModulus); BGVNoiseEstimates noiseEstimates = - computeNoiseEstimates(cryptoParams, ringDimension, evalAddCount, keySwitchCount, auxBits, numPrimes); + computeNoiseEstimates(cryptoParams, ringDimension, evalAddCount, keySwitchCount, auxTowers, numPrimes); uint64_t cyclOrder = getCyclicOrder(ringDimension, plainModulus, scalTech); double firstModLowerBound = 0; @@ -189,7 +184,7 @@ std::pair, uint32_t> ParameterGenerationBGVRNS::compu firstModLowerBound = 2.0 * plainModulus * noiseEstimates.freshEncryptionNoise - plainModulus; else firstModLowerBound = 2.0 * plainModulus * noiseEstimates.noisePerLevel - plainModulus; - usint firstModSize = ceil(log2(firstModLowerBound)); + uint32_t firstModSize = std::ceil(std::log2(firstModLowerBound)); if (firstModSize >= DCRT_MODULUS::MAX_SIZE) { OPENFHE_THROW( "Change parameters! Try reducing the number of additions per level, " @@ -203,7 +198,7 @@ std::pair, uint32_t> ParameterGenerationBGVRNS::compu noiseEstimates.freshEncryptionNoise / noiseEstimates.noisePerLevel * (evalAddCount + 1); extraModLowerBound += keySwitchCount * noiseEstimates.keySwitchingNoise / noiseEstimates.noisePerLevel; extraModLowerBound *= 2; - usint extraModSize = ceil(log2(extraModLowerBound)); + uint32_t extraModSize = std::ceil(std::log2(extraModLowerBound)); if (extraModSize >= DCRT_MODULUS::MAX_SIZE) { OPENFHE_THROW( @@ -235,7 +230,7 @@ std::pair, uint32_t> ParameterGenerationBGVRNS::compu modLowerBound = modLowerBoundNumerator / modLowerBoundDenom; } - usint modSize = ceil(log2(modLowerBound)); + uint32_t modSize = std::ceil(std::log2(modLowerBound)); if (modSize >= DCRT_MODULUS::MAX_SIZE) { OPENFHE_THROW( "Change parameters! Try reducing the number of additions per level, " @@ -277,8 +272,9 @@ std::pair, uint32_t> ParameterGenerationBGVRNS::compu return std::make_pair(moduliQ, composite.GetMSB()); } -void ParameterGenerationBGVRNS::InitializeFloodingDgg(std::shared_ptr> cryptoParams, - usint numPrimes) const { +void ParameterGenerationBGVRNS::InitializeFloodingDgg( + const std::shared_ptr>& cryptoParams, uint32_t numPrimes, + uint32_t ringDimension) const { const auto cryptoParamsBGVRNS = std::dynamic_pointer_cast(cryptoParams); KeySwitchTechnique ksTech = cryptoParamsBGVRNS->GetKeySwitchTechnique(); @@ -286,18 +282,18 @@ void ParameterGenerationBGVRNS::InitializeFloodingDgg(std::shared_ptrGetElementParams()->GetRingDimension(); double sigma = cryptoParamsBGVRNS->GetDistributionParameter(); double alpha = cryptoParamsBGVRNS->GetAssuranceMeasure(); - usint r = cryptoParamsBGVRNS->GetDigitSize(); - double B_e = sqrt(alpha) * sigma; + uint32_t r = cryptoParamsBGVRNS->GetDigitSize(); + double B_e = std::sqrt(alpha) * sigma; uint32_t auxBits = DCRT_MODULUS::MAX_SIZE; uint32_t thresholdParties = cryptoParamsBGVRNS->GetThresholdNumOfParties(); - // bound on the secret key is sigma*sqrt(alpha) if the secret is sampled from discrete gaussian distribution + // bound on the secret key is sigma*sqrt(alpha)*sqrt(thresholdParties) if the secret is sampled from discrete gaussian distribution // and is 1 * threshold number of parties if the secret is sampled from ternary distribution. The threshold number of // parties is 1 by default but can be set to the number of parties in a threshold application. // Bkey set to thresholdParties * 1 for ternary distribution - double Bkey = (cryptoParamsBGVRNS->GetSecretKeyDist() == GAUSSIAN) ? sigma * sqrt(alpha) : thresholdParties; + double Bkey = + (cryptoParamsBGVRNS->GetSecretKeyDist() == GAUSSIAN) ? B_e * std::sqrt(thresholdParties) : thresholdParties; double stat_sec_half = cryptoParamsBGVRNS->GetStatisticalSecurity() / 2; double num_queries = cryptoParamsBGVRNS->GetNumAdversarialQueries(); @@ -306,36 +302,45 @@ void ParameterGenerationBGVRNS::InitializeFloodingDgg(std::shared_ptrGetFloodingDiscreteGaussianGenerator(); double noise_param = 1; if (PREMode == FIXED_NOISE_HRA) { - noise_param = NOISE_FLOODING::PRE_SD; + noise_param = NoiseFlooding::PRE_SD; } else if (PREMode == NOISE_FLOODING_HRA) { + // expansion factor + auto expansionFactor = 2. * std::sqrt(ringDimension); + // re-randomization noise + auto freshEncryptionNoise = B_e * (1. + 2. * expansionFactor * Bkey); + if (ksTech == BV) { if (r > 0) { - // sqrt(12*num_queries) factor required for security analysis - noise_param = sqrt(12 * num_queries) * pow(2, stat_sec_half) * (1 + 2 * Bkey) * numPrimes * - (auxBits / r + 1) * sqrt(ringDimension) * (pow(2, r) - 1) * B_e; + // sqrt(12*num_queries) * pow(2, stat_sec_half) factor required for security analysis + // 2*freshEncryptionNoise is done because after modulus switching the noise will be + // bounded by freshEncryptionNoise + // Note: std::pow(2, stat_sec_half - 1) == std::pow(2, stat_sec_half) / 2.0 + noise_param = std::sqrt(12 * num_queries) * std::pow(2, stat_sec_half - 1) * + (2 * freshEncryptionNoise + + numPrimes * (auxBits / r + 1) * expansionFactor * (std::pow(2, r) - 1) * B_e); } else { - OPENFHE_THROW("Relinwindow value cannot be 0 for BV keyswitching"); + OPENFHE_THROW("Digit size value cannot be 0 for BV keyswitching"); } } else if (ksTech == HYBRID) { if (r == 0) { - double numTowersPerDigit = cryptoParamsBGVRNS->GetNumPerPartQ(); - int numDigits = cryptoParamsBGVRNS->GetNumPartQ(); - noise_param = numTowersPerDigit * numDigits * sqrt(ringDimension) * B_e * (1 + 2 * Bkey); - noise_param += auxBits * (1 + sqrt(ringDimension) * Bkey); - // sqrt(12*num_queries) factor required for security analysis - noise_param = sqrt(12 * num_queries) * pow(2, stat_sec_half) * noise_param; + // 2*freshEncryptionNoise is done because after modulus switching the noise will be + // bounded by freshEncryptionNoise + noise_param = 2 * freshEncryptionNoise; + // we use numPrimes here as an approximation of numDigits * [towers per digit] + noise_param += numPrimes * expansionFactor * B_e / 2.0; + // we use numPrimes (larger bound) instead of auxPrimes because we do not know auxPrimes yet + noise_param += numPrimes * (1 + expansionFactor * Bkey) / 2.0; + // sqrt(12*num_queries) * pow(2, stat_sec_half) factor required for security analysis + noise_param = std::sqrt(12 * num_queries) * std::pow(2, stat_sec_half) * noise_param; } else { - OPENFHE_THROW("Relinwindow value can only be zero for Hybrid keyswitching"); + OPENFHE_THROW("Digit size can only be zero for Hybrid keyswitching"); } } } - else if (PREMode == DIVIDE_AND_ROUND_HRA) { - OPENFHE_THROW("Noise Flooding not applicable for PRE DIVIDE_AND_ROUND_HRA mode"); - } // set the flooding distribution parameter to the distribution. dggFlooding.SetStd(noise_param); const auto cryptoParamsRNS = std::dynamic_pointer_cast(cryptoParams); @@ -343,9 +348,9 @@ void ParameterGenerationBGVRNS::InitializeFloodingDgg(std::shared_ptr> cryptoParams, - uint32_t evalAddCount, uint32_t keySwitchCount, usint cyclOrder, - usint numPrimes, usint firstModSize, usint dcrtBits, uint32_t numPartQ, - usint multihopQBound) const { + uint32_t evalAddCount, uint32_t keySwitchCount, uint32_t cyclOrder, + uint32_t numPrimes, uint32_t firstModSize, uint32_t dcrtBits, + uint32_t numPartQ, uint32_t numHops) const { const auto cryptoParamsBGVRNS = std::dynamic_pointer_cast(cryptoParams); uint32_t ptm = cryptoParamsBGVRNS->GetPlaintextModulus(); @@ -365,60 +370,127 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptr DCRT_MODULUS::MAX_SIZE) ? DCRT_MODULUS::MAX_SIZE : (28 + GetMSB64(ptm)); + } + // Select firstModSize to be dcrtBits if not indicated otherwise + if (firstModSize == 0) + firstModSize = dcrtBits; + } + else { + // we only support PRE in the HRA-secure mode; no FHE operations are supported yet + numPrimes = numHops; + + double sigma = cryptoParamsBGVRNS->GetDistributionParameter(); + double alpha = cryptoParamsBGVRNS->GetAssuranceMeasure(); + + // Bound of the Gaussian error polynomial + double Berr = sigma * std::sqrt(alpha); + + // Bound of the key polynomial supports both + // discrete Gaussian (GAUSSIAN) and ternary uniform distribution (UNIFORM_TERNARY) cases + uint32_t thresholdParties = cryptoParamsBGVRNS->GetThresholdNumOfParties(); + // Bkey set to thresholdParties * 1 for ternary distribution + double Bkey = (cryptoParamsBGVRNS->GetSecretKeyDist() == GAUSSIAN) ? std::sqrt(thresholdParties) * Berr : + thresholdParties; + // delta + auto expansionFactor = 2. * std::sqrt(ringDimension); + // Vnorm + auto freshEncryptionNoise = Berr * (1. + 2. * expansionFactor * Bkey); + + // the logic for finding the parameters for NOISE_FLOODING_HRA + double floodingBound = alpha * cryptoParamsBGVRNS->GetFloodingDistributionParameter(); + double firstModLowerBound = 2.0 * ptm * floodingBound - ptm; + firstModSize = std::ceil(std::log2(firstModLowerBound)); + + // Use one modulus if the first hop fits in 60 bits + // Otherwise use two moduli + if (firstModSize > DCRT_MODULUS::MAX_SIZE) { + firstModSize = 20; + numPrimes++; + } - // Select the size of moduli according to the plaintext modulus - if (dcrtBits == 0) { - dcrtBits = 28 + GetMSB64(ptm); - if (dcrtBits > DCRT_MODULUS::MAX_SIZE) { - dcrtBits = DCRT_MODULUS::MAX_SIZE; + // selects the size of moduli for individual hops + // the noise after modulus swicthing is set to roughly the fresh encryption noise + // which is significantly less than fresh encryption noise + key switching noise that is incurred as + // part of proxy re-encryption + double dcrtBitsNoise = floodingBound / freshEncryptionNoise; + dcrtBits = std::ceil(std::log2(dcrtBitsNoise)); + + // check that the mod size needed for each hop fits in 60 bits + if (dcrtBits > DCRT_MODULUS::MAX_SIZE) { + OPENFHE_THROW("The modulus size for HRA-secure PRE (" + std::to_string(dcrtBits) + + " bits) is above the maximum:" + std::to_string(DCRT_MODULUS::MAX_SIZE) + + ". Try reducing reducing the parameters for noise flooding."); + } } } - // Select firstModSize to be dcrtBits if no indicated otherwise - if (firstModSize == 0) - firstModSize = dcrtBits; - // Size of modulus P uint32_t auxBits = DCRT_MODULUS::MAX_SIZE; // Estimate ciphertext modulus Q bound (in case of GHS/HYBRID P*Q) - usint extraModSize = (scalTech == FLEXIBLEAUTOEXT) ? DCRT_MODULUS::DEFAULT_EXTRA_MOD_SIZE : 0; - uint32_t qBound = firstModSize + (numPrimes - 1) * dcrtBits + extraModSize; - if (ksTech == HYBRID) - qBound += ceil(ceil(static_cast(qBound) / numPartQ) / auxBits) * auxBits; - - // Note this code is not executed if multihopQBound == 0 so it is backwards - // compatable - if (qBound < multihopQBound) { - // need to increase qBound to multihopQBound - qBound = multihopQBound; - - // need to increase numPrimes to support new larger qBound - numPrimes = static_cast((qBound - firstModSize) / static_cast(dcrtBits) + 1); + uint32_t extraModSize = (scalTech == FLEXIBLEAUTOEXT) ? DCRT_MODULUS::DEFAULT_EXTRA_MOD_SIZE : 0; + uint32_t qBound = firstModSize + (numPrimes - 1) * dcrtBits + extraModSize; + + // estimate the extra modulus Q needed for threshold FHE flooding + if (multipartyMode == NOISE_FLOODING_MULTIPARTY) + qBound += cryptoParamsBGVRNS->EstimateMultipartyFloodingLogQ(); + + uint32_t auxTowers = 0; + if (ksTech == HYBRID) { + auto hybridKSInfo = + CryptoParametersRNS::EstimateLogP(numPartQ, firstModSize, dcrtBits, extraModSize, numPrimes, auxBits); + qBound += std::get<0>(hybridKSInfo); + auxTowers = std::get<1>(hybridKSInfo); } + // when the scaling technique is not FIXEDMANUAL (and not FLEXIBLEAUTOEXT), + // set a small value so that the rest of the logic could go through (this is a workaround) + // TODO we should uncouple the logic of FIXEDMANUAL and all FLEXIBLE MODES; some of the code above should be moved + // to the branch for FIXEDMANUAL + if (qBound == 0) + qBound = 20; + + // HE Standards compliance logic/check uint32_t n = computeRingDimension(cryptoParams, qBound, cyclOrder); - //// End HE Standards compliance logic/check uint32_t vecSize = (scalTech != FLEXIBLEAUTOEXT) ? numPrimes : numPrimes + 1; std::vector moduliQ(vecSize); std::vector rootsQ(vecSize); uint64_t modulusOrder = 0; - if ((scalTech == FIXEDAUTO || scalTech == FLEXIBLEAUTO || scalTech == FLEXIBLEAUTOEXT) && (dcrtBitsSet == false)) { - auto moduliInfo = computeModuli(cryptoParams, n, evalAddCount, keySwitchCount, auxBits, numPrimes); + if ((dcrtBits == 0) && (scalTech == FIXEDAUTO || scalTech == FLEXIBLEAUTO || scalTech == FLEXIBLEAUTOEXT)) { + auto moduliInfo = computeModuli(cryptoParams, n, evalAddCount, keySwitchCount, auxTowers, numPrimes); moduliQ = std::get<0>(moduliInfo); uint32_t newQBound = std::get<1>(moduliInfo); - while (qBound < newQBound) { + + // the loop must be executed at least once + do { qBound = newQBound; n = computeRingDimension(cryptoParams, newQBound, cyclOrder); - auto moduliInfo = computeModuli(cryptoParams, n, evalAddCount, keySwitchCount, auxBits, numPrimes); + auto moduliInfo = computeModuli(cryptoParams, n, evalAddCount, keySwitchCount, auxTowers, numPrimes); moduliQ = std::get<0>(moduliInfo); newQBound = std::get<1>(moduliInfo); - if (ksTech == HYBRID) - newQBound += ceil(ceil(static_cast(newQBound) / numPartQ) / auxBits) * auxBits; - } + if (multipartyMode == NOISE_FLOODING_MULTIPARTY) + newQBound += cryptoParamsBGVRNS->EstimateMultipartyFloodingLogQ(); + if (ksTech == HYBRID) { + auto hybridKSInfo = CryptoParametersRNS::EstimateLogP( + numPartQ, std::log2(moduliQ[0].ConvertToDouble()), + (moduliQ.size() > 1) ? std::log2(moduliQ[1].ConvertToDouble()) : 0, + (scalTech == FLEXIBLEAUTOEXT) ? std::log2(moduliQ[moduliQ.size() - 1].ConvertToDouble()) : 0, + (scalTech == FLEXIBLEAUTOEXT) ? moduliQ.size() - 1 : moduliQ.size(), auxBits); + newQBound += std::get<0>(hybridKSInfo); + } + } while (qBound < newQBound); + cyclOrder = 2 * n; modulusOrder = getCyclicOrder(n, ptm, scalTech); @@ -427,12 +499,12 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptr>= 1; pow2ptm <<= 1; @@ -461,11 +533,11 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptr(NOISE_FLOODING::MULTIPARTY_MOD_SIZE, modulusOrder); - std::vector extraModuli(NOISE_FLOODING::NUM_MODULI_MULTIPARTY); - std::vector extraRoots(NOISE_FLOODING::NUM_MODULI_MULTIPARTY); + NativeInteger extraModulus = LastPrime(NoiseFlooding::MULTIPARTY_MOD_SIZE, modulusOrder); + std::vector extraModuli(NoiseFlooding::NUM_MODULI_MULTIPARTY); + std::vector extraRoots(NoiseFlooding::NUM_MODULI_MULTIPARTY); - for (size_t i = 0; i < NOISE_FLOODING::NUM_MODULI_MULTIPARTY; i++) { + for (size_t i = 0; i < NoiseFlooding::NUM_MODULI_MULTIPARTY; i++) { while (std::find(moduliQ.begin(), moduliQ.end(), extraModulus) != moduliQ.end() || std::find(extraModuli.begin(), extraModuli.end(), extraModulus) != extraModuli.end()) { extraModulus = PreviousPrime(extraModulus, modulusOrder); @@ -497,7 +569,7 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptrGetBatchSize() == 0) { // Check whether ptm and cyclOrder are coprime - usint a, b, gcd; + uint32_t a, b, gcd; if (cyclOrder > ptm) { a = cyclOrder; b = ptm; @@ -514,13 +586,13 @@ bool ParameterGenerationBGVRNS::ParamsGenBGVRNS(std::shared_ptrSetEncodingParams(encodingParamsNew); } cryptoParamsBGVRNS->PrecomputeCRTTables(ksTech, scalTech, encTech, multTech, numPartQ, auxBits, 0); - InitializeFloodingDgg(cryptoParams, numPrimes); + + // Validate the ring dimension found using estimated logQ(P) against actual logQ(P) + SecurityLevel stdLevel = cryptoParamsBGVRNS->GetStdLevel(); + if (stdLevel != HEStd_NotSet) { + uint32_t logActualQ = 0; + if (ksTech == HYBRID) { + logActualQ = cryptoParamsBGVRNS->GetParamsQP()->GetModulus().GetMSB(); + } + else { + logActualQ = cryptoParamsBGVRNS->GetElementParams()->GetModulus().GetMSB(); + } + + DistributionType distType = (cryptoParamsBGVRNS->GetSecretKeyDist() == GAUSSIAN) ? HEStd_error : HEStd_ternary; + uint32_t nActual = StdLatticeParm::FindRingDim(distType, stdLevel, logActualQ); + + if (n < nActual) { + std::string errMsg("The ring dimension found using estimated logQ(P) ["); + errMsg += std::to_string(n) + "] does does not meet security requirements. "; + errMsg += "Report this problem to OpenFHE developers and set the ring dimension manually to "; + errMsg += std::to_string(nActual) + "."; + + OPENFHE_THROW(errMsg); + } + } + return true; } diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp index 117f84e38..9d0f2ff09 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-advancedshe.cpp @@ -773,7 +773,7 @@ Ciphertext AdvancedSHECKKSRNS::InnerEvalChebyshevPS(ConstCiphertextModReduceInPlace(cu); } else { - cu = T.front(); + cu = T.front()->Clone(); } } else { @@ -820,14 +820,14 @@ Ciphertext AdvancedSHECKKSRNS::InnerEvalChebyshevPS(ConstCiphertextEvalLinearWSumMutable(ctxs, weights); // the highest order coefficient will always be a power of two up to 2^{m-1} because q is "monic" but the Chebyshev rule adds a factor of 2 // we don't need to increase the depth by multiplying the highest order coefficient, but instead checking and summing, since we work with m <= 4. - Ciphertext sum = T[k - 1]; + Ciphertext sum = T[k - 1]->Clone(); for (uint32_t i = 0; i < log2(divqr->q.back()); i++) { sum = cc->EvalAdd(sum, sum); } cc->EvalAddInPlace(qu, sum); } else { - Ciphertext sum = T[k - 1]; + Ciphertext sum = T[k - 1]->Clone(); for (uint32_t i = 0; i < log2(divqr->q.back()); i++) { sum = cc->EvalAdd(sum, sum); } @@ -864,7 +864,7 @@ Ciphertext AdvancedSHECKKSRNS::InnerEvalChebyshevPS(ConstCiphertextEvalAddInPlace(su, T[k - 1]); } else { - su = T[k - 1]; + su = T[k - 1]->Clone(); } // adds the free term (at x^0) @@ -906,7 +906,7 @@ Ciphertext AdvancedSHECKKSRNS::EvalChebyshevSeriesPS(ConstCiphertext 0)) { + // mult depth = 0 and FLEXIBLEAUTOEXT + // when multiplicative depth = 0, we use the scaling mod size instead of modulus size + // Plaintext modulus is used in EncodingParamsImpl to store the exponent p of the scaling factor + m_scalingFactorsReal[0] = moduliQ[sizeQ - 1].ConvertToDouble(); + m_scalingFactorsReal[1] = pow(2, GetPlaintextModulus()); } else { - m_scalingFactorsReal[1] = moduliQ[sizeQ - 2].ConvertToDouble(); - for (uint32_t k = 2; k < sizeQ; k++) { + m_scalingFactorsReal[0] = moduliQ[sizeQ - 1].ConvertToDouble(); + if (extraBits > 0) + m_scalingFactorsReal[1] = moduliQ[sizeQ - 2].ConvertToDouble(); + const double lastPresetFactor = (extraBits == 0) ? m_scalingFactorsReal[0] : m_scalingFactorsReal[1]; + // number of levels with pre-calculated factors + const size_t numPresetFactors = (extraBits == 0) ? 1 : 2; + + for (size_t k = numPresetFactors; k < sizeQ; k++) { double prevSF = m_scalingFactorsReal[k - 1]; m_scalingFactorsReal[k] = prevSF * prevSF / moduliQ[sizeQ - k].ConvertToDouble(); - double ratio = m_scalingFactorsReal[k] / m_scalingFactorsReal[1]; - + double ratio = m_scalingFactorsReal[k] / lastPresetFactor; if (ratio <= 0.5 || ratio >= 2.0) OPENFHE_THROW( - "CryptoParametersCKKSRNS::PrecomputeCRTTables " - "- FLEXIBLEAUTO cannot support this " - "number of levels in this parameter setting. Please use " - "FIXEDMANUAL."); + "FLEXIBLEAUTO cannot support this number of levels in this parameter setting. Please use FIXEDMANUAL or FIXEDAUTO instead."); } } diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp index 4ef522912..22bf6e99b 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp @@ -51,7 +51,10 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptr(cryptoParams); + // the "const" modifier for cryptoParamsCKKSRNS and encodingParams below doesn't mean that the objects those 2 pointers + // point to are const (not changeable). it means that the pointers themselves are const only. + const auto cryptoParamsCKKSRNS = std::dynamic_pointer_cast(cryptoParams); + const EncodingParams encodingParams = cryptoParamsCKKSRNS->GetEncodingParams(); KeySwitchTechnique ksTech = cryptoParamsCKKSRNS->GetKeySwitchTechnique(); ScalingTechnique scalTech = cryptoParamsCKKSRNS->GetScalingTechnique(); @@ -65,25 +68,25 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptrGetStdLevel(); uint32_t auxBits = AUXMODSIZE; uint32_t n = cyclOrder / 2; uint32_t qBound = firstModSize + (numPrimes - 1) * scalingModSize + extraModSize; - // Estimate ciphertext modulus Q bound (in case of GHS/HYBRID P*Q) + + // Estimate ciphertext modulus Q*P bound (in case of HYBRID P*Q) if (ksTech == HYBRID) { - qBound += ceil(ceil(static_cast(qBound) / numPartQ) / auxBits) * auxBits; + auto hybridKSInfo = + CryptoParametersRNS::EstimateLogP(numPartQ, firstModSize, scalingModSize, extraModSize, numPrimes, auxBits); + qBound += std::get<0>(hybridKSInfo); } // GAUSSIAN security constraint DistributionType distType = (cryptoParamsCKKSRNS->GetSecretKeyDist() == GAUSSIAN) ? HEStd_error : HEStd_ternary; - auto nRLWE = [&](usint q) -> uint32_t { + auto nRLWE = [&](uint32_t q) -> uint32_t { return StdLatticeParm::FindRingDim(distType, stdLevel, q); }; @@ -110,9 +113,15 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptrGetBatchSize() > n / 2) + OPENFHE_THROW("The batch size cannot be larger than ring dimension / 2."); + + if (encodingParams->GetBatchSize() & (encodingParams->GetBatchSize() - 1)) + OPENFHE_THROW("The batch size can only be set to zero (for full packing) or a power of two."); //// End HE Standards compliance logic/check - usint dcrtBits = scalingModSize; + uint32_t dcrtBits = scalingModSize; uint32_t vecSize = (extraModSize == 0) ? numPrimes : numPrimes + 1; std::vector moduliQ(vecSize); @@ -122,107 +131,120 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptr 1) { if (scalTech != FLEXIBLEAUTO && scalTech != FLEXIBLEAUTOEXT) { - uint32_t cnt = 0; - for (usint i = numPrimes - 2; i >= 1; i--) { + NativeInteger qPrev = q; + NativeInteger qNext = q; + for (size_t i = numPrimes - 2, cnt = 0; i >= 1; --i, ++cnt) { if ((cnt % 2) == 0) { - qPrev = PreviousPrime(qPrev, cyclOrder); - q = qPrev; + qPrev = PreviousPrime(qPrev, cyclOrder); + moduliQ[i] = qPrev; } else { - qNext = NextPrime(qNext, cyclOrder); - q = qNext; + qNext = NextPrime(qNext, cyclOrder); + moduliQ[i] = qNext; } - moduliQ[i] = q; - rootsQ[i] = RootOfUnity(cyclOrder, moduliQ[i]); - cnt++; + if (moduliQ[i] > maxPrime) + maxPrime = moduliQ[i]; + else if (moduliQ[i] < minPrime) + minPrime = moduliQ[i]; + + rootsQ[i] = RootOfUnity(cyclOrder, moduliQ[i]); } } else { // FLEXIBLEAUTO /* Scaling factors in FLEXIBLEAUTO are a bit fragile, - * in the sense that once one scaling factor gets far enough from the - * original scaling factor, subsequent level scaling factors quickly - * diverge to either 0 or infinity. To mitigate this problem to a certain - * extend, we have a special prime selection process in place. The goal is - * to maintain the scaling factor of all levels as close to the original - * scale factor of level 0 as possible. - */ - - double sf = moduliQ[numPrimes - 1].ConvertToDouble(); - uint32_t cnt = 0; - for (usint i = numPrimes - 2; i >= 1; i--) { - sf = static_cast(pow(sf, 2) / moduliQ[i + 1].ConvertToDouble()); + * in the sense that once one scaling factor gets far enough from the + * original scaling factor, subsequent level scaling factors quickly + * diverge to either 0 or infinity. To mitigate this problem to a certain + * extend, we have a special prime selection process in place. The goal is + * to maintain the scaling factor of all levels as close to the original + * scale factor of level 0 as possible. + */ + double sf = moduliQ[numPrimes - 1].ConvertToDouble(); + for (size_t i = numPrimes - 2, cnt = 0; i >= 1; --i, ++cnt) { + sf = static_cast(pow(sf, 2) / moduliQ[i + 1].ConvertToDouble()); + NativeInteger sfInt = std::llround(sf); + NativeInteger sfRem = sfInt.Mod(cyclOrder); + bool hasSameMod = true; if ((cnt % 2) == 0) { - NativeInteger sfInt = std::llround(sf); - NativeInteger sfRem = sfInt.Mod(cyclOrder); NativeInteger qPrev = sfInt - NativeInteger(cyclOrder) - sfRem + NativeInteger(1); - - bool hasSameMod = true; while (hasSameMod) { hasSameMod = false; qPrev = PreviousPrime(qPrev, cyclOrder); - for (uint32_t j = i + 1; j < numPrimes; j++) { + for (size_t j = i + 1; j < numPrimes; j++) { if (qPrev == moduliQ[j]) { hasSameMod = true; + break; } } } moduliQ[i] = qPrev; } else { - NativeInteger sfInt = std::llround(sf); - NativeInteger sfRem = sfInt.Mod(cyclOrder); NativeInteger qNext = sfInt + NativeInteger(cyclOrder) - sfRem + NativeInteger(1); - bool hasSameMod = true; while (hasSameMod) { hasSameMod = false; qNext = NextPrime(qNext, cyclOrder); - for (uint32_t j = i + 1; j < numPrimes; j++) { + for (size_t j = i + 1; j < numPrimes; j++) { if (qNext == moduliQ[j]) { hasSameMod = true; + break; } } } moduliQ[i] = qNext; } + if (moduliQ[i] > maxPrime) + maxPrime = moduliQ[i]; + else if (moduliQ[i] < minPrime) + minPrime = moduliQ[i]; rootsQ[i] = RootOfUnity(cyclOrder, moduliQ[i]); - cnt++; } } } if (firstModSize == dcrtBits) { // this requires dcrtBits < 60 - moduliQ[0] = PreviousPrime(qPrev, cyclOrder); + moduliQ[0] = NextPrime(maxPrime, cyclOrder); } else { moduliQ[0] = LastPrime(firstModSize, cyclOrder); + + // find if the value of moduliQ[0] is already in the vector starting with moduliQ[1] and + // if there is, then get another prime for moduliQ[0] + const auto pos = std::find(moduliQ.begin() + 1, moduliQ.end(), moduliQ[0]); + if (pos != moduliQ.end()) { + moduliQ[0] = NextPrime(maxPrime, cyclOrder); + } } + if (moduliQ[0] > maxPrime) + maxPrime = moduliQ[0]; + rootsQ[0] = RootOfUnity(cyclOrder, moduliQ[0]); if (scalTech == FLEXIBLEAUTOEXT) { + // moduliQ[numPrimes] must still be 0, so it has to be populated now + // no need for extra checking as extraModSize is automatically chosen by the library - moduliQ[numPrimes] = FirstPrime(extraModSize - 1, cyclOrder); - rootsQ[numPrimes] = RootOfUnity(cyclOrder, moduliQ[numPrimes]); + auto tempMod = FirstPrime(extraModSize - 1, cyclOrder); + // check if tempMod has a duplicate in the vector (exclude moduliQ[numPrimes] from this operation): + const auto endPos = moduliQ.end() - 1; + auto pos = std::find(moduliQ.begin(), endPos, tempMod); + // if there is a duplicate, then we call NextPrime() + moduliQ[numPrimes] = (pos != endPos) ? NextPrime(maxPrime, cyclOrder) : tempMod; + + rootsQ[numPrimes] = RootOfUnity(cyclOrder, moduliQ[numPrimes]); } auto paramsDCRT = std::make_shared>(cyclOrder, moduliQ, rootsQ); cryptoParamsCKKSRNS->SetElementParams(paramsDCRT); - const EncodingParams encodingParams = cryptoParamsCKKSRNS->GetEncodingParams(); - if (encodingParams->GetBatchSize() > n / 2) - OPENFHE_THROW("The batch size cannot be larger than ring dimension / 2."); - - if (encodingParams->GetBatchSize() & (encodingParams->GetBatchSize() - 1)) - OPENFHE_THROW("The batch size can only be set to zero (for full packing) or a power of two."); - - // if no batch size was specified, we set batchSize = n/2 by default (for full - // packing) + // if no batch size was specified, we set batchSize = n/2 by default (for full packing) if (encodingParams->GetBatchSize() == 0) { uint32_t batchSize = n / 2; EncodingParams encodingParamsNew( @@ -232,6 +254,27 @@ bool ParameterGenerationCKKSRNS::ParamsGenCKKSRNS(std::shared_ptrPrecomputeCRTTables(ksTech, scalTech, encTech, multTech, numPartQ, auxBits, extraModSize); + // Validate the ring dimension found using estimated logQ(P) against actual logQ(P) + if (stdLevel != HEStd_NotSet) { + uint32_t logActualQ = 0; + if (ksTech == HYBRID) { + logActualQ = cryptoParamsCKKSRNS->GetParamsQP()->GetModulus().GetMSB(); + } + else { + logActualQ = cryptoParamsCKKSRNS->GetElementParams()->GetModulus().GetMSB(); + } + + uint32_t nActual = StdLatticeParm::FindRingDim(distType, stdLevel, logActualQ); + if (n < nActual) { + std::string errMsg("The ring dimension found using estimated logQ(P) ["); + errMsg += std::to_string(n) + "] does does not meet security requirements. "; + errMsg += "Report this problem to OpenFHE developers and set the ring dimension manually to "; + errMsg += std::to_string(nActual) + "."; + + OPENFHE_THROW(errMsg); + } + } + return true; } diff --git a/src/pke/lib/scheme/ckksrns/ckksrns-schemeswitching.cpp b/src/pke/lib/scheme/ckksrns/ckksrns-schemeswitching.cpp index c6e5189b7..2a949ba4b 100644 --- a/src/pke/lib/scheme/ckksrns/ckksrns-schemeswitching.cpp +++ b/src/pke/lib/scheme/ckksrns/ckksrns-schemeswitching.cpp @@ -743,7 +743,7 @@ std::vector> ExtractLWEpacked(const CiphertextGetElements()[0]).GetElementAtIndex(0)}; originalB.SetFormat(Format::COEFFICIENT); auto* ptrB = &originalB.GetValues()[0]; - size_t N = originalB.GetLength(); + size_t N = originalB.GetLength(); std::vector> extracted{std::vector(ptrB, ptrB + N), std::vector(ptrA, ptrA + N)}; return extracted; @@ -1382,6 +1382,10 @@ std::vector> SWITCHCKKSRNS::EvalCKKStoFHEW(Co auto ccCKKS = ciphertext->GetCryptoContext(); uint32_t slots = m_numSlotsCKKS; + if (numCtxts == 0 || numCtxts > slots) { + numCtxts = slots; + } + // Step 1. Homomorphic decoding auto ctxtDecoded = EvalSlotsToCoeffsSwitch(*ccCKKS, ciphertext); ccCKKS->GetScheme()->ModReduceInternalInPlace(ctxtDecoded, 1); @@ -1401,10 +1405,6 @@ std::vector> SWITCHCKKSRNS::EvalCKKStoFHEW(Co std::vector> LWEciphertexts(numCtxts); auto AandB = ExtractLWEpacked(ctSwitched); - if (numCtxts == 0 || numCtxts > slots) { - numCtxts = slots; - } - uint32_t gap = ccKS->GetRingDimension() / (2 * slots); for (uint32_t i = 0, idx = 0; i < numCtxts; ++i, idx += gap) { @@ -1622,7 +1622,6 @@ Ciphertext SWITCHCKKSRNS::EvalFHEWtoCKKS(std::vectorEvalChebyshevSeries(BminusAdotS, coefficientsFHEW, a_cheby, b_cheby); if (cryptoParamsCKKS->GetScalingTechnique() != FIXEDMANUAL) { @@ -1667,28 +1666,8 @@ Ciphertext SWITCHCKKSRNS::EvalFHEWtoCKKS(std::vectorGetParamsP()->GetParams(); - - size_t sizeQP = paramsQ.size() + paramsP.size(); - std::vector moduli; - moduli.reserve(sizeQP); - std::vector roots; - roots.reserve(sizeQP); - for (const auto& elem : paramsQ) { - moduli.emplace_back(elem->GetModulus()); - roots.emplace_back(elem->GetRootOfUnity()); - } - for (const auto& elem : paramsP) { - moduli.emplace_back(elem->GetModulus()); - roots.emplace_back(elem->GetRootOfUnity()); - } - - auto elementParamsPtr = std::make_shared>(M, moduli, roots); - auto elementParamsPtr2 = std::dynamic_pointer_cast(elementParamsPtr); - // Use full packing here to clear up the junk in the slots after numValues - auto postScalePlain = ccCKKS->MakeCKKSPackedPlaintext(postScaleVec, 1, towersToDrop, elementParamsPtr2, N / 2); + auto postScalePlain = ccCKKS->MakeCKKSPackedPlaintext(postScaleVec, 1, towersToDrop, nullptr, N / 2); auto BminusAdotSres = ccCKKS->EvalMult(BminusAdotS3, postScalePlain); // Add the plaintext for bias at the correct level and depth diff --git a/src/pke/lib/scheme/gen-cryptocontext-params-impl.cpp b/src/pke/lib/scheme/gen-cryptocontext-params-impl.cpp index da5ee5d75..6f4d6940e 100644 --- a/src/pke/lib/scheme/gen-cryptocontext-params-impl.cpp +++ b/src/pke/lib/scheme/gen-cryptocontext-params-impl.cpp @@ -65,7 +65,7 @@ namespace lbcrypto { SET_TO_SCHEME_DEFAULT(SCHEME, keySwitchCount); \ SET_TO_SCHEME_DEFAULT(SCHEME, encryptionTechnique); \ SET_TO_SCHEME_DEFAULT(SCHEME, multiplicationTechnique); \ - SET_TO_SCHEME_DEFAULT(SCHEME, multiHopModSize); \ + SET_TO_SCHEME_DEFAULT(SCHEME, PRENumHops); \ SET_TO_SCHEME_DEFAULT(SCHEME, PREMode); \ SET_TO_SCHEME_DEFAULT(SCHEME, multipartyMode); \ SET_TO_SCHEME_DEFAULT(SCHEME, executionMode); \ @@ -95,23 +95,6 @@ void Params::SetToDefaults(SCHEME scheme) { } } //==================================================================================================================== -void Params::ValidateRingDim(usint ringDim) { - if (!IsPowerOfTwo(ringDim)) { - std::string errorMsg(std::string("Invalid ringDim [") + std::to_string(ringDim) + - "]. Ring dimension must be a power of 2."); - OPENFHE_THROW(errorMsg); - } -} -//==================================================================================================================== -void Params::ValidateMultiplicativeDepth(usint multiplicativeDepth) { - constexpr usint maxMultiplicativeDepthValue = 1000; - if (multiplicativeDepth > maxMultiplicativeDepthValue) { - std::string errorMsg(std::string("The provided multiplicative depth [") + std::to_string(multiplicativeDepth) + - "] is not computationally feasible. Use a smaller value."); - OPENFHE_THROW(errorMsg); - } -} -//==================================================================================================================== Params::Params(const std::vector& vals) { if (getAllParamsDataMembers().size() != vals.size()) { std::string errMsg(std::string("The number of data members and the number of values do not match: ") + @@ -159,7 +142,7 @@ Params::Params(const std::vector& vals) { if (!(++it)->empty()) multiplicationTechnique = convertToMultiplicationTechnique(*it); if (!(++it)->empty()) - multiHopModSize = static_cast(std::stoul(*it)); + PRENumHops = static_cast(std::stoul(*it)); if (!(++it)->empty()) PREMode = convertToProxyReEncryptionMode(*it); if (!(++it)->empty()) @@ -203,7 +186,7 @@ std::ostream& operator<<(std::ostream& os, const Params& obj) { << "; keySwitchCount: " << obj.keySwitchCount << "; encryptionTechnique: " << obj.encryptionTechnique << "; multiplicationTechnique: " << obj.multiplicationTechnique - << "; multiHopModSize: " << obj.multiHopModSize + << "; PRENumHops: " << obj.PRENumHops << "; PREMode: " << obj.PREMode << "; multipartyMode: " << obj.multipartyMode << "; executionMode: " << obj.executionMode diff --git a/src/pke/lib/scheme/gen-cryptocontext-params-validation.cpp b/src/pke/lib/scheme/gen-cryptocontext-params-validation.cpp new file mode 100644 index 000000000..2834c96dc --- /dev/null +++ b/src/pke/lib/scheme/gen-cryptocontext-params-validation.cpp @@ -0,0 +1,137 @@ +//================================================================================== +// BSD 2-Clause License +// +// Copyright (c) 2014-2024, NJIT, Duality Technologies Inc. and other contributors +// +// All rights reserved. +// +// Author TPOC: contact@openfhe.org +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//================================================================================== +#include "scheme/gen-cryptocontext-params-validation.h" +#include "utils/utilities.h" + +namespace lbcrypto { + +void validateParametersForCryptocontext(const Params& parameters) { + SCHEME scheme = parameters.GetScheme(); + if (isCKKS(scheme)) { + if (NORESCALE == parameters.GetScalingTechnique()) { + OPENFHE_THROW("NORESCALE is not supported in CKKSRNS"); + } + if (NOISE_FLOODING_HRA == parameters.GetPREMode()) { + OPENFHE_THROW("NOISE_FLOODING_HRA is not supported in CKKSRNS"); + } + if (NOISE_FLOODING_MULTIPARTY == parameters.GetMultipartyMode()) { + OPENFHE_THROW("NOISE_FLOODING_MULTIPARTY is not supported in CKKSRNS"); + } + if (MAX_MODULUS_SIZE <= parameters.GetScalingModSize()) { + OPENFHE_THROW("scalingModSize should be less than " + std::to_string(MAX_MODULUS_SIZE)); + } + if (30 != parameters.GetStatisticalSecurity()) { + if (NOISE_FLOODING_MULTIPARTY != parameters.GetMultipartyMode()) { + OPENFHE_THROW("statisticalSecurity is allowed for multipartyMode == NOISE_FLOODING_MULTIPARTY only"); + } + } + if (1 != parameters.GetNumAdversarialQueries()) { + if (NOISE_FLOODING_MULTIPARTY != parameters.GetMultipartyMode()) { + OPENFHE_THROW("numAdversarialQueries is allowed for multipartyMode == NOISE_FLOODING_MULTIPARTY only"); + } + } + } + else if (isBFVRNS(scheme)) { + if (0 == parameters.GetPlaintextModulus()) { + OPENFHE_THROW("PlaintextModulus is not set. It should be set to a non-zero value"); + } + if (NOISE_FLOODING_HRA == parameters.GetPREMode()) { + OPENFHE_THROW("NOISE_FLOODING_HRA is not supported in BFVRNS"); + } + } + else if (isBGVRNS(scheme)) { + if (0 == parameters.GetPlaintextModulus()) { + OPENFHE_THROW("PlaintextModulus is not set. It should be set to a non-zero value"); + } + if (NORESCALE == parameters.GetScalingTechnique()) { + OPENFHE_THROW("NORESCALE is not supported in BGVRNS"); + } + if (NOISE_FLOODING_HRA == parameters.GetPREMode()) { + if (FIXEDMANUAL != parameters.GetScalingTechnique()) { + OPENFHE_THROW("NOISE_FLOODING_HRA is allowed for scalingTechnique == FIXEDMANUAL only"); + } + if (0 == parameters.GetPRENumHops()) { + OPENFHE_THROW("PRENumHops should be set to a value > 0 for PREMode == NOISE_FLOODING_HRA"); + } + if (0 != parameters.GetMultiplicativeDepth()) { + OPENFHE_THROW("multiplicativeDepth should be set to 0 for PREMode == NOISE_FLOODING_HRA"); + } + } + if (0 != parameters.GetFirstModSize()) { + if (FIXEDMANUAL != parameters.GetScalingTechnique()) { + OPENFHE_THROW("firstModSize is allowed for scalingTechnique == FIXEDMANUAL only"); + } + } + if (0 != parameters.GetScalingModSize()) { + if (FIXEDMANUAL != parameters.GetScalingTechnique()) { + OPENFHE_THROW("scalingModSize is allowed for scalingTechnique == FIXEDMANUAL only"); + } + } + if (0 != parameters.GetPRENumHops()) { + if (NOISE_FLOODING_HRA != parameters.GetPREMode()) { + OPENFHE_THROW("PRENumHops is allowed for PREMode == NOISE_FLOODING_HRA only"); + } + } + if (30 != parameters.GetStatisticalSecurity()) { + if (NOISE_FLOODING_HRA != parameters.GetPREMode()) { + OPENFHE_THROW("statisticalSecurity is allowed for PREMode == NOISE_FLOODING_HRA only"); + } + } + if (1 != parameters.GetNumAdversarialQueries()) { + if (NOISE_FLOODING_HRA != parameters.GetPREMode()) { + OPENFHE_THROW("numAdversarialQueries is allowed for PREMode == NOISE_FLOODING_HRA only"); + } + } + } + else { + std::string errMsg(std::string("Unknown schemeId: ") + std::to_string(scheme)); + OPENFHE_THROW(errMsg); + } + + //==================================================================================================================== + // general validations + if (parameters.GetRingDim() && !IsPowerOfTwo(parameters.GetRingDim())) { + std::string errorMsg(std::string("Invalid ringDim [") + std::to_string(parameters.GetRingDim()) + + "]. Ring dimension must be a power of 2."); + OPENFHE_THROW(errorMsg); + } + //==================================================================================================================== + constexpr usint maxMultiplicativeDepthValue = 1000; + if (parameters.GetMultiplicativeDepth() > maxMultiplicativeDepthValue) { + std::string errorMsg(std::string("The provided multiplicative depth [") + + std::to_string(parameters.GetMultiplicativeDepth()) + + "] is not computationally feasible. Use a smaller value."); + OPENFHE_THROW(errorMsg); + } + //==================================================================================================================== +} + +} // namespace lbcrypto diff --git a/src/pke/lib/schemebase/base-advancedshe.cpp b/src/pke/lib/schemebase/base-advancedshe.cpp index e416d7768..b14b5891a 100644 --- a/src/pke/lib/schemebase/base-advancedshe.cpp +++ b/src/pke/lib/schemebase/base-advancedshe.cpp @@ -171,31 +171,10 @@ std::shared_ptr>> AdvancedSHEBase::Eva * we don't validate publicKey as it is needed by NTRU-based scheme only * NTRU-based scheme only and it is checked for null later. */ - const auto cryptoParams = privateKey->GetCryptoParameters(); - const auto encodingParams = cryptoParams->GetEncodingParams(); - const auto elementParams = cryptoParams->GetElementParams(); - usint batchSize = encodingParams->GetBatchSize(); - usint m = elementParams->GetCyclotomicOrder(); - - // stores automorphism indices needed for EvalSum - std::vector indices; - - if (IsPowerOfTwo(m)) { - auto ccInst = privateKey->GetCryptoContext(); - // CKKS Packing - indices = ccInst->getSchemeId() == SCHEME::CKKSRNS_SCHEME ? GenerateIndices2nComplex(batchSize, m) : - GenerateIndices_2n(batchSize, m); - } - else { // Arbitrary cyclotomics - int isize = floor(log2(batchSize)); - indices.reserve(isize); - usint g = encodingParams->GetPlaintextGenerator(); - for (int i = 0; i < isize; i++) { - indices.push_back(g); - g = (g * g) % m; - } - } + // get automorphism indices and convert them to a vector + std::set indx_set{GenerateIndexListForEvalSum(privateKey)}; + std::vector indices(indx_set.begin(), indx_set.end()); auto algo = privateKey->GetCryptoContext()->GetScheme(); return algo->EvalAutomorphismKeyGen(privateKey, indices); @@ -203,52 +182,49 @@ std::shared_ptr>> AdvancedSHEBase::Eva template std::shared_ptr>> AdvancedSHEBase::EvalSumRowsKeyGen( - const PrivateKey privateKey, const PublicKey publicKey, usint rowSize, usint subringDim) const { + const PrivateKey privateKey, usint rowSize, usint subringDim, std::vector& indices) const { auto cc = privateKey->GetCryptoContext(); - if (cc->getSchemeId() != SCHEME::CKKSRNS_SCHEME) - OPENFHE_THROW( - "Matrix summation of row-vectors is only supported for " - "CKKSPackedEncoding."); + if (!isCKKS(cc->getSchemeId())) + OPENFHE_THROW("Matrix summation of row-vectors is only supported for CKKSPackedEncoding."); usint m = (subringDim == 0) ? privateKey->GetCryptoParameters()->GetElementParams()->GetCyclotomicOrder() : subringDim; if (!IsPowerOfTwo(m)) - OPENFHE_THROW( - "Matrix summation of row-vectors is not supported for " - "arbitrary cyclotomics."); + OPENFHE_THROW("Matrix summation of row-vectors is not supported for arbitrary cyclotomics."); - // stores automorphism indices needed for EvalSum - std::vector indices = GenerateIndices2nComplexRows(rowSize, m); + std::set rowsIndices{GenerateIndices2nComplexRows(rowSize, m)}; + indices.reserve(indices.size() + rowsIndices.size()); + indices.insert(indices.end(), rowsIndices.begin(), rowsIndices.end()); auto algo = cc->GetScheme(); - return algo->EvalAutomorphismKeyGen(privateKey, indices); } template std::shared_ptr>> AdvancedSHEBase::EvalSumColsKeyGen( - const PrivateKey privateKey, const PublicKey publicKey) const { + const PrivateKey privateKey, std::vector& indices) const { auto cc = privateKey->GetCryptoContext(); - if (cc->getSchemeId() != SCHEME::CKKSRNS_SCHEME) - OPENFHE_THROW( - "Matrix summation of column-vectors is only supported for " - "CKKSPackedEncoding."); + if (!isCKKS(cc->getSchemeId())) + OPENFHE_THROW("Matrix summation of column-vectors is only supported for CKKSPackedEncoding."); const auto cryptoParams = privateKey->GetCryptoParameters(); usint M = cryptoParams->GetElementParams()->GetCyclotomicOrder(); if (!IsPowerOfTwo(M)) - OPENFHE_THROW( - "Matrix summation of column-vectors is not supported " - "for arbitrary cyclotomics."); + OPENFHE_THROW("Matrix summation of column-vectors is not supported for arbitrary cyclotomics."); - usint batchSize = cryptoParams->GetEncodingParams()->GetBatchSize(); - std::vector indices = GenerateIndices2nComplexCols(batchSize, M); + usint batchSize = cryptoParams->GetEncodingParams()->GetBatchSize(); - auto algo = cc->GetScheme(); + // get indices for EvalSumCols() and merge them with the indices for EvalSum() + std::set evalSumColsIndices = GenerateIndices2nComplexCols(batchSize, M); + std::set evalSumIndices = GenerateIndexListForEvalSum(privateKey); + evalSumColsIndices.merge(evalSumIndices); + indices.reserve(indices.size() + evalSumColsIndices.size()); + indices.insert(indices.end(), evalSumColsIndices.begin(), evalSumColsIndices.end()); + auto algo = cc->GetScheme(); return algo->EvalAutomorphismKeyGen(privateKey, indices); } @@ -261,8 +237,7 @@ Ciphertext AdvancedSHEBase::EvalSum(ConstCiphertext c if ((encodingParams->GetBatchSize() == 0)) OPENFHE_THROW( "EvalSum: Packed encoding parameters 'batch size' is not set; " - "Please " - "check the EncodingParams passed to the crypto context."); + "Please check the EncodingParams passed to the crypto context."); usint m = cryptoParams->GetElementParams()->GetCyclotomicOrder(); @@ -297,81 +272,66 @@ Ciphertext AdvancedSHEBase::EvalSum(ConstCiphertext c } template -Ciphertext AdvancedSHEBase::EvalSumRows(ConstCiphertext ciphertext, usint rowSize, - const std::map>& evalKeyMap, - usint subringDim) const { +Ciphertext AdvancedSHEBase::EvalSumRows(ConstCiphertext ciphertext, uint32_t numRows, + const std::map>& evalSumKeys, + uint32_t subringDim) const { if (ciphertext->GetEncodingType() != CKKS_PACKED_ENCODING) - OPENFHE_THROW( - "Matrix summation of row-vectors is only supported " - "for CKKS packed encoding."); + OPENFHE_THROW("Matrix summation of row-vectors is only supported for CKKS packed encoding."); const auto cryptoParams = ciphertext->GetCryptoParameters(); const auto encodingParams = cryptoParams->GetEncodingParams(); - if ((encodingParams->GetBatchSize() == 0)) OPENFHE_THROW( - "EvalSum: Packed encoding parameters 'batch size' is not set; " - "Please " - "check the EncodingParams passed to the crypto context."); - - usint m = (subringDim == 0) ? cryptoParams->GetElementParams()->GetCyclotomicOrder() : subringDim; + "Packed encoding parameters 'batch size' is not set. Please check the EncodingParams passed to the crypto context."); + uint32_t m = (subringDim == 0) ? cryptoParams->GetElementParams()->GetCyclotomicOrder() : subringDim; if (!IsPowerOfTwo(m)) - OPENFHE_THROW( - "Matrix summation of row-vectors is not supported for " - "arbitrary cyclotomics."); + OPENFHE_THROW("Matrix summation of row-vectors is not supported for arbitrary cyclotomics."); - return EvalSum2nComplexRows(ciphertext->Clone(), rowSize, m, evalKeyMap); + return EvalSum2nComplexRows(ciphertext->Clone(), numRows, m, evalSumKeys); } template Ciphertext AdvancedSHEBase::EvalSumCols( - ConstCiphertext ciphertext, usint batchSize, const std::map>& evalSumKeyMap, - const std::map>& evalSumColsKeyMap) const { + ConstCiphertext ciphertext, uint32_t numCols, const std::map>& evalSumKeyMap, + const std::map>& evalSumColsKeyMap) const { if (!ciphertext) OPENFHE_THROW("Input ciphertext is nullptr"); if (!evalSumKeyMap.size()) OPENFHE_THROW("Input evalKeys map is empty"); if (!evalSumColsKeyMap.size()) OPENFHE_THROW("Input rightEvalKeys map is empty"); - if (ciphertext->GetEncodingType() != CKKS_PACKED_ENCODING) - OPENFHE_THROW( - "Matrix summation of column-vectors is only supported " - "for CKKS packed encoding."); + OPENFHE_THROW("Matrix summation of column-vectors is only supported for CKKS packed encoding."); + + const uint32_t slots = ciphertext->GetSlots(); + if (slots < numCols) + OPENFHE_THROW("The number of columns ca not be greater than the number of slots."); const auto cryptoParams = ciphertext->GetCryptoParameters(); const auto encodingParams = cryptoParams->GetEncodingParams(); - if ((encodingParams->GetBatchSize() == 0)) OPENFHE_THROW( - "EvalSumCols: Packed encoding parameters 'batch size' is not set; " - "Please check the EncodingParams passed to the crypto context."); + "Packed encoding parameters 'batch size' is not set. Please check the EncodingParams passed to the crypto context."); const auto elementParams = cryptoParams->GetElementParams(); - usint m = elementParams->GetCyclotomicOrder(); - + uint32_t m = elementParams->GetCyclotomicOrder(); if (!IsPowerOfTwo(m)) - OPENFHE_THROW( - "Matrix summation of column-vectors is not supported " - "for arbitrary cyclotomics."); - - Ciphertext newCiphertext = EvalSum2nComplex(ciphertext->Clone(), batchSize, m, evalSumKeyMap); + OPENFHE_THROW("Matrix summation of column-vectors is not supported for arbitrary cyclotomics."); - std::vector> mask(m / 4); + std::vector> mask(slots, 0); // create a mask vector and set all its elements to zero for (size_t i = 0; i < mask.size(); i++) { - if (i % batchSize == 0) + if (i % numCols == 0) mask[i] = 1; - else - mask[i] = 0; } - auto cc = ciphertext->GetCryptoContext(); - auto algo = cc->GetScheme(); - Plaintext plaintext = cc->MakeCKKSPackedPlaintext(mask, 1, 0, nullptr, ciphertext->GetSlots()); + Ciphertext newCiphertext = EvalSum2nComplex(ciphertext->Clone(), numCols, m, evalSumKeyMap); + auto cc = ciphertext->GetCryptoContext(); + auto algo = cc->GetScheme(); + Plaintext plaintext = cc->MakeCKKSPackedPlaintext(mask, 1, 0, nullptr, slots); algo->EvalMultInPlace(newCiphertext, plaintext); - return EvalSum2nComplexCols(newCiphertext, batchSize, m, evalSumColsKeyMap); + return EvalSum2nComplexCols(newCiphertext, numCols, m, evalSumColsKeyMap); } template @@ -413,9 +373,7 @@ template Ciphertext AdvancedSHEBase::EvalMerge(const std::vector>& ciphertextVec, const std::map>& evalKeyMap) const { if (ciphertextVec.size() == 0) - OPENFHE_THROW( - "EvalMerge: the vector of ciphertexts to be merged " - "cannot be empty"); + OPENFHE_THROW("the vector of ciphertexts to be merged cannot be empty"); const std::shared_ptr> cryptoParams = ciphertextVec[0]->GetCryptoParameters(); Ciphertext ciphertextMerged(std::make_shared>(*(ciphertextVec[0]))); @@ -444,40 +402,32 @@ Ciphertext AdvancedSHEBase::EvalMerge(const std::vector -std::vector AdvancedSHEBase::GenerateIndices_2n(usint batchSize, usint m) const { - // stores automorphism indices needed for EvalSum - std::vector indices; - +std::set AdvancedSHEBase::GenerateIndices_2n(usint batchSize, usint m) const { + std::set indices; if (batchSize > 1) { - int isize = ceil(log2(batchSize)) - 1; - indices.reserve(isize + 1); - usint g = 5; - for (int i = 0; i < isize; i++) { - indices.push_back(g); + auto isize = static_cast(std::ceil(std::log2(batchSize)) - 1); + usint g = 5; + for (size_t i = 0; i < isize; ++i) { + indices.insert(g); g = (g * g) % m; } if (2 * batchSize < m) - indices.push_back(g); + indices.insert(g); else - indices.push_back(m - 1); + indices.insert(m - 1); } return indices; } template -std::vector AdvancedSHEBase::GenerateIndices2nComplex(usint batchSize, usint m) const { - size_t jsize = ceil(log2(batchSize)); - - // stores automorphism indices needed for EvalSum - std::vector indices; - indices.reserve(jsize); +std::set AdvancedSHEBase::GenerateIndices2nComplex(usint batchSize, usint m) const { + auto isize = static_cast(std::ceil(std::log2(batchSize))); - // generator - usint g = 5; - - for (size_t j = 0; j < jsize; j++) { - indices.push_back(g); + std::set indices; + uint32_t g = 5; + for (size_t i = 0; i < isize; ++i) { + indices.insert(g); g = (g * g) % m; } @@ -485,62 +435,73 @@ std::vector AdvancedSHEBase::GenerateIndices2nComplex(usint batc } template -std::vector AdvancedSHEBase::GenerateIndices2nComplexRows(usint rowSize, usint m) const { - usint colSize = m / (4 * rowSize); - size_t jsize = ceil(log2(colSize)); - - // stores automorphism indices needed for EvalSum - std::vector indices; - indices.reserve(jsize); - - // generator - int32_t g0 = 5; - usint g = 0; - - int32_t f = (NativeInteger(g0).ModExp(rowSize, m)).ConvertToInt(); +std::set AdvancedSHEBase::GenerateIndices2nComplexRows(usint rowSize, usint m) const { + uint32_t colSize = m / (4 * rowSize); + auto isize = static_cast(std::ceil(std::log2(colSize))); + + std::set indices; + uint32_t g = (NativeInteger(5).ModExp(rowSize, m)).ConvertToInt(); + for (size_t i = 0; i < isize; ++i) { + indices.insert(g); + g = (g * g) % m; + } - for (size_t j = 0; j < jsize; j++) { - g = f; + return indices; +} - indices.push_back(g); +template +std::set AdvancedSHEBase::GenerateIndices2nComplexCols(usint batchSize, usint m) const { + auto isize = static_cast(std::ceil(std::log2(batchSize))); - f = (f * f) % m; + std::set indices; + uint32_t g = NativeInteger(5).ModInverse(m).ConvertToInt(); + for (size_t i = 0; i < isize; ++i) { + indices.insert(g); + g = (g * g) % m; } return indices; } template -std::vector AdvancedSHEBase::GenerateIndices2nComplexCols(usint batchSize, usint m) const { - size_t jsize = ceil(log2(batchSize)); - - // stores automorphism indices needed for EvalSum - std::vector indices; - indices.reserve(jsize); - - // generator - int32_t g = NativeInteger(5).ModInverse(m).ConvertToInt(); - usint gFinal = g; +std::set AdvancedSHEBase::GenerateIndexListForEvalSum(const PrivateKey& privateKey) const { + const auto cryptoParams = privateKey->GetCryptoParameters(); + const auto encodingParams = cryptoParams->GetEncodingParams(); + const auto elementParams = cryptoParams->GetElementParams(); - for (size_t j = 0; j < jsize; j++) { - indices.push_back(gFinal); - g = (g * g) % m; + uint32_t batchSize = encodingParams->GetBatchSize(); + uint32_t m = elementParams->GetCyclotomicOrder(); - gFinal = g; + std::set indices; + if (IsPowerOfTwo(m)) { + auto ccInst = privateKey->GetCryptoContext(); + // CKKS Packing + indices = + isCKKS(ccInst->getSchemeId()) ? GenerateIndices2nComplex(batchSize, m) : GenerateIndices_2n(batchSize, m); + } + else { + // Arbitrary cyclotomics + auto isize = static_cast(std::floor(std::log2(batchSize))); + uint32_t g = encodingParams->GetPlaintextGenerator(); + for (size_t i = 0; i < isize; i++) { + indices.insert(g); + g = (g * g) % m; + } } return indices; } template -Ciphertext AdvancedSHEBase::EvalSum_2n(ConstCiphertext ciphertext, usint batchSize, usint m, - const std::map>& evalKeys) const { +Ciphertext AdvancedSHEBase::EvalSum_2n(ConstCiphertext ciphertext, uint32_t batchSize, + uint32_t m, + const std::map>& evalKeys) const { Ciphertext newCiphertext(std::make_shared>(*ciphertext)); auto algo = ciphertext->GetCryptoContext()->GetScheme(); if (batchSize > 1) { - usint g = 5; - for (int i = 0; i < ceil(log2(batchSize)) - 1; i++) { + uint32_t g = 5; + for (size_t i = 0; i < static_cast(std::ceil(std::log2(batchSize))) - 1; ++i) { newCiphertext = algo->EvalAdd(newCiphertext, algo->EvalAutomorphism(newCiphertext, g, evalKeys)); g = (g * g) % m; } @@ -559,16 +520,12 @@ Ciphertext AdvancedSHEBase::EvalSum2nComplex( const std::map>& evalKeys) const { Ciphertext newCiphertext(std::make_shared>(*ciphertext)); - // generator - int32_t g = 5; - usint gFinal = g; - auto algo = ciphertext->GetCryptoContext()->GetScheme(); + uint32_t g = 5; + auto algo = ciphertext->GetCryptoContext()->GetScheme(); - for (int i = 0; i < ceil(log2(batchSize)); i++) { - newCiphertext = algo->EvalAdd(newCiphertext, algo->EvalAutomorphism(newCiphertext, gFinal, evalKeys)); + for (size_t i = 0; i < static_cast(std::ceil(std::log2(batchSize))); ++i) { + newCiphertext = algo->EvalAdd(newCiphertext, algo->EvalAutomorphism(newCiphertext, g, evalKeys)); g = (g * g) % m; - - gFinal = g; } return newCiphertext; @@ -580,20 +537,13 @@ Ciphertext AdvancedSHEBase::EvalSum2nComplexRows( const std::map>& evalKeys) const { Ciphertext newCiphertext(std::make_shared>(*ciphertext)); - usint colSize = m / (4 * rowSize); - - // generator - int32_t g0 = 5; - usint g = 0; - int32_t f = (NativeInteger(g0).ModExp(rowSize, m)).ConvertToInt(); - - auto algo = ciphertext->GetCryptoContext()->GetScheme(); - for (size_t j = 0; j < ceil(log2(colSize)); j++) { - g = f; + uint32_t colSize = m / (4 * rowSize); + uint32_t g = (NativeInteger(5).ModExp(rowSize, m)).ConvertToInt(); + auto algo = ciphertext->GetCryptoContext()->GetScheme(); + for (size_t i = 0; i < static_cast(std::ceil(std::log2(colSize))); ++i) { newCiphertext = algo->EvalAdd(newCiphertext, algo->EvalAutomorphism(newCiphertext, g, evalKeys)); - - f = (f * f) % m; + g = (g * g) % m; } return newCiphertext; @@ -605,17 +555,12 @@ Ciphertext AdvancedSHEBase::EvalSum2nComplexCols( const std::map>& evalKeys) const { Ciphertext newCiphertext(std::make_shared>(*ciphertext)); - // generator - int32_t g = NativeInteger(5).ModInverse(m).ConvertToInt(); - usint gFinal = g; + uint32_t g = NativeInteger(5).ModInverse(m).ConvertToInt(); + auto algo = ciphertext->GetCryptoContext()->GetScheme(); - auto algo = ciphertext->GetCryptoContext()->GetScheme(); - - for (int i = 0; i < ceil(log2(batchSize)); i++) { - newCiphertext = algo->EvalAdd(newCiphertext, algo->EvalAutomorphism(newCiphertext, gFinal, evalKeys)); + for (size_t i = 0; i < static_cast(std::ceil(std::log2(batchSize))); ++i) { + newCiphertext = algo->EvalAdd(newCiphertext, algo->EvalAutomorphism(newCiphertext, g, evalKeys)); g = (g * g) % m; - - gFinal = g; } return newCiphertext; diff --git a/src/pke/lib/schemebase/base-leveledshe.cpp b/src/pke/lib/schemebase/base-leveledshe.cpp index 7ac563a06..29f0cf909 100644 --- a/src/pke/lib/schemebase/base-leveledshe.cpp +++ b/src/pke/lib/schemebase/base-leveledshe.cpp @@ -377,8 +377,8 @@ void LeveledSHEBase::RelinearizeInPlace(Ciphertext& ciphertext ///////////////////////////////////////// template -std::shared_ptr>> LeveledSHEBase::EvalAutomorphismKeyGen( - const PrivateKey privateKey, const std::vector& indexList) const { +std::shared_ptr>> LeveledSHEBase::EvalAutomorphismKeyGen( + const PrivateKey privateKey, const std::vector& indexList) const { // we already have checks on higher level? // auto it = std::find(indexList.begin(), indexList.end(), 2 * n - 1); // if (it != indexList.end()) @@ -388,34 +388,30 @@ std::shared_ptr>> LeveledSHEBase::Eval auto algo = cc->GetScheme(); const Element& s = privateKey->GetPrivateElement(); - usint N = s.GetRingDimension(); + uint32_t N = s.GetRingDimension(); // we already have checks on higher level? // if (indexList.size() > N - 1) // OPENFHE_THROW("size exceeds the ring dimension"); - auto evalKeys = std::make_shared>>(); - - // Do not generate those keys that have been already generated and added to the static storage (map) - const std::string id{privateKey->GetKeyTag()}; - std::vector existingIndices{CryptoContextImpl::GetExistingEvalAutomorphismKeyIndices(id)}; - // if no index found for the given id, then all keys are to be generated - std::vector indicesToGenerate = - (existingIndices.empty()) ? indexList : - CryptoContextImpl::GetUniqueValues(existingIndices, {indexList}); - - // TODO pragma omp currently gives concurrent error - // #pragma omp parallel for if (indicesToGenerate.size() >= 4) - for (usint i = 0; i < indicesToGenerate.size(); i++) { + // create and initialize the key map (key is a value from indexList, EvalKey is nullptr). in this case + // we should be able to assign values to the map without using "omp critical" as all evalKeys' elements would + // have already been created + auto evalKeys = std::make_shared>>(); + for (auto indx : indexList) { + (*evalKeys)[indx]; + } + size_t sz = indexList.size(); +#pragma omp parallel for if (sz >= 4) + for (size_t i = 0; i < sz; ++i) { PrivateKey privateKeyPermuted = std::make_shared>(cc); - usint index = NativeInteger(indicesToGenerate[i]).ModInverse(2 * N).ConvertToInt(); - std::vector vec(N); + uint32_t index = NativeInteger(indexList[i]).ModInverse(2 * N).ConvertToInt(); + std::vector vec(N); PrecomputeAutoMap(N, index, &vec); - Element sPermuted = s.AutomorphismTransform(index, vec); - privateKeyPermuted->SetPrivateElement(sPermuted); - (*evalKeys)[indicesToGenerate[i]] = algo->KeySwitchGen(privateKey, privateKeyPermuted); + privateKeyPermuted->SetPrivateElement(s.AutomorphismTransform(index, vec)); + (*evalKeys)[indexList[i]] = algo->KeySwitchGen(privateKey, privateKeyPermuted); } return evalKeys; @@ -601,6 +597,31 @@ Ciphertext LeveledSHEBase::MorphPlaintext(ConstPlaintext plain ///////////////////////////////////////// // CORE OPERATION ///////////////////////////////////////// +template +void LeveledSHEBase::VerifyNumOfTowers(const ConstCiphertext& ciphertext1, + const ConstCiphertext& ciphertext2, + CALLER_INFO_ARGS_CPP) const { + uint32_t numTowers1 = ciphertext1->GetElements()[0].GetNumOfElements(); + uint32_t numTowers2 = ciphertext2->GetElements()[0].GetNumOfElements(); + if (numTowers1 != numTowers2) { + std::string errorMsg(std::string("Number of towers is not the same for ciphertext1 [") + + std::to_string(numTowers1) + "] and for ciphertext2 [" + std::to_string(numTowers2) + + "] " + CALLER_INFO); + OPENFHE_THROW(errorMsg); + } +} +template +void LeveledSHEBase::VerifyNumOfTowers(const ConstCiphertext& ciphertext, const Element& plaintext, + CALLER_INFO_ARGS_CPP) const { + uint32_t numTowersCtxt = ciphertext->GetElements()[0].GetNumOfElements(); + uint32_t numTowersPtxt = plaintext.GetNumOfElements(); + if (numTowersCtxt != numTowersPtxt) { + std::string errorMsg(std::string("Number of towers is not the same for ciphertext[") + + std::to_string(numTowersCtxt) + "] and for plaintext[" + std::to_string(numTowersPtxt) + + "]" + CALLER_INFO); + OPENFHE_THROW(errorMsg); + } +} template Ciphertext LeveledSHEBase::EvalAddCore(ConstCiphertext ciphertext1, @@ -613,6 +634,7 @@ Ciphertext LeveledSHEBase::EvalAddCore(ConstCiphertext void LeveledSHEBase::EvalAddCoreInPlace(Ciphertext& ciphertext1, ConstCiphertext ciphertext2) const { + VerifyNumOfTowers(ciphertext1, ciphertext2); std::vector& cv1 = ciphertext1->GetElements(); const std::vector& cv2 = ciphertext2->GetElements(); @@ -643,6 +665,7 @@ Ciphertext LeveledSHEBase::EvalSubCore(ConstCiphertext void LeveledSHEBase::EvalSubCoreInPlace(Ciphertext& ciphertext1, ConstCiphertext ciphertext2) const { + VerifyNumOfTowers(ciphertext1, ciphertext2); std::vector& cv1 = ciphertext1->GetElements(); const std::vector& cv2 = ciphertext2->GetElements(); @@ -665,6 +688,7 @@ void LeveledSHEBase::EvalSubCoreInPlace(Ciphertext& ciphertext template Ciphertext LeveledSHEBase::EvalMultCore(ConstCiphertext ciphertext1, ConstCiphertext ciphertext2) const { + VerifyNumOfTowers(ciphertext1, ciphertext2); Ciphertext result = ciphertext1->CloneZero(); std::vector cv1 = ciphertext1->GetElements(); @@ -759,40 +783,44 @@ Ciphertext LeveledSHEBase::EvalSquareCore(ConstCiphertext -Ciphertext LeveledSHEBase::EvalAddCore(ConstCiphertext ciphertext, Element pt) const { +Ciphertext LeveledSHEBase::EvalAddCore(ConstCiphertext ciphertext, const Element& pt) const { Ciphertext result = ciphertext->Clone(); EvalAddCoreInPlace(result, pt); return result; } template -void LeveledSHEBase::EvalAddCoreInPlace(Ciphertext& ciphertext, const Element pt) const { +void LeveledSHEBase::EvalAddCoreInPlace(Ciphertext& ciphertext, const Element& pt) const { + VerifyNumOfTowers(ciphertext, pt); std::vector& cv = ciphertext->GetElements(); cv[0] += pt; } template -Ciphertext LeveledSHEBase::EvalSubCore(ConstCiphertext ciphertext, const Element pt) const { +Ciphertext LeveledSHEBase::EvalSubCore(ConstCiphertext ciphertext, const Element& pt) const { Ciphertext result = ciphertext->Clone(); EvalSubCoreInPlace(result, pt); return result; } template -void LeveledSHEBase::EvalSubCoreInPlace(Ciphertext& ciphertext, const Element pt) const { +void LeveledSHEBase::EvalSubCoreInPlace(Ciphertext& ciphertext, const Element& pt) const { + VerifyNumOfTowers(ciphertext, pt); std::vector& cv = ciphertext->GetElements(); cv[0] -= pt; } template -Ciphertext LeveledSHEBase::EvalMultCore(ConstCiphertext ciphertext, const Element pt) const { +Ciphertext LeveledSHEBase::EvalMultCore(ConstCiphertext ciphertext, + const Element& pt) const { Ciphertext result = ciphertext->Clone(); EvalMultCoreInPlace(result, pt); return result; } template -void LeveledSHEBase::EvalMultCoreInPlace(Ciphertext& ciphertext, const Element pt) const { +void LeveledSHEBase::EvalMultCoreInPlace(Ciphertext& ciphertext, const Element& pt) const { + VerifyNumOfTowers(ciphertext, pt); std::vector& cv = ciphertext->GetElements(); for (auto& c : cv) { c *= pt; diff --git a/src/pke/lib/schemebase/base-multiparty.cpp b/src/pke/lib/schemebase/base-multiparty.cpp index 3fad3ea8a..d4cd4e194 100644 --- a/src/pke/lib/schemebase/base-multiparty.cpp +++ b/src/pke/lib/schemebase/base-multiparty.cpp @@ -185,7 +185,7 @@ std::shared_ptr>> MultipartyBase::Mult std::vector autoIndices(indexList.size()); for (size_t i = 0; i < indexList.size(); i++) { - autoIndices[i] = (cc->getSchemeId() == SCHEME::CKKSRNS_SCHEME) ? + autoIndices[i] = (isCKKS(cc->getSchemeId())) ? FindAutomorphismIndex2nComplex(indexList[i], M) : FindAutomorphismIndex2n(indexList[i], M); } @@ -233,7 +233,7 @@ Ciphertext MultipartyBase::MultipartyDecryptLead(ConstCipherte const Element& s = privateKey->GetPrivateElement(); - DggType dgg(NOISE_FLOODING::MP_SD); + DggType dgg(NoiseFlooding::MP_SD); Element e(dgg, elementParams, Format::EVALUATION); Element b = cv[0] + s * cv[1] + ns * e; @@ -256,7 +256,7 @@ Ciphertext MultipartyBase::MultipartyDecryptMain(ConstCipherte const std::vector& cv = ciphertext->GetElements(); const Element& s = privateKey->GetPrivateElement(); - DggType dgg(NOISE_FLOODING::MP_SD); + DggType dgg(NoiseFlooding::MP_SD); Element e(dgg, elementParams, Format::EVALUATION); // e is added to do noise flooding diff --git a/src/pke/lib/schemebase/base-pke.cpp b/src/pke/lib/schemebase/base-pke.cpp index 7bad76df4..87ff7d14b 100644 --- a/src/pke/lib/schemebase/base-pke.cpp +++ b/src/pke/lib/schemebase/base-pke.cpp @@ -40,7 +40,7 @@ namespace lbcrypto { // makeSparse is not used by this scheme template -KeyPair PKEBase::KeyGenInternal(CryptoContext cc, bool makeSparse) { +KeyPair PKEBase::KeyGenInternal(CryptoContext cc, bool makeSparse) const { KeyPair keyPair(std::make_shared>(cc), std::make_shared>(cc)); diff --git a/src/pke/lib/schemebase/base-pre.cpp b/src/pke/lib/schemebase/base-pre.cpp index bfa85ae98..12d04198f 100644 --- a/src/pke/lib/schemebase/base-pre.cpp +++ b/src/pke/lib/schemebase/base-pre.cpp @@ -65,7 +65,7 @@ Ciphertext PREBase::ReEncrypt(ConstCiphertext ciphert Element enf(cryptoParams->GetFloodingDiscreteGaussianGenerator(), cryptoParams->GetElementParams(), Format::EVALUATION); - auto noise_scale = cryptoParams->GetPlaintextModulus(); + auto noise_scale = cryptoParams->GetNoiseScale(); cv[0] += noise_scale * enf; } algo->KeySwitchInPlace(result, evalKey); diff --git a/src/pke/lib/schemebase/base-scheme.cpp b/src/pke/lib/schemebase/base-scheme.cpp index 567f4bd12..15f30691f 100644 --- a/src/pke/lib/schemebase/base-scheme.cpp +++ b/src/pke/lib/schemebase/base-scheme.cpp @@ -146,12 +146,12 @@ std::shared_ptr>> SchemeBase::EvalSumK template std::shared_ptr>> SchemeBase::EvalSumRowsKeyGen( - const PrivateKey privateKey, const PublicKey publicKey, usint rowSize, usint subringDim) const { + const PrivateKey privateKey, usint rowSize, usint subringDim, std::vector& indices) const { VerifyAdvancedSHEEnabled(__func__); if (!privateKey) OPENFHE_THROW("Input private key is nullptr"); - auto evalKeyMap = m_AdvancedSHE->EvalSumRowsKeyGen(privateKey, publicKey, rowSize, subringDim); + auto evalKeyMap = m_AdvancedSHE->EvalSumRowsKeyGen(privateKey, rowSize, subringDim, indices); for (auto& key : *evalKeyMap) { key.second->SetKeyTag(privateKey->GetKeyTag()); } @@ -160,12 +160,12 @@ std::shared_ptr>> SchemeBase::EvalSumR template std::shared_ptr>> SchemeBase::EvalSumColsKeyGen( - const PrivateKey privateKey, const PublicKey publicKey) const { + const PrivateKey privateKey, std::vector& indices) const { VerifyAdvancedSHEEnabled(__func__); if (!privateKey) OPENFHE_THROW("Input private key is nullptr"); - auto evalKeyMap = m_AdvancedSHE->EvalSumColsKeyGen(privateKey, publicKey); + auto evalKeyMap = m_AdvancedSHE->EvalSumColsKeyGen(privateKey, indices); for (auto& key : *evalKeyMap) { key.second->SetKeyTag(privateKey->GetKeyTag()); } diff --git a/src/pke/lib/schemerns/rns-cryptoparameters.cpp b/src/pke/lib/schemerns/rns-cryptoparameters.cpp index 2b6354c7a..c7f3c8a5e 100644 --- a/src/pke/lib/schemerns/rns-cryptoparameters.cpp +++ b/src/pke/lib/schemerns/rns-cryptoparameters.cpp @@ -70,24 +70,24 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling DiscreteFourierTransform::Initialize(n * 2, n / 2); ChineseRemainderTransformFTT().PreCompute(rootsQ, 2 * n, moduliQ); if (m_ksTechnique == HYBRID) { - // Compute ceil(sizeQ/m_numPartQ), the # of towers per digit - uint32_t a = ceil(static_cast(sizeQ) / numPartQ); - if ((int32_t)(sizeQ - a * (numPartQ - 1)) <= 0) { - auto str = - "CryptoParametersRNS::PrecomputeCRTTables - HYBRID key " - "switching parameters: Can't appropriately distribute " + - std::to_string(sizeQ) + " towers into " + std::to_string(numPartQ) + - " digits. Please select different number of digits."; + // numPartQ can not be zero as there is a division by numPartQ + if (numPartQ == 0) + OPENFHE_THROW("numPartQ is zero"); + + // Compute ceil(sizeQ/numPartQ), the # of towers per digit + uint32_t a = static_cast(std::ceil(static_cast(sizeQ) / numPartQ)); + if (sizeQ <= (a * (numPartQ - 1))) { + auto str = "HYBRID key switching parameters: Can't appropriately distribute " + std::to_string(sizeQ) + + " towers into " + std::to_string(numPartQ) + + " digits. Please select different number of digits."; OPENFHE_THROW(str); } m_numPerPartQ = a; // Compute the composite digits PartQ = Q_j - std::vector moduliPartQ; - moduliPartQ.resize(m_numPartQ); + std::vector moduliPartQ(m_numPartQ, 1); for (usint j = 0; j < m_numPartQ; j++) { - moduliPartQ[j] = BigInteger(1); for (usint i = a * j; i < (j + 1) * a; i++) { if (i < moduliQ.size()) moduliPartQ[j] *= moduliQ[i]; @@ -95,10 +95,8 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling } // Compute PartQHat_i = Q/Q_j - std::vector PartQHat; - PartQHat.resize(m_numPartQ); + std::vector PartQHat(m_numPartQ, 1); for (size_t i = 0; i < m_numPartQ; i++) { - PartQHat[i] = BigInteger(1); for (size_t j = 0; j < m_numPartQ; j++) { if (j != i) PartQHat[i] *= moduliPartQ[j]; @@ -122,16 +120,15 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling std::make_shared>(params[0]->GetCyclotomicOrder(), moduli, roots); } - uint32_t sizeP; // Find number and size of individual special primes. uint32_t maxBits = moduliPartQ[0].GetLengthForBase(2); - for (usint j = 1; j < m_numPartQ; j++) { + for (uint32_t j = 1; j < m_numPartQ; j++) { uint32_t bits = moduliPartQ[j].GetLengthForBase(2); if (bits > maxBits) maxBits = bits; } // Select number of primes in auxiliary CRT basis - sizeP = ceil(static_cast(maxBits) / auxBits); + uint32_t sizeP = static_cast(std::ceil(static_cast(maxBits) / auxBits)); uint64_t primeStep = FindAuxPrimeStep(); // Choose special primes in auxiliary basis and compute their roots @@ -143,7 +140,7 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling NativeInteger firstP = FirstPrime(auxBits, primeStep); NativeInteger pPrev = firstP; BigInteger modulusP(1); - for (usint i = 0; i < sizeP; i++) { + for (uint32_t i = 0; i < sizeP; i++) { // The following loop makes sure that moduli in // P and Q are different bool foundInQ = false; @@ -234,11 +231,11 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling } // Pre-compute compementary partitions for ModUp - uint32_t alpha = ceil(static_cast(sizeQ) / m_numPartQ); + uint32_t alpha = static_cast(std::ceil(static_cast(sizeQ) / m_numPartQ)); m_paramsComplPartQ.resize(sizeQ); m_modComplPartqBarrettMu.resize(sizeQ); for (int32_t l = sizeQ - 1; l >= 0; l--) { - uint32_t beta = ceil(static_cast(l + 1) / alpha); + uint32_t beta = static_cast(std::ceil(static_cast(l + 1) / alpha)); m_paramsComplPartQ[l].resize(beta); m_modComplPartqBarrettMu[l].resize(beta); for (uint32_t j = 0; j < beta; j++) { @@ -305,8 +302,8 @@ void CryptoParametersRNS::PrecomputeCRTTables(KeySwitchTechnique ksTech, Scaling // Pre-compute QHat mod complementary partition qi's m_PartQlHatModp.resize(sizeQ); for (uint32_t l = 0; l < sizeQ; l++) { - uint32_t alpha = ceil(static_cast(sizeQ) / m_numPartQ); - uint32_t beta = ceil(static_cast(l + 1) / alpha); + uint32_t alpha = static_cast(std::ceil(static_cast(sizeQ) / m_numPartQ)); + uint32_t beta = static_cast(std::ceil(static_cast(l + 1) / alpha)); m_PartQlHatModp[l].resize(beta); for (uint32_t k = 0; k < beta; k++) { auto paramsPartQ = GetParamsPartQ(k)->GetParams(); @@ -388,4 +385,51 @@ uint64_t CryptoParametersRNS::FindAuxPrimeStep() const { return GetElementParams()->GetRingDimension(); } +std::pair CryptoParametersRNS::EstimateLogP(uint32_t numPartQ, double firstModulusSize, + double dcrtBits, double extraModulusSize, + uint32_t numPrimes, uint32_t auxBits) { + // numPartQ can not be zero as there is a division by numPartQ + if (numPartQ == 0) + OPENFHE_THROW("numPartQ is zero"); + + size_t sizeQ = numPrimes; + if (extraModulusSize > 0) + sizeQ++; + + // handles a BFV-specific situation where the number of digits might be initially higher than number of RNS limbs in Q + if (numPartQ > sizeQ) + numPartQ = sizeQ; + + // Compute ceil(sizeQ/numPartQ), the # of towers per digit + size_t numPerPartQ = static_cast(std::ceil(static_cast(sizeQ) / numPartQ)); + if (sizeQ <= (numPerPartQ * (numPartQ - 1))) { + auto str = "HYBRID key switching parameters: Can't appropriately distribute " + std::to_string(sizeQ) + + " towers into " + std::to_string(numPartQ) + " digits. Please select different number of digits."; + OPENFHE_THROW(str); + } + + // create a vector with the same value of bit sizes + std::vector qi(sizeQ, dcrtBits); + qi[0] = firstModulusSize; + if (extraModulusSize > 0) + qi[sizeQ - 1] = extraModulusSize; + + // Compute partitions of Q into numPartQ digits + double maxBits = 0; + for (size_t j = 0; j < numPartQ; ++j) { + size_t startTower = j * numPerPartQ; + size_t endTower = ((j + 1) * numPerPartQ - 1 < sizeQ) ? (j + 1) * numPerPartQ - 1 : sizeQ - 1; + + // sum qi elements qi[startTower] + ... + qi[endTower] inclusive. the end element should be qi.begin()+(endTower+1) + double bits = std::accumulate(qi.begin() + startTower, qi.begin() + (endTower + 1), 0.0); + if (bits > maxBits) + maxBits = bits; + } + + // Select number of primes in auxiliary CRT basis + auto sizeP = static_cast(std::ceil(maxBits / auxBits)); + + return std::make_pair(sizeP * auxBits, sizeP); +} + } // namespace lbcrypto diff --git a/src/pke/lib/schemerns/rns-leveledshe.cpp b/src/pke/lib/schemerns/rns-leveledshe.cpp index 429838764..c9aedea1d 100644 --- a/src/pke/lib/schemerns/rns-leveledshe.cpp +++ b/src/pke/lib/schemerns/rns-leveledshe.cpp @@ -83,9 +83,16 @@ Ciphertext LeveledSHERNS::EvalAdd(ConstCiphertext ciphertext } void LeveledSHERNS::EvalAddInPlace(Ciphertext& ciphertext, ConstPlaintext plaintext) const { - auto ctmorphed = MorphPlaintext(plaintext, ciphertext); - AdjustForAddOrSubInPlace(ciphertext, ctmorphed); - EvalAddCoreInPlace(ciphertext, ctmorphed->GetElements()[0]); + const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); + // this branch is for BFV + if (cryptoParams->GetScalingTechnique() == NORESCALE) { + EvalAddCoreInPlace(ciphertext, plaintext->GetElement()); + } + else { + auto ctmorphed = MorphPlaintext(plaintext, ciphertext); + AdjustForAddOrSubInPlace(ciphertext, ctmorphed); + EvalAddCoreInPlace(ciphertext, ctmorphed->GetElements()[0]); + } } Ciphertext LeveledSHERNS::EvalAddMutable(Ciphertext& ciphertext, Plaintext plaintext) const { @@ -147,9 +154,16 @@ Ciphertext LeveledSHERNS::EvalSub(ConstCiphertext ciphertext } void LeveledSHERNS::EvalSubInPlace(Ciphertext& ciphertext, ConstPlaintext plaintext) const { - auto ctmorphed = MorphPlaintext(plaintext, ciphertext); - AdjustForAddOrSubInPlace(ciphertext, ctmorphed); - EvalSubCoreInPlace(ciphertext, ctmorphed->GetElements()[0]); + const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); + // this branch is for BFV + if (cryptoParams->GetScalingTechnique() == NORESCALE) { + EvalAddCoreInPlace(ciphertext, plaintext->GetElement()); + } + else { + auto ctmorphed = MorphPlaintext(plaintext, ciphertext); + AdjustForAddOrSubInPlace(ciphertext, ctmorphed); + EvalSubCoreInPlace(ciphertext, ctmorphed->GetElements()[0]); + } } Ciphertext LeveledSHERNS::EvalSubMutable(Ciphertext& ciphertext, Plaintext plaintext) const { @@ -221,19 +235,26 @@ Ciphertext LeveledSHERNS::EvalMult(ConstCiphertext ciphertex } void LeveledSHERNS::EvalMultInPlace(Ciphertext& ciphertext, ConstPlaintext plaintext) const { - auto ctmorphed = MorphPlaintext(plaintext, ciphertext); - AdjustForMultInPlace(ciphertext, ctmorphed); - EvalMultCoreInPlace(ciphertext, ctmorphed->GetElements()[0]); - const auto cryptoParams = std::dynamic_pointer_cast(ciphertext->GetCryptoParameters()); - ciphertext->SetNoiseScaleDeg(ciphertext->GetNoiseScaleDeg() + ctmorphed->GetNoiseScaleDeg()); - // TODO (Andrey) : This part is only used in CKKS scheme - ciphertext->SetScalingFactor(ciphertext->GetScalingFactor() * ctmorphed->GetScalingFactor()); - // TODO (Andrey) : This part is only used in BGV scheme - if (cryptoParams->GetScalingTechnique() == FLEXIBLEAUTO || cryptoParams->GetScalingTechnique() == FLEXIBLEAUTOEXT) { - const auto plainMod = ciphertext->GetCryptoParameters()->GetPlaintextModulus(); - ciphertext->SetScalingFactorInt( - ciphertext->GetScalingFactorInt().ModMul(ctmorphed->GetScalingFactorInt(), plainMod)); + // this branch is for BFV + if (cryptoParams->GetScalingTechnique() == NORESCALE) { + EvalMultCoreInPlace(ciphertext, plaintext->GetElement()); + } + else { + auto ctmorphed = MorphPlaintext(plaintext, ciphertext); + AdjustForMultInPlace(ciphertext, ctmorphed); + EvalMultCoreInPlace(ciphertext, ctmorphed->GetElements()[0]); + + ciphertext->SetNoiseScaleDeg(ciphertext->GetNoiseScaleDeg() + ctmorphed->GetNoiseScaleDeg()); + // TODO (Andrey) : This part is only used in CKKS scheme + ciphertext->SetScalingFactor(ciphertext->GetScalingFactor() * ctmorphed->GetScalingFactor()); + // TODO (Andrey) : This part is only used in BGV scheme + if (cryptoParams->GetScalingTechnique() == FLEXIBLEAUTO || + cryptoParams->GetScalingTechnique() == FLEXIBLEAUTOEXT) { + const auto plainMod = ciphertext->GetCryptoParameters()->GetPlaintextModulus(); + ciphertext->SetScalingFactorInt( + ciphertext->GetScalingFactorInt().ModMul(ctmorphed->GetScalingFactorInt(), plainMod)); + } } } diff --git a/src/pke/lib/schemerns/rns-multiparty.cpp b/src/pke/lib/schemerns/rns-multiparty.cpp index 5984259e9..6348a4436 100644 --- a/src/pke/lib/schemerns/rns-multiparty.cpp +++ b/src/pke/lib/schemerns/rns-multiparty.cpp @@ -90,7 +90,7 @@ Ciphertext MultipartyRNS::MultipartyDecryptLead(ConstCiphertext MultipartyRNS::MultipartyDecryptMain(ConstCiphertext parameters1; - parameters1.SetMultiplicativeDepth(5); + parameters1.SetMultiplicativeDepth(2); parameters1.SetScalingModSize(40); parameters1.SetRingDim(4096 * 4); parameters1.SetBatchSize(32); diff --git a/src/pke/unittest/UnitTestENCRYPT.cpp b/src/pke/unittest/UnitTestENCRYPT.cpp index 6b2633740..b1245669d 100644 --- a/src/pke/unittest/UnitTestENCRYPT.cpp +++ b/src/pke/unittest/UnitTestENCRYPT.cpp @@ -102,13 +102,13 @@ constexpr usint BV_DSIZE = 4; static std::vector testCases = { // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode { STRING_TEST, "01", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { STRING_TEST, "02", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { STRING_TEST, "03", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { STRING_TEST, "04", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { STRING_TEST, "02", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { STRING_TEST, "03", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { STRING_TEST, "04", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, { STRING_TEST, "05", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { STRING_TEST, "06", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { STRING_TEST, "07", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { STRING_TEST, "08", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { STRING_TEST, "06", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { STRING_TEST, "07", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { STRING_TEST, "08", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 256, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, { STRING_TEST, "09", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, BV, FIXEDMANUAL, DFLT, 256, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT} }, { STRING_TEST, "10", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, BV, FIXEDMANUAL, DFLT, 256, DFLT, DFLT, DFLT, BEHZ, STANDARD, DFLT} }, { STRING_TEST, "11", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, BV, FIXEDMANUAL, DFLT, 256, DFLT, DFLT, DFLT, HPSPOVERQ, STANDARD, DFLT} }, @@ -120,13 +120,13 @@ static std::vector testCases = { // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode { COEF_PACKED_TEST, "01", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { COEF_PACKED_TEST, "02", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { COEF_PACKED_TEST, "03", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { COEF_PACKED_TEST, "04", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { COEF_PACKED_TEST, "02", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { COEF_PACKED_TEST, "03", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { COEF_PACKED_TEST, "04", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, { COEF_PACKED_TEST, "05", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { COEF_PACKED_TEST, "06", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { COEF_PACKED_TEST, "07", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, - { COEF_PACKED_TEST, "08", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { COEF_PACKED_TEST, "06", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { COEF_PACKED_TEST, "07", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, + { COEF_PACKED_TEST, "08", {BGVRNS_SCHEME, 64, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 512, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT} }, { COEF_PACKED_TEST, "09", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, BV, FIXEDMANUAL, DFLT, 512, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT} }, { COEF_PACKED_TEST, "10", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, BV, FIXEDMANUAL, DFLT, 512, DFLT, DFLT, DFLT, BEHZ, STANDARD, DFLT} }, { COEF_PACKED_TEST, "11", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, BV, FIXEDMANUAL, DFLT, 512, DFLT, DFLT, DFLT, HPSPOVERQ, STANDARD, DFLT} }, diff --git a/src/pke/unittest/UnitTestEncoding.cpp b/src/pke/unittest/UnitTestEncoding.cpp index 74b1b0b32..f8acb8000 100644 --- a/src/pke/unittest/UnitTestEncoding.cpp +++ b/src/pke/unittest/UnitTestEncoding.cpp @@ -165,6 +165,7 @@ TEST_F(UTGENERAL_ENCODING, packed_int_ptxt_encoding_DCRTPoly_prime_cyclotomics) PackedEncoding se(paramsDCRT, ep, vectorOfInts1); se.Encode(); + se.GetElement().SetFormat(Format::COEFFICIENT); se.GetElement().SwitchFormat(); se.GetElement().SwitchFormat(); @@ -225,6 +226,7 @@ TEST_F(UTGENERAL_ENCODING, packed_int_ptxt_encoding_DCRTPoly_prime_cyclotomics_n PackedEncoding se(paramsDCRT, ep, vectorOfInts1); se.Encode(); + se.GetElement().SetFormat(Format::COEFFICIENT); se.GetElement().SwitchFormat(); se.GetElement().SwitchFormat(); diff --git a/src/pke/unittest/UnitTestMultihopPRE.cpp b/src/pke/unittest/UnitTestMultihopPRE.cpp index ebb1b3472..1734aec96 100644 --- a/src/pke/unittest/UnitTestMultihopPRE.cpp +++ b/src/pke/unittest/UnitTestMultihopPRE.cpp @@ -45,119 +45,86 @@ using namespace lbcrypto; -class UTGENERAL_MULTIHOP_PRE : public ::testing::TestWithParam { +class UTGENERAL_MULTIHOP_PRE : public ::testing::TestWithParam { protected: - void SetUp() {} - - int run_demo_pre(int security_model) { + int run_demo_pre(uint32_t security_model, uint32_t num_of_hops) { // Generate parameters. - int num_of_hops = 2; - - int plaintextModulus = 2; - usint ringDimension = 1024; - usint digitSize = 1; - usint dcrtbits = 0; - - usint qmodulus = 27; - usint firstqmod = 27; - + PlaintextModulus plaintextModulus{2}; + uint32_t ringDimension; + uint32_t digitSize; CCParams parameters; - parameters.SetPREMode(INDCPA); + if (security_model == 0) { ringDimension = 1024; digitSize = 9; - dcrtbits = 0; - - qmodulus = 27; - firstqmod = 27; parameters.SetPREMode(INDCPA); parameters.SetKeySwitchTechnique(BV); + parameters.SetFirstModSize(27); } else if (security_model == 1) { ringDimension = 2048; - digitSize = 18; - dcrtbits = 0; - - qmodulus = 54; - firstqmod = 54; + digitSize = 16; parameters.SetPREMode(FIXED_NOISE_HRA); parameters.SetKeySwitchTechnique(BV); + parameters.SetFirstModSize(54); } else if (security_model == 2) { ringDimension = 8192; - digitSize = 1; - dcrtbits = 30; - - qmodulus = 218; - firstqmod = 60; + digitSize = 10; parameters.SetPREMode(NOISE_FLOODING_HRA); parameters.SetKeySwitchTechnique(BV); + parameters.SetPRENumHops(num_of_hops); + parameters.SetStatisticalSecurity(40); + parameters.SetNumAdversarialQueries(1048576); } else if (security_model == 3) { ringDimension = 8192; digitSize = 0; - dcrtbits = 30; - - qmodulus = 218; - firstqmod = 60; - uint32_t dnum = 2; parameters.SetPREMode(NOISE_FLOODING_HRA); parameters.SetKeySwitchTechnique(HYBRID); - parameters.SetNumLargeDigits(dnum); + parameters.SetPRENumHops(num_of_hops); + parameters.SetStatisticalSecurity(40); + parameters.SetNumAdversarialQueries(1048576); + } + else { + OPENFHE_THROW("invalid security model"); } parameters.SetMultiplicativeDepth(0); parameters.SetPlaintextModulus(plaintextModulus); parameters.SetRingDim(ringDimension); - parameters.SetFirstModSize(firstqmod); - parameters.SetScalingModSize(dcrtbits); parameters.SetDigitSize(digitSize); parameters.SetScalingTechnique(FIXEDMANUAL); - parameters.SetMultiHopModSize(qmodulus); + parameters.SetSecurityLevel(HEStd_NotSet); - CryptoContext cryptoContext = GenCryptoContext(parameters); - cryptoContext->Enable(PKE); - cryptoContext->Enable(KEYSWITCH); - cryptoContext->Enable(LEVELEDSHE); - cryptoContext->Enable(PRE); + auto cc = GenCryptoContext(parameters); + cc->Enable(PKE); + cc->Enable(KEYSWITCH); + cc->Enable(LEVELEDSHE); + cc->Enable(PRE); //////////////////////////////////////////////////////////// // Perform Key Generation Operation //////////////////////////////////////////////////////////// - // Initialize Key Pair Containers - KeyPair keyPair1; - - keyPair1 = cryptoContext->KeyGen(); - - if (!keyPair1.good()) { - OPENFHE_THROW("Key generation failed!"); - } + auto keyPair1 = cc->KeyGen(); + if (!keyPair1.good()) + OPENFHE_THROW("key generation failed!"); //////////////////////////////////////////////////////////// // Encode source data //////////////////////////////////////////////////////////// - std::vector vectorOfInts; - unsigned int nShort = 0; - int ringsize = 0; - ringsize = cryptoContext->GetRingDimension(); - nShort = ringsize; - - for (size_t i = 0; i < nShort; i++) { - if (plaintextModulus == 2) { - vectorOfInts.push_back(std::rand() % plaintextModulus); - } - else { - vectorOfInts.push_back((std::rand() % plaintextModulus) - (std::floor(plaintextModulus / 2) - 1)); - } - } - Plaintext plaintext = cryptoContext->MakeCoefPackedPlaintext(vectorOfInts); + std::vector vectorOfInts(ringDimension); + for (auto& v : vectorOfInts) + v = (std::rand() % plaintextModulus); + auto plaintext = cc->MakeCoefPackedPlaintext(vectorOfInts); + //////////////////////////////////////////////////////////// // Encryption //////////////////////////////////////////////////////////// - auto ciphertext1 = cryptoContext->Encrypt(keyPair1.publicKey, plaintext); + auto ciphertext1 = cc->Encrypt(keyPair1.publicKey, plaintext); //////////////////////////////////////////////////////////// // Decryption of Ciphertext @@ -165,69 +132,57 @@ class UTGENERAL_MULTIHOP_PRE : public ::testing::TestWithParam { Plaintext plaintextDec1; - cryptoContext->Decrypt(keyPair1.secretKey, ciphertext1, &plaintextDec1); + cc->Decrypt(keyPair1.secretKey, ciphertext1, &plaintextDec1); plaintextDec1->SetLength(plaintext->GetLength()); - Ciphertext reEncryptedCT1, reEncryptedCT; + Ciphertext reEncryptedCT; Plaintext plaintextDec; // multiple hop - std::vector> keyPairs; - std::vector> reEncryptedCTs; - - keyPairs.push_back(keyPair1); - reEncryptedCTs.push_back(ciphertext1); + std::vector> keyPairs{keyPair1}; + std::vector> reEncryptedCTs{ciphertext1}; - for (int i = 0; i < num_of_hops; i++) { - auto keyPair = cryptoContext->KeyGen(); - keyPairs.push_back(keyPair); + for (uint32_t i = 0; i < num_of_hops; ++i) { + keyPairs.push_back(cc->KeyGen()); - auto reencryptionKey = cryptoContext->ReKeyGen(keyPairs[i].secretKey, keyPairs[i + 1].publicKey); + auto reencryptionKey = cc->ReKeyGen(keyPairs[i].secretKey, keyPairs[i + 1].publicKey); switch (security_model) { case 0: // CPA secure PRE - reEncryptedCT = cryptoContext->ReEncrypt(reEncryptedCTs[i], reencryptionKey); // IND-CPA secure + reEncryptedCT = cc->ReEncrypt(reEncryptedCTs[i], reencryptionKey); // IND-CPA secure break; case 1: // Fixed noise (20 bits) practically secure PRE - reEncryptedCT = cryptoContext->ReEncrypt(reEncryptedCTs[i], reencryptionKey, keyPairs[i].publicKey); + reEncryptedCT = cc->ReEncrypt(reEncryptedCTs[i], reencryptionKey, keyPairs[i].publicKey); break; case 2: // Provable HRA secure PRE with noise flooding with BV switching - reEncryptedCT1 = - cryptoContext->ReEncrypt(reEncryptedCTs[i], reencryptionKey, keyPairs[i].publicKey); - reEncryptedCT = cryptoContext->ModReduce(reEncryptedCT1); // mod reduction for noise flooding + reEncryptedCT = cc->ReEncrypt(reEncryptedCTs[i], reencryptionKey, keyPairs[i].publicKey); + if (i < num_of_hops - 1) + reEncryptedCT = cc->ModReduce(reEncryptedCT); // mod reduction for noise flooding break; case 3: // Provable HRA secure PRE with noise flooding with Hybrid switching - reEncryptedCT1 = - cryptoContext->ReEncrypt(reEncryptedCTs[i], reencryptionKey, keyPairs[i].publicKey); - reEncryptedCT = cryptoContext->ModReduce(reEncryptedCT1); // mod reduction for noise flooding + reEncryptedCT = cc->ReEncrypt(reEncryptedCTs[i], reencryptionKey, keyPairs[i].publicKey); + if (i < num_of_hops - 1) + reEncryptedCT = cc->ModReduce(reEncryptedCT); // mod reduction for noise flooding break; default: OPENFHE_THROW("Not a valid security mode"); } - reEncryptedCTs.push_back(reEncryptedCT); } - int kp_size_vec, ct_size_vec; - kp_size_vec = keyPairs.size(); - ct_size_vec = reEncryptedCTs.size(); - - cryptoContext->Decrypt(keyPairs[kp_size_vec - 1].secretKey, reEncryptedCTs[ct_size_vec - 1], &plaintextDec); + cc->Decrypt(keyPairs.back().secretKey, reEncryptedCTs.back(), &plaintextDec); // verification - std::vector unpackedPT, unpackedDecPT; - unpackedPT = plaintextDec1->GetCoefPackedValue(); - unpackedDecPT = plaintextDec->GetCoefPackedValue(); - for (unsigned int j = 0; j < unpackedPT.size(); j++) { + auto& unpackedPT = plaintextDec1->GetCoefPackedValue(); + auto& unpackedDecPT = plaintextDec->GetCoefPackedValue(); + EXPECT_EQ(unpackedPT.size(), unpackedDecPT.size()); + for (size_t j = 0; j < unpackedPT.size(); ++j) { EXPECT_EQ(unpackedPT[j], unpackedDecPT[j]); - if (unpackedPT[j] != unpackedDecPT[j]) { - OPENFHE_THROW("Decryption failure"); - } } return 0; @@ -236,14 +191,12 @@ class UTGENERAL_MULTIHOP_PRE : public ::testing::TestWithParam { TEST_P(UTGENERAL_MULTIHOP_PRE, MULTIHOP_PRE_TEST) { auto test = GetParam(); - run_demo_pre(test); + run_demo_pre(test, 1); + run_demo_pre(test, 3); + run_demo_pre(test, 4); + run_demo_pre(test, 5); } -int Security_Model_Options[4] = {0, 1, 2, 3}; +uint32_t Security_Model_Options[4] = {0, 1, 2, 3}; INSTANTIATE_TEST_SUITE_P(MULTIHOP_PRE_TEST, UTGENERAL_MULTIHOP_PRE, ::testing::ValuesIn(Security_Model_Options)); - -/* -run_demo_pre(0); // IND CPA secure -run_demo_pre(1); // Fixed 20 bits Noise HRA -run_demo_pre(2); // provably secure HRA */ diff --git a/src/pke/unittest/UnitTestMultiparty.cpp b/src/pke/unittest/UnitTestMultiparty.cpp index 169043146..6374d7bff 100644 --- a/src/pke/unittest/UnitTestMultiparty.cpp +++ b/src/pke/unittest/UnitTestMultiparty.cpp @@ -268,30 +268,30 @@ static std::vector testCases = { { BGVRNS_TEST, "06", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, { BGVRNS_TEST, "07", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, { BGVRNS_TEST, "08", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "09", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "10", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "11", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "12", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "13", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "14", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "15", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "16", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "17", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "18", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "19", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "20", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "21", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "22", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "23", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "24", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "25", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "26", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "27", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "28", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "29", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "30", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "31", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "32", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "09", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "10", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "11", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "12", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "13", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "14", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "15", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "16", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "17", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "18", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "19", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "20", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "21", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "22", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "23", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "24", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "25", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "26", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "27", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "28", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "29", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "30", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "31", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "32", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, FIXED_NOISE_MULTIPARTY}, true, 0, "NA"}, { BGVRNS_TEST, "33", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, { BGVRNS_TEST, "34", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, { BGVRNS_TEST, "35", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, @@ -300,30 +300,30 @@ static std::vector testCases = { { BGVRNS_TEST, "38", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, { BGVRNS_TEST, "39", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, { BGVRNS_TEST, "40", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "41", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "42", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "43", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "44", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "45", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "46", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "47", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "48", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "49", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "50", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "51", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "52", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "53", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "54", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "55", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "56", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "57", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "58", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "59", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "60", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, - { BGVRNS_TEST, "61", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "62", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "63", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, - { BGVRNS_TEST, "64", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "41", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "42", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "43", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "44", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "45", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "46", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "47", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "48", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "49", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "50", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "51", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "52", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "53", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "54", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "55", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "56", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "57", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "58", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "59", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "60", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, false, 0, "NA"}, + { BGVRNS_TEST, "61", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "62", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "63", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, + { BGVRNS_TEST, "64", {BGVRNS_SCHEME, 256, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, NOISE_FLOODING_MULTIPARTY}, true, 0, "NA"}, // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize,BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Star, Slots, sharingScheme { BFVRNS_TEST_EXTRA, "01", {BFVRNS_SCHEME, DFLT, DFLT, 60, 20, DFLT, GAUSSIAN, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, 4, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, false, 0, "NA"}, @@ -343,19 +343,19 @@ static std::vector testCases = { { BFVRNS_TEST_EXTRA, "15", {BFVRNS_SCHEME, DFLT, DFLT, 60, 20, DFLT, GAUSSIAN, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, 4, DFLT, DFLT, DFLT, HPSPOVERQLEVELED, EXTENDED, DFLT}, false, 0, "NA"}, { BFVRNS_TEST_EXTRA, "16", {BFVRNS_SCHEME, DFLT, DFLT, 60, 20, DFLT, UNIFORM_TERNARY, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, 16, DFLT, DFLT, DFLT, HPSPOVERQLEVELED, EXTENDED, DFLT}, false, 0, "NA"}, // ========================================== - // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, MultipartyMode, Star, Slots, sharingScheme - { TEST_ABORTS, "01", {BFVRNS_SCHEME, 1024, 2, DFLT, DFLT, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, DFLT, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, - { TEST_ABORTS, "02", {BFVRNS_SCHEME, 1024, 2, DFLT, DFLT, BATCH, UNIFORM_TERNARY, DFLT, DFLT, HEStd_NotSet, DFLT, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, - { TEST_ABORTS, "03", {BFVRNS_SCHEME, 1024, 2, DFLT, DFLT, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, DFLT, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, - { TEST_ABORTS, "04", {BFVRNS_SCHEME, 1024, 2, DFLT, DFLT, BATCH, UNIFORM_TERNARY, DFLT, DFLT, HEStd_NotSet, DFLT, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, - { TEST_ABORTS, "05", {BGVRNS_SCHEME, 1024, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, - { TEST_ABORTS, "06", {BGVRNS_SCHEME, 1024, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, DFLT, 60, HEStd_NotSet, BV, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, - { TEST_ABORTS, "07", {BGVRNS_SCHEME, 1024, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, - { TEST_ABORTS, "08", {BGVRNS_SCHEME, 1024, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, DFLT, 60, HEStd_NotSet, BV, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, - { TEST_ABORTS, "09", {CKKSRNS_SCHEME, 1024, 2, 50, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, - { TEST_ABORTS, "10", {CKKSRNS_SCHEME, 1024, 2, 50, 3, BATCH, UNIFORM_TERNARY, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, - { TEST_ABORTS, "11", {CKKSRNS_SCHEME, 1024, 2, 50, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, - { TEST_ABORTS, "12", {CKKSRNS_SCHEME, 1024, 2, 50, 3, BATCH, UNIFORM_TERNARY, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, + // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, MultipartyMode, Star, Slots, sharingScheme + { TEST_ABORTS, "01", {BFVRNS_SCHEME, 1024, 2, DFLT, DFLT, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, DFLT, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, + { TEST_ABORTS, "02", {BFVRNS_SCHEME, 1024, 2, DFLT, DFLT, BATCH, UNIFORM_TERNARY, DFLT, DFLT, HEStd_NotSet, DFLT, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, + { TEST_ABORTS, "03", {BFVRNS_SCHEME, 1024, 2, DFLT, DFLT, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, DFLT, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, + { TEST_ABORTS, "04", {BFVRNS_SCHEME, 1024, 2, DFLT, DFLT, BATCH, UNIFORM_TERNARY, DFLT, DFLT, HEStd_NotSet, DFLT, DFLT, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, + { TEST_ABORTS, "05", {BGVRNS_SCHEME, 1024, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, + { TEST_ABORTS, "06", {BGVRNS_SCHEME, 1024, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, DFLT, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, + { TEST_ABORTS, "07", {BGVRNS_SCHEME, 1024, 2, DFLT, 3, BATCH, GAUSSIAN, DFLT, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, + { TEST_ABORTS, "08", {BGVRNS_SCHEME, 1024, 2, DFLT, 3, BATCH, UNIFORM_TERNARY, DFLT, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, 65537, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, + { TEST_ABORTS, "09", {CKKSRNS_SCHEME, 1024, 2, 50, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, + { TEST_ABORTS, "10", {CKKSRNS_SCHEME, 1024, 2, 50, 3, BATCH, UNIFORM_TERNARY, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "shamir"}, + { TEST_ABORTS, "11", {CKKSRNS_SCHEME, 1024, 2, 50, 3, BATCH, GAUSSIAN, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, + { TEST_ABORTS, "12", {CKKSRNS_SCHEME, 1024, 2, 50, 3, BATCH, UNIFORM_TERNARY, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, false, 0, "additive"}, // ========================================== }; // clang-format on diff --git a/src/pke/unittest/UnitTestSHE.cpp b/src/pke/unittest/UnitTestSHE.cpp index b8f8f0975..df9ba3ffe 100644 --- a/src/pke/unittest/UnitTestSHE.cpp +++ b/src/pke/unittest/UnitTestSHE.cpp @@ -150,13 +150,13 @@ constexpr usint BV_DSIZE = 4; static std::vector testCases = { // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode { ADD_PACKED, "01", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { ADD_PACKED, "02", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { ADD_PACKED, "03", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { ADD_PACKED, "04", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { ADD_PACKED, "02", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { ADD_PACKED, "03", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { ADD_PACKED, "04", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { ADD_PACKED, "05", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { ADD_PACKED, "06", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { ADD_PACKED, "07", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { ADD_PACKED, "08", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { ADD_PACKED, "06", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { ADD_PACKED, "07", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { ADD_PACKED, "08", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { ADD_PACKED, "09", {BFVRNS_SCHEME, DFLT, 0, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM, DFLT, 1, DFLT, HPS, STANDARD, DFLT}, }, { ADD_PACKED, "10", {BFVRNS_SCHEME, DFLT, 0, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM, DFLT, 1, DFLT, HPS, STANDARD, DFLT}, }, { ADD_PACKED, "11", {BFVRNS_SCHEME, DFLT, 0, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM, DFLT, 1, DFLT, BEHZ, STANDARD, DFLT}, }, @@ -192,13 +192,13 @@ static std::vector testCases = { // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode { MULT_COEF_PACKED, "01", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_COEF_PACKED, "02", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_COEF_PACKED, "03", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_COEF_PACKED, "04", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_COEF_PACKED, "02", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_COEF_PACKED, "03", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_COEF_PACKED, "04", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { MULT_COEF_PACKED, "05", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_COEF_PACKED, "06", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_COEF_PACKED, "07", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_COEF_PACKED, "08", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_COEF_PACKED, "06", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_COEF_PACKED, "07", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_COEF_PACKED, "08", {BGVRNS_SCHEME, 16, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { MULT_COEF_PACKED, "09", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, { MULT_COEF_PACKED, "10", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, { MULT_COEF_PACKED, "11", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM, DFLT, DFLT, DFLT, BEHZ, STANDARD, DFLT}, }, @@ -234,13 +234,13 @@ static std::vector testCases = { // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode { MULT_PACKED, "01", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_PACKED, "02", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_PACKED, "03", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_PACKED, "04", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_PACKED, "02", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_PACKED, "03", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_PACKED, "04", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { MULT_PACKED, "05", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_PACKED, "06", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_PACKED, "07", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { MULT_PACKED, "08", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_PACKED, "06", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_PACKED, "07", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { MULT_PACKED, "08", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { MULT_PACKED, "09", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, { MULT_PACKED, "10", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, { MULT_PACKED, "11", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, BEHZ, STANDARD, DFLT}, }, @@ -276,13 +276,13 @@ static std::vector testCases = { // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode { EVALATINDEX, "01", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALATINDEX, "02", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALATINDEX, "03", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALATINDEX, "04", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALATINDEX, "02", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALATINDEX, "03", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALATINDEX, "04", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { EVALATINDEX, "05", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALATINDEX, "06", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALATINDEX, "07", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALATINDEX, "08", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALATINDEX, "06", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALATINDEX, "07", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALATINDEX, "08", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { EVALATINDEX, "09", {BFVRNS_SCHEME, DFLT, 0, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM_LRG, DFLT, DFLT, 1, HPS, STANDARD, DFLT}, }, { EVALATINDEX, "10", {BFVRNS_SCHEME, DFLT, 0, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM_LRG, DFLT, DFLT, 1, HPS, STANDARD, DFLT}, }, { EVALATINDEX, "11", {BFVRNS_SCHEME, DFLT, 0, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM_LRG, DFLT, DFLT, 1, BEHZ, STANDARD, DFLT}, }, @@ -318,13 +318,13 @@ static std::vector testCases = { // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech EncTech, PREMode { EVALMERGE, "01", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALMERGE, "02", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALMERGE, "03", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALMERGE, "04", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALMERGE, "02", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALMERGE, "03", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALMERGE, "04", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { EVALMERGE, "05", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALMERGE, "06", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALMERGE, "07", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALMERGE, "08", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALMERGE, "06", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALMERGE, "07", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALMERGE, "08", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { EVALMERGE, "09", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, DFLT, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, { EVALMERGE, "10", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, DFLT, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, { EVALMERGE, "11", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, DFLT, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, BEHZ, STANDARD, DFLT}, }, @@ -362,13 +362,13 @@ static std::vector testCases = { // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode { METADATA, "01", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { METADATA, "02", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { METADATA, "03", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { METADATA, "04", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { METADATA, "02", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { METADATA, "03", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { METADATA, "04", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { METADATA, "05", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { METADATA, "06", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { METADATA, "07", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { METADATA, "08", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { METADATA, "06", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { METADATA, "07", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { METADATA, "08", {BGVRNS_SCHEME, 256, 2, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { METADATA, "09", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, DFLT, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, { METADATA, "10", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, DFLT, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, { METADATA, "11", {BFVRNS_SCHEME, DFLT, DFLT, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, DFLT, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, BEHZ, STANDARD, DFLT}, }, @@ -403,13 +403,13 @@ static std::vector testCases = { // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode { EVALSQUARE, "01", {BGVRNS_SCHEME, DFLT, 3, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, DFLT, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, - { EVALSQUARE, "02", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALSQUARE, "03", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALSQUARE, "04", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALSQUARE, "02", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALSQUARE, "03", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALSQUARE, "04", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, UNIFORM_TERNARY, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { EVALSQUARE, "05", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALSQUARE, "06", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALSQUARE, "07", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, - { EVALSQUARE, "08", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, 60, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALSQUARE, "06", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALSQUARE, "07", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, + { EVALSQUARE, "08", {BGVRNS_SCHEME, 256, 3, DFLT, BV_DSIZE, BATCH, GAUSSIAN, 1, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, PTM_LRG, DFLT, DFLT, DFLT, DFLT, STANDARD, DFLT}, }, { EVALSQUARE, "09", {BFVRNS_SCHEME, DFLT, 3, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, DFLT, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, { EVALSQUARE, "10", {BFVRNS_SCHEME, DFLT, 3, DFLT, 20, BATCH, GAUSSIAN, DFLT, DFLT, DFLT, DFLT, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, HPS, STANDARD, DFLT}, }, { EVALSQUARE, "11", {BFVRNS_SCHEME, DFLT, 3, DFLT, 20, BATCH, UNIFORM_TERNARY, DFLT, DFLT, DFLT, DFLT, FIXEDMANUAL, DFLT, PTM_LRG, DFLT, DFLT, DFLT, BEHZ, STANDARD, DFLT}, }, @@ -652,8 +652,12 @@ class UTGENERAL_SHE : public ::testing::TestWithParam { EXPECT_EQ(intArrayExpected->GetPackedValue(), results->GetPackedValue()) << failmsg << " EvalMult fails"; if (!((cc->getSchemeId() == SCHEME::BFVRNS_SCHEME) && - (std::dynamic_pointer_cast(cc->GetCryptoParameters()) - ->GetMultiplicationTechnique() == BEHZ))) { + ((std::dynamic_pointer_cast(cc->GetCryptoParameters()) + ->GetMultiplicationTechnique() == BEHZ) || + (std::dynamic_pointer_cast(cc->GetCryptoParameters()) + ->GetMultiplicationTechnique() == HPS) || + (std::dynamic_pointer_cast(cc->GetCryptoParameters()) + ->GetEncryptionTechnique() == EXTENDED)))) { cResult = cc->Compress(cResult, 1); cc->Decrypt(kp.secretKey, cResult, &results); results->SetLength(intArrayExpected->GetLength()); @@ -668,8 +672,12 @@ class UTGENERAL_SHE : public ::testing::TestWithParam { EXPECT_EQ(intArrayExpected->GetPackedValue(), results->GetPackedValue()) << failmsg << " operator* fails"; if (!((cc->getSchemeId() == SCHEME::BFVRNS_SCHEME) && - (std::dynamic_pointer_cast(cc->GetCryptoParameters()) - ->GetMultiplicationTechnique() == BEHZ))) { + ((std::dynamic_pointer_cast(cc->GetCryptoParameters()) + ->GetMultiplicationTechnique() == BEHZ) || + (std::dynamic_pointer_cast(cc->GetCryptoParameters()) + ->GetMultiplicationTechnique() == HPS) || + (std::dynamic_pointer_cast(cc->GetCryptoParameters()) + ->GetEncryptionTechnique() == EXTENDED)))) { cResult = cc->Compress(cResult, 1); cc->Decrypt(kp.secretKey, cResult, &results); results->SetLength(intArrayExpected->GetLength()); diff --git a/src/pke/unittest/utbfvrns/UnitTestBFVrns.cpp b/src/pke/unittest/utbfvrns/UnitTestBFVrns.cpp index 58cac1385..1d7bd730f 100644 --- a/src/pke/unittest/utbfvrns/UnitTestBFVrns.cpp +++ b/src/pke/unittest/utbfvrns/UnitTestBFVrns.cpp @@ -44,6 +44,7 @@ using namespace lbcrypto; //=========================================================================================================== enum TEST_CASE_TYPE { EVAL_FAST_ROTATION = 0, + COMPRESSED_BFV = 1, }; static std::ostream& operator<<(std::ostream& os, const TEST_CASE_TYPE& type) { @@ -52,6 +53,9 @@ static std::ostream& operator<<(std::ostream& os, const TEST_CASE_TYPE& type) { case EVAL_FAST_ROTATION: typeName = "EVAL_FAST_ROTATION"; break; + case COMPRESSED_BFV: + typeName = "COMPRESSED_BFV"; + break; default: typeName = "UNKNOWN"; break; @@ -91,7 +95,7 @@ static std::ostream& operator<<(std::ostream& os, const TEST_CASE_UTBFVRNS& test return os << test.toString(); } //=========================================================================================================== -constexpr usint MULDEPTH = 5; +constexpr usint MULDEPTH = 7; constexpr usint PTM = 65537; // clang-format off static std::vector testCases = { @@ -104,6 +108,10 @@ static std::vector testCases = { { EVAL_FAST_ROTATION, "06", {BFVRNS_SCHEME, DFLT, MULDEPTH, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, HYBRID, DFLT, DFLT, PTM, DFLT, DFLT, DFLT, HPS, DFLT, DFLT}}, { EVAL_FAST_ROTATION, "07", {BFVRNS_SCHEME, DFLT, MULDEPTH, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM, DFLT, DFLT, DFLT, BEHZ, DFLT, DFLT}}, { EVAL_FAST_ROTATION, "08", {BFVRNS_SCHEME, DFLT, MULDEPTH, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, HYBRID, DFLT, DFLT, PTM, DFLT, DFLT, DFLT, BEHZ, DFLT, DFLT}}, + { COMPRESSED_BFV, "01", {BFVRNS_SCHEME, DFLT, MULDEPTH, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM, DFLT, DFLT, DFLT, HPSPOVERQLEVELED, DFLT, DFLT}}, + { COMPRESSED_BFV, "02", {BFVRNS_SCHEME, DFLT, MULDEPTH, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, HYBRID, DFLT, DFLT, PTM, DFLT, DFLT, DFLT, HPSPOVERQLEVELED, DFLT, DFLT}}, + { COMPRESSED_BFV, "03", {BFVRNS_SCHEME, DFLT, MULDEPTH, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, BV, DFLT, DFLT, PTM, DFLT, DFLT, DFLT, HPSPOVERQ, DFLT, DFLT}}, + { COMPRESSED_BFV, "04", {BFVRNS_SCHEME, DFLT, MULDEPTH, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, HYBRID, DFLT, DFLT, PTM, DFLT, DFLT, DFLT, HPSPOVERQ, DFLT, DFLT}}, // ========================================== }; // clang-format on @@ -161,14 +169,6 @@ class UTBFVRNS : public ::testing::TestWithParam { auto ciphertextRot3 = cc->EvalFastRotation(ciphertextMultResult, 2, M, digits2); auto ciphertextRot4 = cc->EvalFastRotation(ciphertextMultResult, -2, M, digits2); - // Plaintext plaintextMul12; - // cc->Decrypt(keyPair.secretKey, ciphertextMul12, &plaintextMul12); - // plaintextMultResult => { 3 4 3 16 25 36 49 64 81 100 121 144 } - - // Plaintext plaintextMultResult; - // cc->Decrypt(keyPair.secretKey, ciphertextMultResult, &plaintextMultResult); - // plaintextMultResult => { 81 4096 -14912 -16 15300 -29119 3875 16 -2298 15428 -8061 5916 } - // EvalFastRotate +1 (left rotation) std::vector expectedResults1 = {4, 3, 16, 25, 36, 49, 64, 81, 100, 121, 144, 0}; Plaintext plaintextRot1; @@ -213,6 +213,128 @@ class UTBFVRNS : public ::testing::TestWithParam { std::string name("EMSCRIPTEN_UNKNOWN"); #else std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name())); +#endif + std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl; + // make it fail + EXPECT_TRUE(0 == 1) << failmsg; + } + } + + void UnitTest_CompressedBFV(const TEST_CASE_UTBFVRNS& testData, const std::string& failmsg = std::string()) { + try { + CryptoContext cc(UnitTestGenerateContext(testData.params)); + + KeyPair keyPair = cc->KeyGen(); + + // Generate the relinearization key + cc->EvalMultKeyGen(keyPair.secretKey); + + // Generate the rotation evaluation keys + cc->EvalRotateKeyGen(keyPair.secretKey, {1}); + + std::vector vectorOfInts1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 11, 12}; + Plaintext plaintext1 = cc->MakePackedPlaintext(vectorOfInts1, 1, 1); + auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1); + + std::vector vectorOfInts2 = {3, 2, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + Plaintext plaintext2 = cc->MakePackedPlaintext(vectorOfInts2, 1, 1); + auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2); + + std::vector vectorOfInts3 = {1, 2, 5, 2, 5, 6, 7, 8, 9, 9, 11, 12}; + Plaintext plaintext3 = cc->MakePackedPlaintext(vectorOfInts3, 1, 1); + auto ciphertext3 = cc->Encrypt(keyPair.publicKey, plaintext3); + + // Homomorphic multiplications (do enough to drop some levels) + auto ciphertextMul12 = cc->EvalMult(ciphertext1, ciphertext2); + auto ciphertextMultResult = cc->EvalMult(ciphertextMul12, ciphertext3); + auto ciphertextMultCompressed1 = cc->Compress(ciphertextMultResult, 1); + auto ciphertextMultCompressed2 = cc->Compress(ciphertextMultResult, 2); + auto ciphertextSquareResult = cc->EvalSquare(ciphertext1); + + auto digits = cc->EvalFastRotationPrecompute(ciphertextMul12); + const uint32_t M = cc->GetCyclotomicOrder(); + + auto ciphertextRot1 = cc->EvalFastRotation(ciphertextMul12, 1, M, digits); + auto ciphertextRot2 = cc->EvalRotate(ciphertextMul12, 1); + + auto ciphertextPtxtMult = cc->EvalMult(ciphertext1, plaintext2); + + auto ciphertextPtxtAdd = cc->EvalAdd(ciphertext1, plaintext2); + + // Multiplication + std::vector expectedResults1 = {3, 8, 15, 32, 125, 216, 343, 512, 729, 990, 1331, 1728}; + Plaintext plaintextMult; + cc->Decrypt(keyPair.secretKey, ciphertextMultResult, &plaintextMult); + plaintextMult->SetLength(vectorOfInts1.size()); + auto results1 = plaintextMult->GetPackedValue(); + checkEquality(results1, expectedResults1, eps, failmsg + " EvalMult failed"); + + // Squaring + expectedResults1 = {1, 4, 9, 16, 25, 36, 49, 64, 81, 121, 121, 144}; + Plaintext plaintextSquare; + cc->Decrypt(keyPair.secretKey, ciphertextSquareResult, &plaintextSquare); + plaintextSquare->SetLength(vectorOfInts1.size()); + results1 = plaintextSquare->GetPackedValue(); + checkEquality(results1, expectedResults1, eps, failmsg + " EvalSquare failed"); + + // Fast Rotation + expectedResults1 = {4, 3, 16, 25, 36, 49, 64, 81, 110, 121, 144, 0}; + Plaintext plaintextRot1; + cc->Decrypt(keyPair.secretKey, ciphertextRot1, &plaintextRot1); + plaintextRot1->SetLength(vectorOfInts1.size()); + results1 = plaintextRot1->GetPackedValue(); + checkEquality(results1, expectedResults1, eps, failmsg + " EvalFastRotation failed"); + + // Rotation + expectedResults1 = {4, 3, 16, 25, 36, 49, 64, 81, 110, 121, 144, 0}; + Plaintext plaintextRot2; + cc->Decrypt(keyPair.secretKey, ciphertextRot2, &plaintextRot2); + plaintextRot2->SetLength(vectorOfInts1.size()); + results1 = plaintextRot2->GetPackedValue(); + checkEquality(results1, expectedResults1, eps, failmsg + " EvalRotate failed"); + + // Multiplication by plaintext + expectedResults1 = {3, 4, 3, 16, 25, 36, 49, 64, 81, 110, 121, 144}; + Plaintext plaintextPtxtMult; + cc->Decrypt(keyPair.secretKey, ciphertextPtxtMult, &plaintextPtxtMult); + plaintextPtxtMult->SetLength(vectorOfInts1.size()); + results1 = plaintextPtxtMult->GetPackedValue(); + checkEquality(results1, expectedResults1, eps, failmsg + " EvalMult with plaintext failed"); + + // Addition of a plaintext + expectedResults1 = {4, 4, 4, 8, 10, 12, 14, 16, 18, 21, 22, 24}; + Plaintext plaintextPtxtAdd; + cc->Decrypt(keyPair.secretKey, ciphertextPtxtAdd, &plaintextPtxtAdd); + plaintextPtxtAdd->SetLength(vectorOfInts1.size()); + results1 = plaintextPtxtAdd->GetPackedValue(); + checkEquality(results1, expectedResults1, eps, failmsg + " EvalAdd with plaintext failed"); + + // Multiplication - compressed to 1 + expectedResults1 = {3, 8, 15, 32, 125, 216, 343, 512, 729, 990, 1331, 1728}; + Plaintext plaintextMultComp1; + cc->Decrypt(keyPair.secretKey, ciphertextMultCompressed1, &plaintextMultComp1); + plaintextMultComp1->SetLength(vectorOfInts1.size()); + results1 = plaintextMultComp1->GetPackedValue(); + checkEquality(results1, expectedResults1, eps, failmsg + " EvalMult compressed to 1 RNS limb failed"); + + // Multiplication - compressed to 2 + expectedResults1 = {3, 8, 15, 32, 125, 216, 343, 512, 729, 990, 1331, 1728}; + Plaintext plaintextMultComp2; + cc->Decrypt(keyPair.secretKey, ciphertextMultCompressed2, &plaintextMultComp2); + plaintextMultComp2->SetLength(vectorOfInts1.size()); + results1 = plaintextMultComp2->GetPackedValue(); + checkEquality(results1, expectedResults1, eps, failmsg + " EvalMult compressed to 2 RNS limbs failed"); + } + catch (std::exception& e) { + std::cerr << "Exception thrown from " << __func__ << "(): " << e.what() << std::endl; + // make it fail + EXPECT_TRUE(0 == 1) << failmsg; + } + catch (...) { +#if defined EMSCRIPTEN + std::string name("EMSCRIPTEN_UNKNOWN"); +#else + std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name())); #endif std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl; // make it fail @@ -229,6 +351,9 @@ TEST_P(UTBFVRNS, BFVRNS) { case EVAL_FAST_ROTATION: UnitTest_EvalFastRotation(test, test.buildTestName()); break; + case COMPRESSED_BFV: + UnitTest_CompressedBFV(test, test.buildTestName()); + break; default: break; } diff --git a/src/pke/unittest/utbgvrns/UnitTestBGVrns.cpp b/src/pke/unittest/utbgvrns/UnitTestBGVrns.cpp index 5721145ba..f06f6b14d 100644 --- a/src/pke/unittest/utbgvrns/UnitTestBGVrns.cpp +++ b/src/pke/unittest/utbgvrns/UnitTestBGVrns.cpp @@ -53,6 +53,7 @@ enum TEST_CASE_TYPE { COMPRESS_UTBGVRNS, EVAL_FAST_ROTATION_UTBGVRNS, METADATA_UTBGVRNS, + CRYPTOPARAMS_VALIDATION_UTBGVRNS, }; static std::ostream& operator<<(std::ostream& os, const TEST_CASE_TYPE& type) { @@ -85,6 +86,9 @@ static std::ostream& operator<<(std::ostream& os, const TEST_CASE_TYPE& type) { case METADATA_UTBGVRNS: typeName = "METADATA_UTBGVRNS"; break; + case CRYPTOPARAMS_VALIDATION_UTBGVRNS: + typeName = "CRYPTOPARAMS_VALIDATION_UTBGVRNS"; + break; default: typeName = "UNKNOWN_UTBGVRNS"; break; @@ -138,100 +142,108 @@ constexpr usint DSIZE = 0; constexpr usint BV_DSIZE = 4; constexpr usint PTM = 65537; constexpr usint BATCH = 16; -constexpr usint FIRST_MOD_SIZE = 60; +constexpr usint FIRST_MOD_SIZE = 0; constexpr SecurityLevel SEC_LVL = HEStd_NotSet; // clang-format off static std::vector testCasesUTBGVRNS = { // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { ADD_PACKED_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { ADD_PACKED_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { ADD_PACKED_UTBGVRNS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { ADD_PACKED_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { ADD_PACKED_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { ADD_PACKED_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { ADD_PACKED_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { ADD_PACKED_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { ADD_PACKED_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { ADD_PACKED_UTBGVRNS, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { ADD_PACKED_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { ADD_PACKED_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { ADD_PACKED_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { ADD_PACKED_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + /// tests the scenario when plaintext modulus * cyclotomic order > 2^32 + { ADD_PACKED_UTBGVRNS, "09", {BGVRNS_SCHEME, 32768, 3, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { ADD_PACKED_UTBGVRNS, "10", {BGVRNS_SCHEME, 32768, 3, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { MULT_PACKED_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { MULT_PACKED_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { MULT_PACKED_UTBGVRNS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { MULT_PACKED_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { MULT_PACKED_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { MULT_PACKED_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { MULT_PACKED_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { MULT_PACKED_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { MULT_PACKED_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { MULT_PACKED_UTBGVRNS, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { MULT_PACKED_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { MULT_PACKED_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { MULT_PACKED_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { MULT_PACKED_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { EVALATINDEX_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALATINDEX_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { EVALATINDEX_UTBGVRNS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALATINDEX_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALATINDEX_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALATINDEX_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALATINDEX_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALATINDEX_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALATINDEX_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { EVALATINDEX_UTBGVRNS, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALATINDEX_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALATINDEX_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALATINDEX_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALATINDEX_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { EVALMERGE_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { EVALMERGE_UTBGVRNS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { EVALMERGE_UTBGVRNS, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { RE_ENCRYPTION_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { RE_ENCRYPTION_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { RE_ENCRYPTION_UTBGVRNS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { RE_ENCRYPTION_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { RE_ENCRYPTION_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { RE_ENCRYPTION_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, + { RE_ENCRYPTION_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { RE_ENCRYPTION_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { RE_ENCRYPTION_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, { RE_ENCRYPTION_UTBGVRNS, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, - { RE_ENCRYPTION_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, - { RE_ENCRYPTION_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, + { RE_ENCRYPTION_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, + { RE_ENCRYPTION_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { AUTO_LEVEL_REDUCE_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { AUTO_LEVEL_REDUCE_UTBGVRNS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { AUTO_LEVEL_REDUCE_UTBGVRNS, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { COMPRESS_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { COMPRESS_UTBGVRNS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { COMPRESS_UTBGVRNS, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { EVAL_FAST_ROTATION_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_FAST_ROTATION_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { EVAL_FAST_ROTATION_UTBGVRNS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_FAST_ROTATION_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_FAST_ROTATION_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_FAST_ROTATION_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_FAST_ROTATION_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_FAST_ROTATION_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_FAST_ROTATION_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { EVAL_FAST_ROTATION_UTBGVRNS, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_FAST_ROTATION_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_FAST_ROTATION_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_FAST_ROTATION_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_FAST_ROTATION_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { METADATA_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA_UTBGVRNS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { METADATA_UTBGVRNS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA_UTBGVRNS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA_UTBGVRNS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { METADATA_UTBGVRNS, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA_UTBGVRNS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA_UTBGVRNS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + // ========================================== + // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode + { CRYPTOPARAMS_VALIDATION_UTBGVRNS, "01", {BGVRNS_SCHEME, 3, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { CRYPTOPARAMS_VALIDATION_UTBGVRNS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, 60, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { CRYPTOPARAMS_VALIDATION_UTBGVRNS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, BV_DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, NORESCALE, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, }; // clang-format on //=========================================================================================================== @@ -1135,6 +1147,35 @@ class UTBGVRNS : public ::testing::TestWithParam { std::string name("EMSCRIPTEN_UNKNOWN"); #else std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name())); +#endif + std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl; + // make it fail + EXPECT_TRUE(0 == 1) << failmsg; + } + } + + void UnitTest_CryptoparamsValidation(const TEST_CASE_UTBGVRNS& testData, + const std::string& failmsg = std::string()) { + try { + CryptoContext cc(UnitTestGenerateContext(testData.params)); + + // make it fail + EXPECT_EQ(0, 1); + } + catch (OpenFHEException& e) { + // expected an exception + EXPECT_TRUE(1 == 1) << failmsg; + } + catch (std::exception& e) { + std::cerr << "Exception thrown from " << __func__ << "(): " << e.what() << std::endl; + // make it fail + EXPECT_TRUE(0 == 1) << failmsg; + } + catch (...) { +#if defined EMSCRIPTEN + std::string name("EMSCRIPTEN_UNKNOWN"); +#else + std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name())); #endif std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl; // make it fail @@ -1175,6 +1216,9 @@ TEST_P(UTBGVRNS, BGVRNS) { case METADATA_UTBGVRNS: UnitTest_Metadata(test, test.buildTestName()); break; + case CRYPTOPARAMS_VALIDATION_UTBGVRNS: + UnitTest_CryptoparamsValidation(test, test.buildTestName()); + break; default: break; } diff --git a/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv b/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv index 45a7a8178..4c9fe0241 100644 --- a/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv +++ b/src/pke/unittest/utbgvrns/UnitTestBGVrnsAutomorphism.csv @@ -1,4 +1,4 @@ -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,multiHopModSize,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList BGVRNS_AUTOMORPHISM,1,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 BGVRNS_AUTOMORPHISM,2,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 BGVRNS_AUTOMORPHISM,3,BGVRNS_SCHEME,17,1,,,,BV,FIXEDMANUAL,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 @@ -23,7 +23,7 @@ BGVRNS_AUTOMORPHISM,21,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSe BGVRNS_AUTOMORPHISM,22,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 BGVRNS_AUTOMORPHISM,23,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_EVAL_KEY,3|5|7|9|11|13|15 BGVRNS_AUTOMORPHISM,24,BGVRNS_SCHEME,17,1,,,,BV,FLEXIBLEAUTOEXT,,,,,,HEStd_NotSet,8,,,,,,,,,,,,,,,,INVALID_INDEX,3|5|7|9|11|13|15 -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,multiHopModSize,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList EVAL_AT_INDX_PACKED_ARRAY,31,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,SUCCESS,3|5|7|9|11|13|15 EVAL_AT_INDX_PACKED_ARRAY,32,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,CORNER_CASES,0 EVAL_AT_INDX_PACKED_ARRAY,33,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_INPUT_DATA,3|5|7|9|11|13|15 @@ -48,7 +48,7 @@ EVAL_AT_INDX_PACKED_ARRAY,51,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,, EVAL_AT_INDX_PACKED_ARRAY,52,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY,3|5|7|9|11|13|15 EVAL_AT_INDX_PACKED_ARRAY,53,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY,3|5|7|9|11|13|15 EVAL_AT_INDX_PACKED_ARRAY,54,BGVRNS_SCHEME,65537,,,,,,FLEXIBLEAUTOEXT,,,,,,,,,,,,,,,,,,,,,,,NO_KEY_GEN_CALL,3|5|7|9|11|13|15 -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,multiHopModSize,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,Error,indexList EVAL_SUM_PACKED_ARRAY,61,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,SUCCESS, EVAL_SUM_PACKED_ARRAY,62,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_PRIVATE_KEY, EVAL_SUM_PACKED_ARRAY,63,BGVRNS_SCHEME,65537,,,,,,FIXEDMANUAL,,,,,,,,,,,,,,,,,,,,,,,INVALID_PUBLIC_KEY, diff --git a/src/pke/unittest/utbgvrns/UnitTestBGVrnsSerialize.cpp b/src/pke/unittest/utbgvrns/UnitTestBGVrnsSerialize.cpp index 341167fec..cd7112d70 100644 --- a/src/pke/unittest/utbgvrns/UnitTestBGVrnsSerialize.cpp +++ b/src/pke/unittest/utbgvrns/UnitTestBGVrnsSerialize.cpp @@ -119,39 +119,39 @@ constexpr usint MAX_RELIN_DEG = 2; constexpr usint DSIZE = 4; constexpr usint PTM = 65537; constexpr usint BATCH = 16; -constexpr usint FIRST_MOD_SIZE = 60; +constexpr usint FIRST_MOD_SIZE = 0; constexpr SecurityLevel SEC_LVL = HEStd_NotSet; // TODO (dsuponit): are there any changes under this condition - #if NATIVEINT != 128? // clang-format off static std::vector testCases = { // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { CONTEXT, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { CONTEXT, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { CONTEXT, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { CONTEXT, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { CONTEXT, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { CONTEXT, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { CONTEXT, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { CONTEXT, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { CONTEXT, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { CONTEXT, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { CONTEXT, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { CONTEXT, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { CONTEXT, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { CONTEXT, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { KEYS_AND_CIPHERTEXTS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "01", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { KEYS_AND_CIPHERTEXTS, "02", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "03", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "04", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "05", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { KEYS_AND_CIPHERTEXTS, "06", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "09", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "07", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "08", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, 0, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, HYBRID, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "09", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { KEYS_AND_CIPHERTEXTS, "10", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "11", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "12", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "13", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "11", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "12", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "13", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, { KEYS_AND_CIPHERTEXTS, "14", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDMANUAL, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "15", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { KEYS_AND_CIPHERTEXTS, "16", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, FIRST_MOD_SIZE, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "15", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FIXEDAUTO, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { KEYS_AND_CIPHERTEXTS, "16", {BGVRNS_SCHEME, RING_DIM, MULT_DEPTH, DFLT, DSIZE, BATCH, DFLT, MAX_RELIN_DEG, DFLT, SEC_LVL, BV, FLEXIBLEAUTOEXT, DFLT, PTM, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, // ========================================== }; // clang-format on diff --git a/src/pke/unittest/utckksrns/UnitTestCKKSrns.cpp b/src/pke/unittest/utckksrns/UnitTestCKKSrns.cpp index d98576a53..a8c7fa949 100644 --- a/src/pke/unittest/utckksrns/UnitTestCKKSrns.cpp +++ b/src/pke/unittest/utckksrns/UnitTestCKKSrns.cpp @@ -64,6 +64,7 @@ enum TEST_CASE_TYPE { ADD_PACKED_PRECISION, MULT_PACKED_PRECISION, EVALSQUARE, + SMALL_SCALING_MOD_SIZE, }; static std::ostream& operator<<(std::ostream& os, const TEST_CASE_TYPE& type) { @@ -114,6 +115,9 @@ static std::ostream& operator<<(std::ostream& os, const TEST_CASE_TYPE& type) { case EVALSQUARE: typeName = "EVALSQUARE"; break; + case SMALL_SCALING_MOD_SIZE: + typeName = "SMALL_SCALING_MOD_SIZE"; + break; default: typeName = "UNKNOWN"; break; @@ -157,8 +161,6 @@ static std::ostream& operator<<(std::ostream& os, const TEST_CASE_UTCKKSRNS& tes } //=========================================================================================================== /*** - * SMODSIZE: Scaling factor bit-length. - * Should fit into a machine word, i.e., less than 64. * DSIZE: The bit decomposition count used in BV relinearization. * BATCH: The length of the packed vectors to be used with CKKS. */ @@ -166,359 +168,363 @@ constexpr usint RING_DIM = 512; constexpr usint RING_DIM_HALF = 256; constexpr usint DSIZE = 10; constexpr usint BATCH = 8; -#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__) -constexpr usint SMODSIZE = 90; -#else +#if NATIVEINT != 128 && !defined(__EMSCRIPTEN__) constexpr usint RING_DIM_PREC = 2048; // for test cases with approximation error comparison only -constexpr usint SMODSIZE = 50; #endif // MIN_PRECISION_DIFF is the minimal difference expected between approximation error/precision for FLEXIBLEAUTO and FLEXIBLEAUTOEXT constexpr double MIN_PRECISION_DIFF = 1.5; // clang-format off static std::vector testCases = { // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots - { ADD_PACKED, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { ADD_PACKED, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { ADD_PACKED, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { ADD_PACKED, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { ADD_PACKED, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { ADD_PACKED, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { ADD_PACKED, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { ADD_PACKED, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, #if NATIVEINT != 128 - { ADD_PACKED, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { ADD_PACKED, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { ADD_PACKED, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { ADD_PACKED, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { ADD_PACKED, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { ADD_PACKED, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { ADD_PACKED, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { ADD_PACKED, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots, LowPrec, HighPrec - { ADD_PACKED_PRECISION, "01", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, - { ADD_PACKED_PRECISION, "02", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { ADD_PACKED_PRECISION, "01", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { ADD_PACKED_PRECISION, "02", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + // Special cases when mult depth = 0 and FLEXIBLEAUTO* modes are used; checks that the scaling factor set correctly + { ADD_PACKED, "11", {CKKSRNS_SCHEME, RING_DIM, 0, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { ADD_PACKED, "12", {CKKSRNS_SCHEME, RING_DIM, 0, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots - { ADD_PACKED, "21", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { ADD_PACKED, "22", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { ADD_PACKED, "23", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { ADD_PACKED, "24", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { ADD_PACKED, "21", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { ADD_PACKED, "22", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { ADD_PACKED, "23", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { ADD_PACKED, "24", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, #if NATIVEINT != 128 - { ADD_PACKED, "25", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { ADD_PACKED, "26", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { ADD_PACKED, "27", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { ADD_PACKED, "28", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { ADD_PACKED, "25", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { ADD_PACKED, "26", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { ADD_PACKED, "27", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { ADD_PACKED, "28", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots, LowPrec, HighPrec - { ADD_PACKED_PRECISION, "21", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, - { ADD_PACKED_PRECISION, "22", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { ADD_PACKED_PRECISION, "21", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { ADD_PACKED_PRECISION, "22", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots - { ADD_PACKED, "31", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { ADD_PACKED, "32", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { ADD_PACKED, "33", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { ADD_PACKED, "34", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { ADD_PACKED, "31", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { ADD_PACKED, "32", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { ADD_PACKED, "33", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { ADD_PACKED, "34", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, #if NATIVEINT != 128 - { ADD_PACKED, "35", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { ADD_PACKED, "36", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { ADD_PACKED, "37", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { ADD_PACKED, "38", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { ADD_PACKED, "35", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { ADD_PACKED, "36", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { ADD_PACKED, "37", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { ADD_PACKED, "38", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots, LowPrec, HighPrec - { ADD_PACKED_PRECISION, "31", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, - { ADD_PACKED_PRECISION, "32", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { ADD_PACKED_PRECISION, "31", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { ADD_PACKED_PRECISION, "32", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots - { MULT_PACKED, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, #if NATIVEINT != 128 - { MULT_PACKED, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots, LowPrec, HighPrec - { MULT_PACKED_PRECISION, "01", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, - { MULT_PACKED_PRECISION, "02", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, - { MULT_PACKED_PRECISION, "03", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FIXEDAUTO, FLEXIBLEAUTO}, - { MULT_PACKED_PRECISION, "04", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FIXEDAUTO, FLEXIBLEAUTO}, + { MULT_PACKED_PRECISION, "01", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { MULT_PACKED_PRECISION, "02", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { MULT_PACKED_PRECISION, "03", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FIXEDAUTO, FLEXIBLEAUTO}, + { MULT_PACKED_PRECISION, "04", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FIXEDAUTO, FLEXIBLEAUTO}, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots - { MULT_PACKED, "11", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "12", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "13", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "14", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "11", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "12", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "13", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "14", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, #if NATIVEINT != 128 - { MULT_PACKED, "15", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "16", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "17", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { MULT_PACKED, "18", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "15", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "16", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "17", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { MULT_PACKED, "18", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots, LowPrec, HighPrec - { MULT_PACKED_PRECISION, "11", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, - { MULT_PACKED_PRECISION, "12", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, - { MULT_PACKED_PRECISION, "13", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FIXEDAUTO, FLEXIBLEAUTO}, - { MULT_PACKED_PRECISION, "14", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FIXEDAUTO, FLEXIBLEAUTO}, + { MULT_PACKED_PRECISION, "11", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { MULT_PACKED_PRECISION, "12", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { MULT_PACKED_PRECISION, "13", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FIXEDAUTO, FLEXIBLEAUTO}, + { MULT_PACKED_PRECISION, "14", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0, FIXEDAUTO, FLEXIBLEAUTO}, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots - { MULT_PACKED, "21", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { MULT_PACKED, "22", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { MULT_PACKED, "23", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { MULT_PACKED, "24", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { MULT_PACKED, "21", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { MULT_PACKED, "22", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { MULT_PACKED, "23", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { MULT_PACKED, "24", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, #if NATIVEINT != 128 - { MULT_PACKED, "25", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { MULT_PACKED, "26", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { MULT_PACKED, "27", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { MULT_PACKED, "28", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { MULT_PACKED, "25", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { MULT_PACKED, "26", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { MULT_PACKED, "27", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { MULT_PACKED, "28", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots, LowPrec, HighPrec - { MULT_PACKED_PRECISION, "21", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, - { MULT_PACKED_PRECISION, "22", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, - { MULT_PACKED_PRECISION, "23", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH, FIXEDAUTO, FLEXIBLEAUTO}, - { MULT_PACKED_PRECISION, "24", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH, FIXEDAUTO, FLEXIBLEAUTO}, + { MULT_PACKED_PRECISION, "21", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { MULT_PACKED_PRECISION, "22", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH, FLEXIBLEAUTO, FLEXIBLEAUTOEXT}, + { MULT_PACKED_PRECISION, "23", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH, FIXEDAUTO, FLEXIBLEAUTO}, + { MULT_PACKED_PRECISION, "24", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH, FIXEDAUTO, FLEXIBLEAUTO}, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots - { MULT_PACKED, "31", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { MULT_PACKED, "32", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { MULT_PACKED, "33", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { MULT_PACKED, "34", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { MULT_PACKED, "31", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { MULT_PACKED, "32", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { MULT_PACKED, "33", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { MULT_PACKED, "34", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, #if NATIVEINT != 128 - { MULT_PACKED, "35", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { MULT_PACKED, "36", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { MULT_PACKED, "37", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, - { MULT_PACKED, "38", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { MULT_PACKED, "35", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { MULT_PACKED, "36", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { MULT_PACKED, "37", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, + { MULT_PACKED, "38", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32}, // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots, LowPrec, HighPrec - { MULT_PACKED_PRECISION, "31", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FLEXIBLEAUTO, FLEXIBLEAUTOEXT }, - { MULT_PACKED_PRECISION, "32", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FLEXIBLEAUTO, FLEXIBLEAUTOEXT }, - { MULT_PACKED_PRECISION, "33", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FIXEDAUTO, FLEXIBLEAUTO }, - { MULT_PACKED_PRECISION, "34", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FIXEDAUTO, FLEXIBLEAUTO }, + { MULT_PACKED_PRECISION, "31", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FLEXIBLEAUTO, FLEXIBLEAUTOEXT }, + { MULT_PACKED_PRECISION, "32", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FLEXIBLEAUTO, FLEXIBLEAUTOEXT }, + { MULT_PACKED_PRECISION, "33", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FIXEDAUTO, FLEXIBLEAUTO }, + { MULT_PACKED_PRECISION, "34", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 32, FIXEDAUTO, FLEXIBLEAUTO }, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots - { MULT_PACKED, "41", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { MULT_PACKED, "42", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { MULT_PACKED, "43", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { MULT_PACKED, "44", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { MULT_PACKED, "41", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { MULT_PACKED, "42", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { MULT_PACKED, "43", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { MULT_PACKED, "44", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, #if NATIVEINT != 128 - { MULT_PACKED, "45", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { MULT_PACKED, "46", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { MULT_PACKED, "47", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { MULT_PACKED, "48", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { MULT_PACKED, "45", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { MULT_PACKED, "46", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { MULT_PACKED, "47", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { MULT_PACKED, "48", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots, LowPrec, HighPrec - { MULT_PACKED_PRECISION, "41", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FLEXIBLEAUTO, FLEXIBLEAUTOEXT }, - { MULT_PACKED_PRECISION, "42", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FLEXIBLEAUTO, FLEXIBLEAUTOEXT }, - { MULT_PACKED_PRECISION, "43", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FIXEDAUTO, FLEXIBLEAUTO }, - { MULT_PACKED_PRECISION, "44", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FIXEDAUTO, FLEXIBLEAUTO }, + { MULT_PACKED_PRECISION, "41", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FLEXIBLEAUTO, FLEXIBLEAUTOEXT }, + { MULT_PACKED_PRECISION, "42", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FLEXIBLEAUTO, FLEXIBLEAUTOEXT }, + { MULT_PACKED_PRECISION, "43", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FIXEDAUTO, FLEXIBLEAUTO }, + { MULT_PACKED_PRECISION, "44", {CKKSRNS_SCHEME, RING_DIM_PREC, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF, FIXEDAUTO, FLEXIBLEAUTO }, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { SCALE_FACTOR_ADJUSTMENTS, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { SCALE_FACTOR_ADJUSTMENTS, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, // TODO (dsuponit): review 2 commented tests below with FIXEDMANUAL - //{ SCALE_FACTOR_ADJUSTMENTS, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { SCALE_FACTOR_ADJUSTMENTS, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - //{ SCALE_FACTOR_ADJUSTMENTS, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + //{ SCALE_FACTOR_ADJUSTMENTS, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { SCALE_FACTOR_ADJUSTMENTS, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + //{ SCALE_FACTOR_ADJUSTMENTS, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #if NATIVEINT != 128 - { SCALE_FACTOR_ADJUSTMENTS, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { SCALE_FACTOR_ADJUSTMENTS, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { SCALE_FACTOR_ADJUSTMENTS, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { SCALE_FACTOR_ADJUSTMENTS, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { SCALE_FACTOR_ADJUSTMENTS, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { SCALE_FACTOR_ADJUSTMENTS, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { SCALE_FACTOR_ADJUSTMENTS, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { SCALE_FACTOR_ADJUSTMENTS, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { AUTO_LEVEL_REDUCE, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #if NATIVEINT != 128 - { AUTO_LEVEL_REDUCE, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { AUTO_LEVEL_REDUCE, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { AUTO_LEVEL_REDUCE, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { COMPRESS, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #if NATIVEINT != 128 - { COMPRESS, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { COMPRESS, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { COMPRESS, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots - { EVAL_FAST_ROTATION, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVAL_FAST_ROTATION, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVAL_FAST_ROTATION, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVAL_FAST_ROTATION, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVAL_FAST_ROTATION, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVAL_FAST_ROTATION, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVAL_FAST_ROTATION, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVAL_FAST_ROTATION, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, #if NATIVEINT != 128 - { EVAL_FAST_ROTATION, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVAL_FAST_ROTATION, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVAL_FAST_ROTATION, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVAL_FAST_ROTATION, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVAL_FAST_ROTATION, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVAL_FAST_ROTATION, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVAL_FAST_ROTATION, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVAL_FAST_ROTATION, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, #endif - { EVAL_FAST_ROTATION, "09", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, - { EVAL_FAST_ROTATION, "10", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, - { EVAL_FAST_ROTATION, "11", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, - { EVAL_FAST_ROTATION, "12", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, + { EVAL_FAST_ROTATION, "09", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, + { EVAL_FAST_ROTATION, "10", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, + { EVAL_FAST_ROTATION, "11", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, + { EVAL_FAST_ROTATION, "12", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, #if NATIVEINT != 128 - { EVAL_FAST_ROTATION, "13", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, - { EVAL_FAST_ROTATION, "14", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, - { EVAL_FAST_ROTATION, "15", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, - { EVAL_FAST_ROTATION, "16", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, + { EVAL_FAST_ROTATION, "13", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, + { EVAL_FAST_ROTATION, "14", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, + { EVAL_FAST_ROTATION, "15", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, + { EVAL_FAST_ROTATION, "16", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 1}, #endif - { EVAL_FAST_ROTATION, "17", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, - { EVAL_FAST_ROTATION, "18", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, - { EVAL_FAST_ROTATION, "19", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, - { EVAL_FAST_ROTATION, "20", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, + { EVAL_FAST_ROTATION, "17", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, + { EVAL_FAST_ROTATION, "18", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, + { EVAL_FAST_ROTATION, "19", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, + { EVAL_FAST_ROTATION, "20", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, #if NATIVEINT != 128 - { EVAL_FAST_ROTATION, "21", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, - { EVAL_FAST_ROTATION, "22", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, - { EVAL_FAST_ROTATION, "23", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, - { EVAL_FAST_ROTATION, "24", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, + { EVAL_FAST_ROTATION, "21", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, + { EVAL_FAST_ROTATION, "22", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, + { EVAL_FAST_ROTATION, "23", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, + { EVAL_FAST_ROTATION, "24", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 2}, #endif - { EVAL_FAST_ROTATION, "25", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, - { EVAL_FAST_ROTATION, "26", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, - { EVAL_FAST_ROTATION, "27", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, - { EVAL_FAST_ROTATION, "28", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, + { EVAL_FAST_ROTATION, "25", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, + { EVAL_FAST_ROTATION, "26", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, + { EVAL_FAST_ROTATION, "27", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, + { EVAL_FAST_ROTATION, "28", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, #if NATIVEINT != 128 - { EVAL_FAST_ROTATION, "29", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, - { EVAL_FAST_ROTATION, "30", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, - { EVAL_FAST_ROTATION, "31", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, - { EVAL_FAST_ROTATION, "32", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, + { EVAL_FAST_ROTATION, "29", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, + { EVAL_FAST_ROTATION, "30", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, + { EVAL_FAST_ROTATION, "31", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, + { EVAL_FAST_ROTATION, "32", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 4}, #endif - { EVAL_FAST_ROTATION, "33", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { EVAL_FAST_ROTATION, "34", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { EVAL_FAST_ROTATION, "35", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { EVAL_FAST_ROTATION, "36", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { EVAL_FAST_ROTATION, "33", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { EVAL_FAST_ROTATION, "34", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { EVAL_FAST_ROTATION, "35", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { EVAL_FAST_ROTATION, "36", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, #if NATIVEINT != 128 - { EVAL_FAST_ROTATION, "37", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { EVAL_FAST_ROTATION, "38", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { EVAL_FAST_ROTATION, "39", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, - { EVAL_FAST_ROTATION, "40", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { EVAL_FAST_ROTATION, "37", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { EVAL_FAST_ROTATION, "38", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { EVAL_FAST_ROTATION, "39", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, + { EVAL_FAST_ROTATION, "40", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, BATCH}, #endif #if !defined(EMSCRIPTEN) - { EVAL_FAST_ROTATION, "41", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVAL_FAST_ROTATION, "42", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVAL_FAST_ROTATION, "43", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVAL_FAST_ROTATION, "44", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVAL_FAST_ROTATION, "41", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVAL_FAST_ROTATION, "42", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVAL_FAST_ROTATION, "43", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVAL_FAST_ROTATION, "44", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, #if NATIVEINT != 128 - { EVAL_FAST_ROTATION, "45", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVAL_FAST_ROTATION, "46", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVAL_FAST_ROTATION, "47", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVAL_FAST_ROTATION, "48", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVAL_FAST_ROTATION, "45", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVAL_FAST_ROTATION, "46", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVAL_FAST_ROTATION, "47", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVAL_FAST_ROTATION, "48", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Slots - { EVALATINDEX, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVALATINDEX, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVALATINDEX, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVALATINDEX, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVALATINDEX, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVALATINDEX, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVALATINDEX, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVALATINDEX, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, #if NATIVEINT != 128 - { EVALATINDEX, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVALATINDEX, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVALATINDEX, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, - { EVALATINDEX, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVALATINDEX, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVALATINDEX, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVALATINDEX, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, + { EVALATINDEX, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 0}, #endif - { EVALATINDEX, "09", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, - { EVALATINDEX, "10", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, - { EVALATINDEX, "11", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, - { EVALATINDEX, "12", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, + { EVALATINDEX, "09", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, + { EVALATINDEX, "10", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, + { EVALATINDEX, "11", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, + { EVALATINDEX, "12", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, #if NATIVEINT != 128 - { EVALATINDEX, "13", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, - { EVALATINDEX, "14", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, - { EVALATINDEX, "15", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, - { EVALATINDEX, "16", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, + { EVALATINDEX, "13", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, + { EVALATINDEX, "14", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, + { EVALATINDEX, "15", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, + { EVALATINDEX, "16", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 8}, #endif - { EVALATINDEX, "17", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, - { EVALATINDEX, "18", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, - { EVALATINDEX, "19", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, - { EVALATINDEX, "20", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, + { EVALATINDEX, "17", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, + { EVALATINDEX, "18", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, + { EVALATINDEX, "19", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, + { EVALATINDEX, "20", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, #if NATIVEINT != 128 - { EVALATINDEX, "21", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, - { EVALATINDEX, "22", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, - { EVALATINDEX, "23", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, - { EVALATINDEX, "24", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, + { EVALATINDEX, "21", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, + { EVALATINDEX, "22", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, + { EVALATINDEX, "23", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, + { EVALATINDEX, "24", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, 16}, #endif - { EVALATINDEX, "25", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVALATINDEX, "26", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVALATINDEX, "27", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVALATINDEX, "28", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVALATINDEX, "25", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVALATINDEX, "26", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVALATINDEX, "27", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVALATINDEX, "28", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, #if NATIVEINT != 128 - { EVALATINDEX, "29", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVALATINDEX, "30", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVALATINDEX, "31", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, - { EVALATINDEX, "32", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVALATINDEX, "29", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVALATINDEX, "30", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVALATINDEX, "31", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, + { EVALATINDEX, "32", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, RING_DIM_HALF}, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { EVALMERGE, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #if NATIVEINT != 128 - { EVALMERGE, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALMERGE, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALMERGE, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { EVAL_LINEAR_WSUM, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_LINEAR_WSUM, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_LINEAR_WSUM, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_LINEAR_WSUM, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_LINEAR_WSUM, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_LINEAR_WSUM, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_LINEAR_WSUM, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_LINEAR_WSUM, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #if NATIVEINT != 128 - { EVAL_LINEAR_WSUM, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_LINEAR_WSUM, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_LINEAR_WSUM, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_LINEAR_WSUM, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_LINEAR_WSUM, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_LINEAR_WSUM, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_LINEAR_WSUM, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_LINEAR_WSUM, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { RE_ENCRYPTION, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { RE_ENCRYPTION, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, - { RE_ENCRYPTION, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { RE_ENCRYPTION, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, + { RE_ENCRYPTION, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { RE_ENCRYPTION, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, + { RE_ENCRYPTION, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { RE_ENCRYPTION, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, #if NATIVEINT != 128 - { RE_ENCRYPTION, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { RE_ENCRYPTION, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, - { RE_ENCRYPTION, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { RE_ENCRYPTION, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, + { RE_ENCRYPTION, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { RE_ENCRYPTION, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, + { RE_ENCRYPTION, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { RE_ENCRYPTION, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, INDCPA}, }, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { EVAL_POLY, "01", {CKKSRNS_SCHEME, RING_DIM, 5, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_POLY, "02", {CKKSRNS_SCHEME, RING_DIM, 5, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_POLY, "03", {CKKSRNS_SCHEME, RING_DIM, 5, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_POLY, "04", {CKKSRNS_SCHEME, RING_DIM, 5, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_POLY, "01", {CKKSRNS_SCHEME, RING_DIM, 5, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_POLY, "02", {CKKSRNS_SCHEME, RING_DIM, 5, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_POLY, "03", {CKKSRNS_SCHEME, RING_DIM, 5, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_POLY, "04", {CKKSRNS_SCHEME, RING_DIM, 5, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #if NATIVEINT != 128 - { EVAL_POLY, "05", {CKKSRNS_SCHEME, RING_DIM, 5, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_POLY, "06", {CKKSRNS_SCHEME, RING_DIM, 5, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_POLY, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVAL_POLY, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_POLY, "05", {CKKSRNS_SCHEME, RING_DIM, 5, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_POLY, "06", {CKKSRNS_SCHEME, RING_DIM, 5, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_POLY, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVAL_POLY, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { METADATA, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #if NATIVEINT != 128 - { METADATA, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { METADATA, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { METADATA, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #endif // ========================================== // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode - { EVALSQUARE, "01", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALSQUARE, "02", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALSQUARE, "03", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALSQUARE, "04", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALSQUARE, "01", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALSQUARE, "02", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALSQUARE, "03", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALSQUARE, "04", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FIXEDAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #if NATIVEINT != 128 - { EVALSQUARE, "05", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALSQUARE, "06", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALSQUARE, "07", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, - { EVALSQUARE, "08", {CKKSRNS_SCHEME, RING_DIM, 7, SMODSIZE, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALSQUARE, "05", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALSQUARE, "06", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTO, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALSQUARE, "07", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, BV, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { EVALSQUARE, "08", {CKKSRNS_SCHEME, RING_DIM, 7, DFLT, DSIZE, BATCH, DFLT, DFLT, DFLT, HEStd_NotSet, HYBRID, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #endif + // ========================================== + // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize, BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode + { SMALL_SCALING_MOD_SIZE, "01", {CKKSRNS_SCHEME, 32768, 19, 22, DFLT, DFLT, DFLT, DFLT, 23, DFLT, DFLT, FIXEDMANUAL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, + { SMALL_SCALING_MOD_SIZE, "02", {CKKSRNS_SCHEME, 32768, 16, 50, DFLT, DFLT, DFLT, DFLT, 50, HEStd_NotSet, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, }, #endif // ========================================== }; @@ -770,13 +776,14 @@ class UTCKKSRNS : public ::testing::TestWithParam { failmsg + " EvalSub Ct and negative double fails"); approximationErrors.emplace_back(CalculateApproximationError(plaintext1AddScalar->GetCKKSPackedValue(), results->GetCKKSPackedValue())); - - // Testing EvalAdd ciphertext + large double - cResult = cc->EvalAdd(ciphertext1, factor); - cc->Decrypt(kp.secretKey, cResult, &results); - results->SetLength(plaintext1AddLargeScalar->GetLength()); - checkEquality(plaintext1AddLargeScalar->GetCKKSPackedValue(), results->GetCKKSPackedValue(), factor * eps, - failmsg + " EvalAdd Ct and large double fails"); + if (testData.params.multiplicativeDepth > 0) { + // Testing EvalAdd ciphertext + large double + cResult = cc->EvalAdd(ciphertext1, factor); + cc->Decrypt(kp.secretKey, cResult, &results); + results->SetLength(plaintext1AddLargeScalar->GetLength()); + checkEquality(plaintext1AddLargeScalar->GetCKKSPackedValue(), results->GetCKKSPackedValue(), + factor * eps, failmsg + " EvalAdd Ct and large double fails"); + } // Testing EvalNegate cResult = cc->EvalNegate(ciphertext1); @@ -2144,6 +2151,28 @@ class UTCKKSRNS : public ::testing::TestWithParam { std::string name("EMSCRIPTEN_UNKNOWN"); #else std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name())); +#endif + std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl; + // make it fail + EXPECT_TRUE(0 == 1) << failmsg; + } + } + + void UnitTest_Small_ScalingModSize(const TEST_CASE_UTCKKSRNS& testData, + const std::string& failmsg = std::string()) { + try { + CryptoContext cc(UnitTestGenerateContext(testData.params)); + } + catch (std::exception& e) { + std::cerr << "Exception thrown from " << __func__ << "(): " << e.what() << std::endl; + // make it fail + EXPECT_TRUE(0 == 1) << failmsg; + } + catch (...) { +#if defined EMSCRIPTEN + std::string name("EMSCRIPTEN_UNKNOWN"); +#else + std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name())); #endif std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl; // make it fail @@ -2227,6 +2256,10 @@ TEST_P(UTCKKSRNS, CKKSRNS) { break; case EVALSQUARE: UnitTest_EvalSquare(test, test.buildTestName()); + break; + case SMALL_SCALING_MOD_SIZE: + UnitTest_Small_ScalingModSize(test, test.buildTestName()); + break; default: break; } diff --git a/src/pke/unittest/utckksrns/UnitTestCKKSrnsAutomorphism.cpp b/src/pke/unittest/utckksrns/UnitTestCKKSrnsAutomorphism.cpp index 421610b48..758f2a0c9 100644 --- a/src/pke/unittest/utckksrns/UnitTestCKKSrnsAutomorphism.cpp +++ b/src/pke/unittest/utckksrns/UnitTestCKKSrnsAutomorphism.cpp @@ -48,6 +48,8 @@ using namespace lbcrypto; enum TEST_CASE_TYPE { EVAL_AT_INDX_PACKED_ARRAY = 0, EVAL_SUM_PACKED_ARRAY, + EVAL_SUM_ROWS, + EVAL_SUM_COLS, }; static std::ostream& operator<<(std::ostream& os, const TEST_CASE_TYPE& type) { @@ -59,6 +61,12 @@ static std::ostream& operator<<(std::ostream& os, const TEST_CASE_TYPE& type) { case EVAL_SUM_PACKED_ARRAY: typeName = "EVAL_SUM_PACKED_ARRAY"; break; + case EVAL_SUM_ROWS: + typeName = "EVAL_SUM_ROWS"; + break; + case EVAL_SUM_COLS: + typeName = "EVAL_SUM_COLS"; + break; default: typeName = "UNKNOWN_UTCKKSRNS_AUTOMORPHISM"; break; @@ -181,6 +189,12 @@ static std::vector testCasesUTCKKSRNS_AUTOMORP { EVAL_SUM_PACKED_ARRAY, "34", {CKKSRNS_SCHEME, RING_DIM, MULT_DEPTH, SMODSIZE, DFLT, BATCH, DFLT, DFLT, DFLT, SEC_LVL, DFLT, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, INVALID_BATCH_SIZE }, { EVAL_SUM_PACKED_ARRAY, "35", {CKKSRNS_SCHEME, RING_DIM, MULT_DEPTH, SMODSIZE, DFLT, BATCH, DFLT, DFLT, DFLT, SEC_LVL, DFLT, FLEXIBLEAUTOEXT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, NO_KEY_GEN_CALL }, #endif + // ========================================== + // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize,BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Error, indexList + { EVAL_SUM_ROWS, "01", {CKKSRNS_SCHEME, RING_DIM, DFLT, DFLT, DFLT, RING_DIM/2, DFLT, DFLT, DFLT, SEC_LVL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, SUCCESS }, + // ========================================== + // TestType, Descr, Scheme, RDim, MultDepth, SModSize, DSize,BatchSz, SecKeyDist, MaxRelinSkDeg, FModSize, SecLvl, KSTech, ScalTech, LDigits, PtMod, StdDev, EvalAddCt, KSCt, MultTech, EncTech, PREMode, Error, indexList + { EVAL_SUM_COLS, "01", {CKKSRNS_SCHEME, RING_DIM, DFLT, DFLT, DFLT, RING_DIM/2, DFLT, DFLT, DFLT, SEC_LVL, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT, DFLT}, SUCCESS }, }; // clang-format on //=========================================================================================================== @@ -353,6 +367,104 @@ class UTCKKSRNS_AUTOMORPHISM : public ::testing::TestWithParamname())); +#endif + std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl; + // make it fail + EXPECT_TRUE(0 == 1) << failmsg; + } + } + + void UnitTest_EvalSumRows(const TEST_CASE_UTCKKSRNS_AUTOMORPHISM& testData, + const std::string& failmsg = std::string()) { + try { + CryptoContext cc(UnitTestGenerateContext(testData.params)); + + KeyPair kp = cc->KeyGen(); + + std::vector mat{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0}; + uint32_t rowSize = 4; + uint32_t batchSize = cc->GetEncodingParams()->GetBatchSize(); + + const std::vector> outputSumRows{6.0, 8.0, 10.0, 12.0, 6.0, 8.0, 10.0, 12.0}; + + // Encoding as plaintexts + Plaintext ptxtMat = cc->MakeCKKSPackedPlaintext(mat); + + // Encrypt the encoded vectors + auto ctMat = cc->Encrypt(kp.publicKey, ptxtMat); + + auto evalSumRowKeys = cc->EvalSumRowsKeyGen(kp.secretKey, nullptr, rowSize); + + // Evaluation + auto ctRowsSum = cc->EvalSumRows(ctMat, rowSize, *evalSumRowKeys); + + // Decrypt + Plaintext result; + cc->Decrypt(kp.secretKey, ctRowsSum, &result); + result->SetLength(batchSize); + // std::cout << "sum Rows: " << result; + checkEquality(result->GetCKKSPackedValue(), outputSumRows, eps, + failmsg + " EvalSumRowsKeyGen()/EvalSumRows fails - result is incorrect"); + } + catch (std::exception& e) { + std::cerr << "Exception thrown from " << __func__ << "(): " << e.what() << std::endl; + // make it fail + EXPECT_TRUE(0 == 1) << failmsg; + } + catch (...) { +#if defined EMSCRIPTEN + std::string name("EMSCRIPTEN_UNKNOWN"); +#else + std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name())); +#endif + std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl; + // make it fail + EXPECT_TRUE(0 == 1) << failmsg; + } + } + + void UnitTest_EvalSumCols(const TEST_CASE_UTCKKSRNS_AUTOMORPHISM& testData, + const std::string& failmsg = std::string()) { + try { + CryptoContext cc(UnitTestGenerateContext(testData.params)); + + KeyPair kp = cc->KeyGen(); + + std::vector mat{8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; + uint32_t colSize = 4; + uint32_t batchSize = cc->GetEncodingParams()->GetBatchSize(); + + const std::vector> outputSumCols{14.0, 14.0, 14.0, 14.0, 22.0, 22.0, 22.0, 22.0}; + + // Encoding as plaintexts + Plaintext ptxtMat = cc->MakeCKKSPackedPlaintext(mat); + + // Encrypt the encoded vectors + auto ctMat = cc->Encrypt(kp.publicKey, ptxtMat); + + auto evalSumColKeys = cc->EvalSumColsKeyGen(kp.secretKey); + + // Evaluation + auto ctColsSum = cc->EvalSumCols(ctMat, colSize, *evalSumColKeys); + + // Decrypt + Plaintext result; + cc->Decrypt(kp.secretKey, ctColsSum, &result); + result->SetLength(batchSize); + // std::cout << "sum Cols: " << result; + checkEquality(result->GetCKKSPackedValue(), outputSumCols, eps, + failmsg + " EvalSumColsKeyGen()/EvalSumCols fails - result is incorrect"); + } + catch (std::exception& e) { + std::cerr << "Exception thrown from " << __func__ << "(): " << e.what() << std::endl; + // make it fail + EXPECT_TRUE(0 == 1) << failmsg; + } + catch (...) { +#if defined EMSCRIPTEN + std::string name("EMSCRIPTEN_UNKNOWN"); +#else + std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name())); #endif std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl; // make it fail @@ -372,6 +484,12 @@ TEST_P(UTCKKSRNS_AUTOMORPHISM, Automorphism) { case EVAL_SUM_PACKED_ARRAY: UnitTest_EvalSumPackedArray(test, test.buildTestName()); break; + case EVAL_SUM_ROWS: + UnitTest_EvalSumRows(test, test.buildTestName()); + break; + case EVAL_SUM_COLS: + UnitTest_EvalSumCols(test, test.buildTestName()); + break; default: break; } diff --git a/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv b/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv index 738d60ded..4c1e56efb 100644 --- a/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv +++ b/src/pke/unittest/utckksrns/UnitTestInteractiveBootstrap.csv @@ -1,4 +1,4 @@ -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,multiHopModSize,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,numParties +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,numParties INTERACTIVE_MP_BOOT,1,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 INTERACTIVE_MP_BOOT,2,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 INTERACTIVE_MP_BOOT,3,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK,3 @@ -7,7 +7,7 @@ INTERACTIVE_MP_BOOT,5,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,4,,7,,HEStd_NotSet,64,, INTERACTIVE_MP_BOOT,6,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 INTERACTIVE_MP_BOOT,7,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 INTERACTIVE_MP_BOOT,8,CKKSRNS_SCHEME,,,,,,,FIXEDMANUAL,,4,,7,,HEStd_NotSet,64,,,,,,,,,,,,,,,COMPACT,3 -#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,multiHopModSize,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,numParties +#### TestType,Descr,scheme,ptModulus,digitSize,standardDeviation,secretKeyDist,maxRelinSkDeg,ksTech,scalTech,firstModSize,batchSize,numLargeDigits,multiplicativeDepth,scalingModSize,securityLevel,ringDim,evalAddCount,keySwitchCount,encryptionTechnique,multiplicationTechnique,PRENumHops,PREMode,multipartyMode,executionMode,decryptionNoiseMode,noiseEstimate,desiredPrecision,statisticalSecurity,numAdversarialQueries,thresholdNumOfParties,interactiveBootCompressionLevel,numParties INTERACTIVE_MP_BOOT_CHEBYSHEV,1,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, INTERACTIVE_MP_BOOT_CHEBYSHEV,2,CKKSRNS_SCHEME,,,,,,,FLEXIBLEAUTOEXT,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, INTERACTIVE_MP_BOOT_CHEBYSHEV,3,CKKSRNS_SCHEME,,,,,,,FIXEDAUTO,,16,,10,,HEStd_NotSet,64,,,,,,,,,,,,,,,SLACK, diff --git a/src/pke/unittest/utils/UnitTestCryptoContext.cpp b/src/pke/unittest/utils/UnitTestCryptoContext.cpp index fe38d5ec2..cb7debbc2 100644 --- a/src/pke/unittest/utils/UnitTestCryptoContext.cpp +++ b/src/pke/unittest/utils/UnitTestCryptoContext.cpp @@ -45,8 +45,10 @@ static void setCryptoContextParametersFromUnitTestCCParams(const UnitTestCCParam if (!isDefaultValue(params.multiplicativeDepth)) { parameters.SetMultiplicativeDepth(static_cast(std::round(params.multiplicativeDepth))); } - if (!isDefaultValue(params.scalingModSize)) { - parameters.SetScalingModSize(static_cast(std::round(params.scalingModSize))); + if constexpr (std::is_same_v> == false) { + if (!isDefaultValue(params.scalingModSize)) { + parameters.SetScalingModSize(static_cast(std::round(params.scalingModSize))); + } } if (!isDefaultValue(params.digitSize)) { parameters.SetDigitSize(static_cast(std::round(params.digitSize))); @@ -60,8 +62,10 @@ static void setCryptoContextParametersFromUnitTestCCParams(const UnitTestCCParam if (!isDefaultValue(params.maxRelinSkDeg)) { parameters.SetMaxRelinSkDeg(static_cast(std::round(params.maxRelinSkDeg))); } - if (!isDefaultValue(params.firstModSize)) { - parameters.SetFirstModSize(static_cast(std::round(params.firstModSize))); + if constexpr (std::is_same_v> == false) { + if (!isDefaultValue(params.firstModSize)) { + parameters.SetFirstModSize(static_cast(std::round(params.firstModSize))); + } } if (!isDefaultValue(params.securityLevel)) { parameters.SetSecurityLevel(static_cast(std::round(params.securityLevel))); @@ -69,45 +73,65 @@ static void setCryptoContextParametersFromUnitTestCCParams(const UnitTestCCParam if (!isDefaultValue(params.ksTech)) { parameters.SetKeySwitchTechnique(static_cast(std::round(params.ksTech))); } - if (!isDefaultValue(params.scalTech)) { - parameters.SetScalingTechnique(static_cast(std::round(params.scalTech))); + if constexpr (std::is_same_v> == false) { + if (!isDefaultValue(params.scalTech)) { + parameters.SetScalingTechnique(static_cast(std::round(params.scalTech))); + } } if (!isDefaultValue(params.numLargeDigits)) { parameters.SetNumLargeDigits(static_cast(std::round(params.numLargeDigits))); } - if (!isDefaultValue(params.plaintextModulus)) { - parameters.SetPlaintextModulus(static_cast(std::round(params.plaintextModulus))); + if constexpr (std::is_same_v> == false) { + if (!isDefaultValue(params.plaintextModulus)) { + parameters.SetPlaintextModulus(static_cast(std::round(params.plaintextModulus))); + } } if (!isDefaultValue(params.standardDeviation)) { parameters.SetStandardDeviation(params.standardDeviation); } - if (!isDefaultValue(params.multiplicationTechnique)) { - parameters.SetMultiplicationTechnique( - static_cast(std::round(params.multiplicationTechnique))); + if constexpr (std::is_same_v> == true) { + if (!isDefaultValue(params.multiplicationTechnique)) { + parameters.SetMultiplicationTechnique( + static_cast(std::round(params.multiplicationTechnique))); + } } - if (!isDefaultValue(params.encryptionTechnique)) { - parameters.SetEncryptionTechnique(static_cast(std::round(params.encryptionTechnique))); + if constexpr (std::is_same_v> == true) { + if (!isDefaultValue(params.encryptionTechnique)) { + parameters.SetEncryptionTechnique(static_cast(std::round(params.encryptionTechnique))); + } } - if (!isDefaultValue(params.evalAddCount)) { - parameters.SetEvalAddCount(static_cast(std::round(params.evalAddCount))); + if constexpr (std::is_same_v> == false) { + if (!isDefaultValue(params.evalAddCount)) { + parameters.SetEvalAddCount(static_cast(std::round(params.evalAddCount))); + } } - if (!isDefaultValue(params.keySwitchCount)) { - parameters.SetKeySwitchCount(static_cast(std::round(params.keySwitchCount))); + if constexpr (std::is_same_v> == false) { + if (!isDefaultValue(params.keySwitchCount)) { + parameters.SetKeySwitchCount(static_cast(std::round(params.keySwitchCount))); + } } if (!isDefaultValue(params.PREMode)) { parameters.SetPREMode(static_cast(std::round(params.PREMode))); } - if (!isDefaultValue(params.multipartyMode)) { - parameters.SetMultipartyMode(static_cast(std::round(params.multipartyMode))); - } - if (!isDefaultValue(params.decryptionNoiseMode)) { - parameters.SetDecryptionNoiseMode(static_cast(std::round(params.decryptionNoiseMode))); - } - if (!isDefaultValue(params.executionMode)) { - parameters.SetExecutionMode(static_cast(std::round(params.executionMode))); - } - if (!isDefaultValue(params.noiseEstimate)) { - parameters.SetNoiseEstimate(params.noiseEstimate); + if constexpr (std::is_same_v> == false) { + if (!isDefaultValue(params.multipartyMode)) { + parameters.SetMultipartyMode(static_cast(std::round(params.multipartyMode))); + } + } + if constexpr (std::is_same_v> == true) { + if (!isDefaultValue(params.decryptionNoiseMode)) { + parameters.SetDecryptionNoiseMode(static_cast(std::round(params.decryptionNoiseMode))); + } + } + if constexpr (std::is_same_v> == true) { + if (!isDefaultValue(params.executionMode)) { + parameters.SetExecutionMode(static_cast(std::round(params.executionMode))); + } + } + if constexpr (std::is_same_v> == true) { + if (!isDefaultValue(params.noiseEstimate)) { + parameters.SetNoiseEstimate(params.noiseEstimate); + } } } //===========================================================================================================