Skip to content

[Feature/experimental] add BFV stack under heu/experimental#199

Open
chasglim wants to merge 3 commits intosecretflow:mainfrom
chasglim:feat/experimental-bfv-pr-prep
Open

[Feature/experimental] add BFV stack under heu/experimental#199
chasglim wants to merge 3 commits intosecretflow:mainfrom
chasglim:feat/experimental-bfv-pr-prep

Conversation

@chasglim
Copy link
Copy Markdown

Summary

This PR adds an experimental BFV stack under heu/experimental/bfv.

The contribution includes:

  • BFV math / RNS / NTT / polynomial backends
  • BFV crypto objects and homomorphic operators
  • planning utilities such as parameter advisor, keyset planner, and deployment planner
  • unit tests, runnable demos, and benchmark targets
  • top-level README / changelog references that keep the feature explicitly scoped as experimental

Scope

This PR intentionally keeps the BFV work under heu/experimental.
It does not yet integrate BFV into HEU SPI, PyLib, or HEU stable public APIs.

Validation

bazel test //heu/experimental/bfv/...

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 21, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@chasglim chasglim marked this pull request as ready for review April 21, 2026 08:52
@chasglim
Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@chasglim chasglim force-pushed the feat/experimental-bfv-pr-prep branch from 439d7e8 to a908620 Compare April 21, 2026 09:54
@tongke6 tongke6 requested a review from Copilot April 21, 2026 10:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds an experimental BFV homomorphic encryption stack under heu/experimental/bfv with core crypto objects, serialization, planning utilities, tests, demos, and benchmarks, while keeping it explicitly outside stable HEU APIs.

Changes:

  • Introduces BFV crypto primitives and homomorphic operators (keys, ciphertext/plaintext, operators, planning utilities).
  • Adds msgpack-based serialization helpers plus bulk (batch) serialization APIs.
  • Adds extensive gtest coverage and multiple benchmark entrypoints; updates top-level READMEs and changelog to scope as experimental.

Reviewed changes

Copilot reviewed 68 out of 195 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
heu/experimental/bfv/crypto/test/test_keyset_planner.cc Adds unit tests for keyset planning and key materialization.
heu/experimental/bfv/crypto/test/test_key_switching_key.cc Adds tests for key switching key creation, switching correctness, and serialization.
heu/experimental/bfv/crypto/test/test_galois_key.cc Adds tests for Galois key creation/apply and serialization.
heu/experimental/bfv/crypto/test/test_encoding.cc Adds tests for Encoding factories, semantics, and string conversion.
heu/experimental/bfv/crypto/test/test_bulk_serialization.cc Adds tests for batch serialization round-trips and mismatch/corruption handling.
heu/experimental/bfv/crypto/test/test_bfv_parameters.cc Adds tests for parameter builder/defaults, validation, contexts, and serialization.
heu/experimental/bfv/crypto/serialization/serialization_exceptions.h Introduces structured serialization exception types.
heu/experimental/bfv/crypto/serialization/serialization_exceptions.cc Placeholder TU for serialization exceptions library linkage.
heu/experimental/bfv/crypto/serialization/msgpack_adaptors.h Defines msgpack DTOs for BFV objects + generic msgpack serializer helpers.
heu/experimental/bfv/crypto/secret_key_impl.h Adds templated SecretKey RNG entrypoints and encrypt forwarding.
heu/experimental/bfv/crypto/secret_key.h Defines SecretKey API including encryption/decryption and serialization.
heu/experimental/bfv/crypto/rgsw_ciphertext.h Adds RGSW ciphertext type and external-product operator declarations.
heu/experimental/bfv/crypto/rgsw_ciphertext.cc Implements RGSW ciphertext behavior and serialization.
heu/experimental/bfv/crypto/relinearization_key_impl.h Adds templated RNG forwarding for relinearization key creation.
heu/experimental/bfv/crypto/relinearization_key.h Defines relinearization key API and serialization hooks.
heu/experimental/bfv/crypto/public_key_impl.h Adds templated RNG forwarding/bridging for public key operations.
heu/experimental/bfv/crypto/public_key.h Defines PublicKey API and serialization hooks.
heu/experimental/bfv/crypto/public_key.cc Implements public key generation/encryption and serialization.
heu/experimental/bfv/crypto/plaintext.h Defines Plaintext API with encoding/decode, metadata, and serialization.
heu/experimental/bfv/crypto/operators.h Declares BFV operator overloads and cache-clearing hook.
heu/experimental/bfv/crypto/operators.cc Implements operators including cached Multiplicator construction.
heu/experimental/bfv/crypto/operations.h Adds an (intended) optimized dot-product API (currently namespace/mismatch issues).
heu/experimental/bfv/crypto/operations_impl.h Implements optimized dot-product (currently namespace/mismatch issues).
heu/experimental/bfv/crypto/multiplicator.h Declares multiplicator strategy abstraction for ciphertext multiplication.
heu/experimental/bfv/crypto/keyset_planner.h Declares keyset request/profile/plan types and planner APIs.
heu/experimental/bfv/crypto/keyset_planner.cc Implements keyset planning logic and key building based on plans.
heu/experimental/bfv/crypto/key_switching_key_impl.h Adds templated RNG forwarding/bridging for key switching key creation.
heu/experimental/bfv/crypto/key_switching_key.h Defines KeySwitchingKey API and serialization hooks.
heu/experimental/bfv/crypto/galois_key_impl.h Adds templated RNG forwarding/bridging for Galois key creation.
heu/experimental/bfv/crypto/galois_key.h Defines GaloisKey API and serialization hooks.
heu/experimental/bfv/crypto/exceptions.h Defines BFV exception hierarchy.
heu/experimental/bfv/crypto/exceptions.cc Placeholder TU for exception linkage consistency.
heu/experimental/bfv/crypto/evaluation_key_impl.h Adds templated RNG forwarding for evaluation key builder.
heu/experimental/bfv/crypto/evaluation_key.h Defines EvaluationKey and EvaluationKeyBuilder APIs plus serialization.
heu/experimental/bfv/crypto/encoding.h Defines Encoding type used by plaintext/ciphertext APIs.
heu/experimental/bfv/crypto/encoding.cc Implements Encoding semantics and formatting.
heu/experimental/bfv/crypto/dot_product.h Adds dot-product API in crypto::bfv namespace.
heu/experimental/bfv/crypto/dot_product_impl.h Implements dot product by repeated ct * pt accumulations.
heu/experimental/bfv/crypto/ciphertext.h Defines Ciphertext API and serialization hooks used by operators/keys.
heu/experimental/bfv/crypto/bulk_serialization.h Declares batch-oriented serializer APIs for BFV object collections.
heu/experimental/bfv/crypto/bfv_parameters.h Defines BFV parameters/builder plus serialization and context accessors.
heu/experimental/bfv/benchmark/zq_benchmark.cc Adds zq modulus microbenchmarks.
heu/experimental/bfv/benchmark/rq_benchmark.cc Adds rq polynomial operation microbenchmarks.
heu/experimental/bfv/benchmark/rns_benchmark.cc Adds RNS transfer engine microbenchmarks.
heu/experimental/bfv/benchmark/ntt_benchmark.cc Adds NTT operator microbenchmarks.
heu/experimental/bfv/benchmark/bench_ntt.cc Adds a standalone NTT benchmark target.
heu/experimental/bfv/benchmark/bench_mul.cc Adds a standalone multiplication benchmark target (uses operator cache clear).
heu/experimental/bfv/benchmark/bench_dec.cc Adds a standalone decryption benchmark target.
heu/experimental/bfv/benchmark/bench_add.cc Adds a standalone addition benchmark target.
README_cn.md Documents experimental BFV stack location and scoping (Chinese).
README.md Documents experimental BFV stack location and scoping (English).
CHANGELOGS.md Adds an unreleased entry announcing the experimental BFV stack.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +9 to +27
namespace bfv::crypto::bfv {

/**
* @brief Compute the dot product between an iterator of Ciphertext and an
* iterator of Plaintext.
*
* This function computes the dot product between ciphertexts and plaintexts
* efficiently, using optimized accumulation when possible.
*
* @tparam CtIterator Iterator type for ciphertexts
* @tparam PtIterator Iterator type for plaintexts
* @param ct_begin Begin iterator for ciphertexts
* @param ct_end End iterator for ciphertexts
* @param pt_begin Begin iterator for plaintexts
* @param pt_end End iterator for plaintexts
* @return Ciphertext The result of the dot product
* @throws BfvException if iterators are empty, parameters don't match, or
* ciphertexts have different sizes
*/
Comment on lines +88 to +90
// Calculate how many bits are available for accumulation
uint32_t leading_zeros = __builtin_clzll(qi);
max_acc.push_back(1ULL << (2 * leading_zeros));
Comment on lines +97 to +102
std::vector<::bfv::math::rq::Polynomial> result_polys;
result_polys.reserve(ct_first.size());

for (size_t i = 0; i < ct_first.size(); ++i) {
std::vector<const ::bfv::math::rq::Polynomial *> ct_polys;
std::vector<const ::bfv::math::rq::Polynomial *> pt_polys;
}

// Use the polynomial dot product from math library
auto result_poly = ::bfv::math::rq::dot_product(ct_polys, pt_polys);
Comment on lines +149 to +150
std::vector<::bfv::math::rq::Polynomial> result_polys;
result_polys.reserve(ct_size);
Comment on lines +232 to +255
static std::mutex cache_mutex;
static std::unordered_map<size_t, std::unique_ptr<Multiplicator>> *cache_ptr =
nullptr;

// Cached multiplicator to avoid repeated construction overhead
static Multiplicator *get_cached_multiplicator(
const std::shared_ptr<BfvParameters> &params, size_t level) {
const size_t key = (reinterpret_cast<size_t>(params.get()) ^
(level * 0x9e3779b97f4a7c15ULL));
std::lock_guard<std::mutex> lock(cache_mutex);
if (!cache_ptr) {
cache_ptr =
new std::unordered_map<size_t, std::unique_ptr<Multiplicator>>();
}

auto it = cache_ptr->find(key);
if (it != cache_ptr->end()) {
return it->second.get();
}
auto mult = create_basic_multiplicator(params, level);
auto *raw_ptr = mult.get();
cache_ptr->emplace(key, std::move(mult));
return raw_ptr;
}
Comment on lines +362 to +364
if (cache_ptr) {
cache_ptr->clear();
}
if (!pImpl && !other.pImpl) return true;
if (!pImpl || !other.pImpl) return false;

return pImpl->par == other.pImpl->par && pImpl->c == other.pImpl->c;
Comment on lines +33 to +37
/**
* @brief Get the raw error message without prefix
* @return The original error message
*/
const std::string &get_message() const noexcept { return message_; }
Comment on lines +64 to +65
// Even exponents should fail
EXPECT_THROW(GaloisKey::create(sk, i, 0, 0, rng_), std::exception);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants