Skip to content

Commit

Permalink
778 fix lmkcdey parameter sets (#799)
Browse files Browse the repository at this point in the history
* increase mod of STD128Q_LMKCDEY within binfhecontext.cpp

* update BINFHE_PARAMSETs

* update LPF BINFHE_PARAMSETs

* add approximate probability of failure to binfhe-constants

* created binfhe-paramsets benchmark

* added LPF sets to binfhe-constants-impl.cpp

* added comments for BinFHEContext::GenerateLUTviaFunctionv()
  • Loading branch information
pascoec committed Jun 13, 2024
1 parent 4eed808 commit a68c33c
Show file tree
Hide file tree
Showing 7 changed files with 336 additions and 233 deletions.
136 changes: 136 additions & 0 deletions benchmark/src/binfhe-paramsets.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//==================================================================================
// 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 <random>

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<LWEPlaintext>(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<LWEPlaintext>(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<LWEPlaintext>(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<LWEPlaintext>(0, 1), std::default_random_engine());
for (auto _ : state)
auto ct = cc.EvalBinGate(
g, std::vector<LWECiphertext>{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<LWEPlaintext>(0, 1), std::default_random_engine());
for (auto _ : state)
auto ct = cc.EvalBinGate(
g, std::vector<LWECiphertext>{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_BINGATE2, STD128Q_2_LMKCDEY_OR, STD128Q_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond);
#if NATIVEINT >= 64
BENCHMARK_CAPTURE(FHEW_BINGATE2, STD192_2_LMKCDEY_OR, STD192_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(FHEW_BINGATE2, STD192Q_2_LMKCDEY_OR, STD192Q_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(FHEW_BINGATE2, STD256_2_LMKCDEY_OR, STD256_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond);
#endif
BENCHMARK_CAPTURE(FHEW_BINGATE2, STD256Q_2_LMKCDEY_OR, STD256Q_LMKCDEY, LMKCDEY, OR)->Unit(benchmark::kMillisecond);
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();
2 changes: 1 addition & 1 deletion src/binfhe/examples/boolean-multi-input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
89 changes: 36 additions & 53 deletions src/binfhe/include/binfhe-constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,61 +45,44 @@ 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^(-50)
STD128Q_LMKCDEY, // STD128Q optimized for LMKCDEY (using Gaussian secrets) : 2^(-50)
STD192_LMKCDEY, // STD192 optimized for LMKCDEY (using Gaussian secrets) : 2^(-60)
STD192Q_LMKCDEY, // STD192Q optimized for LMKCDEY (using Gaussian secrets) : 2^(-70)
STD256_LMKCDEY, // STD256 optimized for LMKCDEY (using Gaussian secrets) : 2^(-50)
STD256Q_LMKCDEY, // STD256Q optimized for LMKCDEY (using Gaussian secrets) : 2^(-60)
LPF_STD128, // STD128 configured with lower probability of failures : 2^(-120)
LPF_STD128Q, // STD128Q configured with lower probability of failures : 2^(-75)
LPF_STD128_LMKCDEY, // LPF_STD128 optimized for LMKCDEY (using Gaussian secrets) : 2^(-100)
LPF_STD128Q_LMKCDEY, // LPF_STD128Q optimized for LMKCDEY (using Gaussian secrets) : 2^(-90)
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);

/**
Expand Down
2 changes: 1 addition & 1 deletion src/binfhe/include/binfhecontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
Expand Down
2 changes: 1 addition & 1 deletion src/binfhe/include/rgsw-cryptoparameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint32_t>(std::ceil(logQ / log(static_cast<double>(m_baseG))));
Expand Down
Loading

0 comments on commit a68c33c

Please sign in to comment.