Compare commits

..

22 Commits

Author SHA1 Message Date
Thomas Montaigu
225df2c2c5 chore(hlapi): add param_prod to tests 2026-01-23 14:37:56 +01:00
Thomas Montaigu
5330bce563 chore(ci): add dedicatd param-prod run 2026-01-23 14:37:56 +01:00
Thomas Montaigu
7077f71078 chore(hlapi): set ks32 params as default
Notable changes:

- PublicKey::parameters, and CompressedPublicKey::parameters now returns
  ShortintParameterSet and not ClassicPBSParameters, to fix compatibility with KS32
- CompactCiphertextListExpansionKind::NoCasting changed to store an
  AtomicPatternKind, to allow correct expansion of compact list when
  using KS32 params
2026-01-23 14:37:56 +01:00
Thomas Montaigu
18b834d23d chore(integer): add ks32 to test params 2026-01-23 14:01:28 +01:00
Arthur Meyre
6fc6bbb7f2 chore(shortint): add prod params to tests in shortint
- special case the filter to manage prod parameters with a single flag
2026-01-23 14:01:28 +01:00
Arthur Meyre
96ecad06e6 chore: remove integer test filter which is not relevant anymore 2026-01-23 13:04:25 +01:00
Pedro Alves
c5c16782ff fix(gpu): fix an inconsistency between CudaCompactCiphertextListExpander::len() and the CPU equivalent 2026-01-23 09:20:35 +01:00
Agnes Leroy
bb571712bf fix(gpu): fix potential overflow in create_on_same_gpus 2026-01-23 09:10:36 +01:00
Pedro Alves
222a7e93c4 fix(gpu): change a type to avoid possible issues when compression is executed for a large batch of LWEs 2026-01-22 10:51:35 +01:00
Arthur Meyre
8c96762f79 refactor!: rename to_approximate_recomposition_summand
- this function was named at a time where the decomposition algorithms had
a completely different look for the non native case, when you look at what
the code is doing it is merely returning the value under the correct
modulus, there is nothing approximate about it
- the DecomposerNonNative has a debug assert checking that the modulus has
strictly more bits than are being decomposed i.e.
ceil(log2(modulus)) > base_log * level_count
- a single decomposed value can have at most base_log bits, which will
always fit in the modulus given the above constraints, so there was no
correctness concern
- the original decomposer does not have that concern, it uses a native
modulus (and now power of two moduli) which naturally matches the contained
values (2's complement representation of CPUs is just mod 2^{reg_size})
2026-01-20 18:04:21 +01:00
Agnes Leroy
d23e879a87 chore(gpu): oprf-gpu on any integer in HL API 2026-01-20 17:46:13 +01:00
dependabot[bot]
ae856dcce2 chore(deps): bump JS-DevTools/npm-publish from 4.1.1 to 4.1.3
Bumps [JS-DevTools/npm-publish](https://github.com/js-devtools/npm-publish) from 4.1.1 to 4.1.3.
- [Release notes](https://github.com/js-devtools/npm-publish/releases)
- [Changelog](https://github.com/JS-DevTools/npm-publish/blob/main/CHANGELOG.md)
- [Commits](7f8fe47b3b...d2fef917d9)

---
updated-dependencies:
- dependency-name: JS-DevTools/npm-publish
  dependency-version: 4.1.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-20 15:33:14 +01:00
Arthur Meyre
4c786562ba feat: add missing raw parts APIs for shortint (Compressed)DecompressionKey 2026-01-20 14:17:30 +01:00
Agnes Leroy
9d0a772089 chore(gpu): filter out uniformity tests from compupte sanitizer and valgrind 2026-01-20 14:10:36 +01:00
David Testé
cfd8672b0f chore(ci): fix clippy findings with the latest toolchain 2026-01-16 18:06:37 +01:00
David Testé
3c2c40b058 chore(ci): update toolchain to nightly-2026-01-14 2026-01-16 18:06:37 +01:00
David Testé
bb7e94423b chore(ci): fix typos in documentation 2026-01-16 18:06:37 +01:00
David Testé
e90944d213 chore(ci): update typos checker version to 1.42.0 2026-01-16 18:06:37 +01:00
David Testé
e55c339c46 chore(ci): fix findings from zizmor about archived repositories 2026-01-16 18:06:37 +01:00
David Testé
c1f82f633a chore(ci): update zizmor version to 1.20.0 2026-01-16 18:06:37 +01:00
Arthur Meyre
61550c6405 chore: bump TFHE-rs to 1.6.0 2026-01-16 14:34:40 +01:00
Arthur Meyre
f93b872551 chore: disable the Ubuntu auto upgrader to avoid fails in CI for GPU 2026-01-16 11:07:46 +01:00
225 changed files with 9111 additions and 2634 deletions

View File

@@ -23,6 +23,10 @@ runs:
echo "${CMAKE_SCRIPT_SHA} cmake-${CMAKE_VERSION}-linux-x86_64.sh" > checksum
sha256sum -c checksum
sudo bash cmake-"${CMAKE_VERSION}"-linux-x86_64.sh --skip-license --prefix=/usr/ --exclude-subdir
# Disable unattended-upgrades to avoid lock issues
sudo systemctl disable --now unattended-upgrades
sudo apt-get clean
sudo rm -rf /var/lib/apt/lists/*
sudo apt update

View File

@@ -0,0 +1,213 @@
# Run a small subset of tests to ensure quick feedback.
name: aws_tfhe_param_prod_tests
env:
CARGO_TERM_COLOR: always
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
RUSTFLAGS: "-C target-cpu=native"
RUST_BACKTRACE: "full"
RUST_MIN_STACK: "8388608"
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACKIFY_MARKDOWN: true
IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}
PULL_REQUEST_MD_LINK: ""
CHECKOUT_TOKEN: ${{ secrets.REPO_CHECKOUT_TOKEN || secrets.GITHUB_TOKEN }}
# Secrets will be available only to zama-ai organization members
SECRETS_AVAILABLE: ${{ secrets.JOB_SECRET != '' }}
EXTERNAL_CONTRIBUTION_RUNNER: "large_ubuntu_64-22.04"
on:
# Allows you to run this workflow manually from the Actions tab as an alternative.
workflow_dispatch:
pull_request:
types: [ labeled ]
permissions:
contents: read
# zizmor: ignore[concurrency-limits] concurrency is managed after instance setup to ensure safe provisioning
jobs:
should-run:
name: aws_tfhe_param_prod_tests/should-run
if: (github.event_name == 'pull_request' && contains(github.event.label.name, 'approved')) || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
pull-requests: read # Needed to check for file change
outputs:
csprng_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.csprng_any_changed }}
zk_pok_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.zk_pok_any_changed }}
versionable_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.versionable_any_changed }}
shortint_test: ${{ env.IS_PULL_REQUEST == 'false' ||
steps.changed-files.outputs.shortint_any_changed ||
steps.changed-files.outputs.dependencies_any_changed }}
integer_test: ${{ env.IS_PULL_REQUEST == 'false' ||
steps.changed-files.outputs.integer_any_changed ||
steps.changed-files.outputs.dependencies_any_changed }}
high_level_api_test: ${{ env.IS_PULL_REQUEST == 'false' ||
steps.changed-files.outputs.high_level_api_any_changed ||
steps.changed-files.outputs.dependencies_any_changed }}
any_file_changed: ${{ env.IS_PULL_REQUEST == 'false' || steps.aggregated-changes.outputs.any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3
with:
fetch-depth: 0
persist-credentials: 'false'
token: ${{ env.CHECKOUT_TOKEN }}
- name: Check for file changes
id: changed-files
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0
with:
files_yaml: |
dependencies:
- tfhe/Cargo.toml
- tfhe-csprng/**
- tfhe-fft/**
- tfhe-zk-pok/**
- utils/tfhe-versionable/**
- utils/tfhe-versionable-derive/**
versionable:
- utils/tfhe-versionable/**
- utils/tfhe-versionable-derive/**
shortint:
- tfhe/src/core_crypto/**
- tfhe/src/shortint/**
integer:
- tfhe/src/core_crypto/**
- tfhe/src/shortint/**
- tfhe/src/integer/**
high_level_api:
- tfhe/src/**
- '!tfhe/src/c_api/**'
- '!tfhe/src/boolean/**'
- '!tfhe/src/c_api/**'
- '!tfhe/src/js_on_wasm_api/**'
- name: Aggregate file changes
id: aggregated-changes
if: ( steps.changed-files.outputs.dependencies_any_changed == 'true' ||
steps.changed-files.outputs.csprng_any_changed == 'true' ||
steps.changed-files.outputs.zk_pok_any_changed == 'true' ||
steps.changed-files.outputs.versionable_any_changed == 'true' ||
steps.changed-files.outputs.core_crypto_any_changed == 'true' ||
steps.changed-files.outputs.boolean_any_changed == 'true' ||
steps.changed-files.outputs.shortint_any_changed == 'true' ||
steps.changed-files.outputs.integer_any_changed == 'true' ||
steps.changed-files.outputs.wasm_any_changed == 'true' ||
steps.changed-files.outputs.high_level_api_any_changed == 'true' ||
steps.changed-files.outputs.user_docs_any_changed == 'true')
run: |
echo "any_changed=true" >> "$GITHUB_OUTPUT"
setup-instance:
name: aws_tfhe_param_prod_tests/setup-instance
if: github.event_name == 'workflow_dispatch' ||
(github.event_name != 'workflow_dispatch' && needs.should-run.outputs.any_file_changed == 'true')
needs: should-run
runs-on: ubuntu-latest
outputs:
runner-name: ${{ steps.start-remote-instance.outputs.label || steps.start-github-instance.outputs.runner_group }}
steps:
- name: Start remote instance
id: start-remote-instance
if: env.SECRETS_AVAILABLE == 'true'
uses: zama-ai/slab-github-runner@973c1d22702de8d0acd2b34e83404c96ed92c264 # v1.4.2
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
slab-url: ${{ secrets.SLAB_BASE_URL }}
job-secret: ${{ secrets.JOB_SECRET }}
backend: aws
profile: cpu-big
# This instance will be spawned especially for pull-request from forked repository
- name: Start GitHub instance
id: start-github-instance
if: env.SECRETS_AVAILABLE == 'false'
run: |
echo "runner_group=${EXTERNAL_CONTRIBUTION_RUNNER}" >> "$GITHUB_OUTPUT"
param-prod-tests:
name: aws_tfhe_param_prod_tests/param-prod-tests
needs: [ should-run, setup-instance ]
concurrency:
group: ${{ github.workflow_ref }}
cancel-in-progress: true
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3
with:
persist-credentials: 'false'
token: ${{ env.CHECKOUT_TOKEN }}
- name: Install latest stable
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # zizmor: ignore[stale-action-refs] this action doesn't create releases
with:
toolchain: stable
- name: Gen Keys if required
if: needs.should-run.outputs.shortint_test == 'true' ||
needs.should-run.outputs.integer_test == 'true'
run: |
make gen_key_cache
- name: Run shortint tests
if: needs.should-run.outputs.shortint_test == 'true'
run: |
BIG_TESTS_INSTANCE=TRUE FAST_TESTS=FALSE make test_param_prod_shortint_ci
- name: Run integer tests
if: needs.should-run.outputs.integer_test == 'true'
run: |
BIG_TESTS_INSTANCE=TRUE FAST_TESTS=FALSE make test_param_prod_integer_ci
- name: Run high-level API tests
if: needs.should-run.outputs.high_level_api_test == 'true'
run: |
make test_param_prod_high_level_api
- name: Set pull-request URL
if: ${{ failure() && github.event_name == 'pull_request' }}
run: |
echo "PULL_REQUEST_MD_LINK=[pull-request](${PR_BASE_URL}${PR_NUMBER}), " >> "${GITHUB_ENV}"
env:
PR_BASE_URL: ${{ vars.PR_BASE_URL }}
PR_NUMBER: ${{ github.event.pull_request.number }}
- name: Slack Notification
if: ${{ failure() && env.SECRETS_AVAILABLE == 'true' }}
continue-on-error: true
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Fast AWS tests finished with status: ${{ job.status }}. (${{ env.PULL_REQUEST_MD_LINK }}[action run](${{ env.ACTION_RUN_URL }}))"
teardown-instance:
name: aws_tfhe_param_prod_tests/teardown-instance
if: ${{ always() && needs.setup-instance.result == 'success' }}
needs: [ setup-instance, param-prod-tests ]
runs-on: ubuntu-latest
steps:
- name: Stop remote instance
id: stop-instance
if: env.SECRETS_AVAILABLE == 'true'
uses: zama-ai/slab-github-runner@973c1d22702de8d0acd2b34e83404c96ed92c264 # v1.4.2
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
slab-url: ${{ secrets.SLAB_BASE_URL }}
job-secret: ${{ secrets.JOB_SECRET }}
label: ${{ needs.setup-instance.outputs.runner-name }}
- name: Slack Notification
if: ${{ failure() || (cancelled() && github.event_name != 'pull_request') }}
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (param-prod-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -73,7 +73,7 @@ jobs:
SHA: ${{ github.sha }}
- name: Install rust
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # zizmor: ignore[stale-action-refs] this action doesn't create releases
with:
toolchain: nightly
override: true

View File

@@ -73,7 +73,7 @@ jobs:
SHA: ${{ github.sha }}
- name: Install rust
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # zizmor: ignore[stale-action-refs] this action doesn't create releases
with:
toolchain: nightly
override: true

View File

@@ -32,7 +32,7 @@ jobs:
token: ${{ env.CHECKOUT_TOKEN }}
- name: Install Rust
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # zizmor: ignore[stale-action-refs] this action doesn't create releases
with:
toolchain: stable
override: true

View File

@@ -30,7 +30,7 @@ jobs:
token: ${{ env.CHECKOUT_TOKEN }}
- name: Install Rust
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # zizmor: ignore[stale-action-refs] this action doesn't create releases
with:
toolchain: stable
override: true

View File

@@ -62,7 +62,7 @@ jobs:
token: ${{ env.CHECKOUT_TOKEN }}
- name: Install Rust
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # zizmor: ignore[stale-action-refs] this action doesn't create releases
with:
toolchain: stable
override: true

View File

@@ -93,7 +93,7 @@ jobs:
token: ${{ env.CHECKOUT_TOKEN }}
- name: Install Rust
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # zizmor: ignore[stale-action-refs] this action doesn't create releases
with:
toolchain: stable
override: true

View File

@@ -89,7 +89,7 @@ jobs:
token: ${{ env.CHECKOUT_TOKEN }}
- name: Install Rust
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # zizmor: ignore[stale-action-refs] this action doesn't create releases
with:
toolchain: stable
override: true

View File

@@ -92,7 +92,7 @@ jobs:
- name: Publish web package
if: ${{ inputs.push_web_package }}
uses: JS-DevTools/npm-publish@7f8fe47b3bea1be0c3aec2b717c5ec1f3e03410b
uses: JS-DevTools/npm-publish@d2fef917d9aa6e1f0ee5eac28ed023eb4921ce51
with:
package: tfhe/pkg/package.json
dry-run: ${{ inputs.dry_run }}
@@ -109,7 +109,7 @@ jobs:
- name: Publish Node package
if: ${{ inputs.push_node_package }}
uses: JS-DevTools/npm-publish@7f8fe47b3bea1be0c3aec2b717c5ec1f3e03410b
uses: JS-DevTools/npm-publish@d2fef917d9aa6e1f0ee5eac28ed023eb4921ce51
with:
package: tfhe/pkg/package.json
dry-run: ${{ inputs.dry_run }}

View File

@@ -29,8 +29,8 @@ WASM_PACK_VERSION="0.13.1"
WASM_BINDGEN_VERSION:=$(shell cargo tree --target wasm32-unknown-unknown -e all --prefix none | grep "wasm-bindgen v" | head -n 1 | cut -d 'v' -f2)
WEB_RUNNER_DIR=web-test-runner
WEB_SERVER_DIR=tfhe/web_wasm_parallel_tests
TYPOS_VERSION=1.39.0
ZIZMOR_VERSION=1.16.2
TYPOS_VERSION=1.42.0
ZIZMOR_VERSION=1.20.0
# This is done to avoid forgetting it, we still precise the RUSTFLAGS in the commands to be able to
# copy paste the command in the terminal and change them if required without forgetting the flags
export RUSTFLAGS?=-C target-cpu=native
@@ -905,6 +905,14 @@ test_shortint_ci: install_cargo_nextest
./scripts/shortint-tests.sh \
--cargo-profile "$(CARGO_PROFILE)" --tfhe-package "tfhe"
.PHONY: test_param_prod_shortint_ci # Run the tests for shortint ci
test_param_prod_shortint_ci: install_cargo_nextest
BIG_TESTS_INSTANCE="$(BIG_TESTS_INSTANCE)" \
FAST_TESTS="$(FAST_TESTS)" \
./scripts/shortint-tests.sh \
--cargo-profile "$(CARGO_PROFILE)" --run-prod-only --tfhe-package "tfhe"
.PHONY: test_shortint_multi_bit_ci # Run the tests for shortint ci running only multibit tests
test_shortint_multi_bit_ci: install_cargo_nextest
BIG_TESTS_INSTANCE="$(BIG_TESTS_INSTANCE)" \
@@ -934,6 +942,15 @@ test_integer_ci: install_cargo_nextest
--cargo-profile "$(CARGO_PROFILE)" --avx512-support "$(AVX512_SUPPORT)" \
--tfhe-package "tfhe"
.PHONY: test_param_prod_integer_ci # Run the tests for integer ci
test_param_prod_integer_ci: install_cargo_nextest
BIG_TESTS_INSTANCE="$(BIG_TESTS_INSTANCE)" \
FAST_TESTS="$(FAST_TESTS)" \
NIGHTLY_TESTS="$(NIGHTLY_TESTS)" \
./scripts/integer-tests.sh \
--cargo-profile "$(CARGO_PROFILE)" --avx512-support "$(AVX512_SUPPORT)" \
--run-prod-only --tfhe-package "tfhe"
.PHONY: test_unsigned_integer_ci # Run the tests for unsigned integer ci
test_unsigned_integer_ci: install_cargo_nextest
BIG_TESTS_INSTANCE="$(BIG_TESTS_INSTANCE)" \
@@ -1031,9 +1048,16 @@ test_integer_cov: install_tarpaulin
.PHONY: test_high_level_api # Run all the tests for high_level_api
test_high_level_api:
RUSTFLAGS="$(RUSTFLAGS)" cargo test --profile $(CARGO_PROFILE) \
RUSTFLAGS="$(RUSTFLAGS)" cargo nextest run --cargo-profile $(CARGO_PROFILE) \
--profile=ci \
--features=boolean,shortint,integer,internal-keycache,zk-pok,strings -p tfhe \
-- high_level_api::
-E "test(/high_level_api::.*/) and not test(/.*param_prod.*/)"
test_param_prod_high_level_api:
RUSTFLAGS="$(RUSTFLAGS)" cargo nextest run --cargo-profile $(CARGO_PROFILE) \
--profile=ci \
--features=boolean,shortint,integer,internal-keycache,zk-pok,strings -p tfhe \
-E "test(/high_level_api::.*/) and test(/.*param_prod.*/)"
test_high_level_api_gpu: install_cargo_nextest
RUSTFLAGS="$(RUSTFLAGS)" cargo nextest run --cargo-profile $(CARGO_PROFILE) \

View File

@@ -129,7 +129,7 @@ Other sizes than 64 bit are expected to be available in the future.
# FHE shortint Trivium implementation
The same implementation is also available for generic Ciphertexts representing bits (meant to be used with parameters `V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128`).
The same implementation is also available for generic Ciphertexts representing bits (meant to be used with parameters `V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128`).
It uses a lower level API of tfhe-rs, so the syntax is a little bit different. It also implements the `TransCiphering` trait. For optimization purposes, it does not internally run
on the same cryptographic parameters as the high level API of tfhe-rs. As such, it requires the usage of a casting key, to switch from one parameter space to another, which makes
its setup a little more intricate.
@@ -138,9 +138,9 @@ Example code:
```rust
use tfhe::shortint::prelude::*;
use tfhe::shortint::parameters::current_params::{
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
};
use tfhe::{ConfigBuilder, generate_keys, FheUint64};
use tfhe::prelude::*;
@@ -148,17 +148,17 @@ use tfhe_trivium::TriviumStreamShortint;
fn test_shortint() {
let config = ConfigBuilder::default()
.use_custom_parameters(V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.use_custom_parameters(V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
let (hl_client_key, hl_server_key) = generate_keys(config);
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) = gen_keys(V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
let (client_key, server_key): (ClientKey, ServerKey) = gen_keys(V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
(&underlying_ck, &underlying_sk),
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128_2M128,
);
let key_string = "0053A6F94C9FF24598EB".to_string();

View File

@@ -1,9 +1,9 @@
use criterion::Criterion;
use tfhe::prelude::*;
use tfhe::shortint::parameters::current_params::{
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
};
use tfhe::shortint::prelude::*;
use tfhe::{generate_keys, ConfigBuilder, FheUint64};
@@ -11,19 +11,19 @@ use tfhe_trivium::{KreyviumStreamShortint, TransCiphering};
pub fn kreyvium_shortint_warmup(c: &mut Criterion) {
let config = ConfigBuilder::default()
.use_custom_parameters(V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.use_custom_parameters(V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
let (hl_client_key, hl_server_key) = generate_keys(config);
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
gen_keys(V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
(&underlying_ck, &underlying_sk),
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
);
let key_string = "0053A6F94C9FF24598EB000000000000".to_string();
@@ -64,19 +64,19 @@ pub fn kreyvium_shortint_warmup(c: &mut Criterion) {
pub fn kreyvium_shortint_gen(c: &mut Criterion) {
let config = ConfigBuilder::default()
.use_custom_parameters(V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.use_custom_parameters(V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
let (hl_client_key, hl_server_key) = generate_keys(config);
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
gen_keys(V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
(&underlying_ck, &underlying_sk),
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
);
let key_string = "0053A6F94C9FF24598EB000000000000".to_string();
@@ -112,19 +112,19 @@ pub fn kreyvium_shortint_gen(c: &mut Criterion) {
pub fn kreyvium_shortint_trans(c: &mut Criterion) {
let config = ConfigBuilder::default()
.use_custom_parameters(V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.use_custom_parameters(V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
let (hl_client_key, hl_server_key) = generate_keys(config);
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
gen_keys(V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
(&underlying_ck, &underlying_sk),
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
);
let key_string = "0053A6F94C9FF24598EB000000000000".to_string();

View File

@@ -1,9 +1,9 @@
use criterion::Criterion;
use tfhe::prelude::*;
use tfhe::shortint::parameters::current_params::{
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
};
use tfhe::shortint::prelude::*;
use tfhe::{generate_keys, ConfigBuilder, FheUint64};
@@ -11,19 +11,19 @@ use tfhe_trivium::{TransCiphering, TriviumStreamShortint};
pub fn trivium_shortint_warmup(c: &mut Criterion) {
let config = ConfigBuilder::default()
.use_custom_parameters(V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.use_custom_parameters(V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
let (hl_client_key, hl_server_key) = generate_keys(config);
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
gen_keys(V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
(&underlying_ck, &underlying_sk),
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
);
let key_string = "0053A6F94C9FF24598EB".to_string();
@@ -64,19 +64,19 @@ pub fn trivium_shortint_warmup(c: &mut Criterion) {
pub fn trivium_shortint_gen(c: &mut Criterion) {
let config = ConfigBuilder::default()
.use_custom_parameters(V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.use_custom_parameters(V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
let (hl_client_key, hl_server_key) = generate_keys(config);
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
gen_keys(V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
(&underlying_ck, &underlying_sk),
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
);
let key_string = "0053A6F94C9FF24598EB".to_string();
@@ -112,19 +112,19 @@ pub fn trivium_shortint_gen(c: &mut Criterion) {
pub fn trivium_shortint_trans(c: &mut Criterion) {
let config = ConfigBuilder::default()
.use_custom_parameters(V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.use_custom_parameters(V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
let (hl_client_key, hl_server_key) = generate_keys(config);
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
gen_keys(V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
(&underlying_ck, &underlying_sk),
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
);
let key_string = "0053A6F94C9FF24598EB".to_string();

View File

@@ -1,9 +1,9 @@
use crate::{KreyviumStream, KreyviumStreamByte, KreyviumStreamShortint, TransCiphering};
use tfhe::prelude::*;
use tfhe::shortint::parameters::current_params::{
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
};
use tfhe::{generate_keys, ConfigBuilder, FheBool, FheUint64, FheUint8};
// Values for these tests come from the github repo renaud1239/Kreyvium,
@@ -221,19 +221,19 @@ use tfhe::shortint::prelude::*;
#[test]
fn kreyvium_test_shortint_long() {
let config = ConfigBuilder::default()
.use_custom_parameters(V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.use_custom_parameters(V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
let (hl_client_key, hl_server_key) = generate_keys(config);
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
gen_keys(V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
(&underlying_ck, &underlying_sk),
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
);
let key_string = "0053A6F94C9FF24598EB000000000000".to_string();

View File

@@ -7,7 +7,7 @@ use tfhe::prelude::*;
use tfhe::shortint::Ciphertext;
use tfhe::{set_server_key, unset_server_key, FheUint64, FheUint8, ServerKey};
/// Triat specifying the interface for trans ciphering a FheUint64 object. Since it is meant
/// Trait specifying the interface for trans ciphering a FheUint64 object. Since it is meant
/// to be used with stream ciphers, encryption and decryption are by default the same.
pub trait TransCiphering {
fn trans_encrypt_64(&mut self, cipher: FheUint64) -> FheUint64;

View File

@@ -1,9 +1,9 @@
use crate::{TransCiphering, TriviumStream, TriviumStreamByte, TriviumStreamShortint};
use tfhe::prelude::*;
use tfhe::shortint::parameters::current_params::{
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
};
use tfhe::{generate_keys, ConfigBuilder, FheBool, FheUint64, FheUint8};
// Values for these tests come from the github repo cantora/avr-crypto-lib, commit 2a5b018,
@@ -357,19 +357,19 @@ use tfhe::shortint::prelude::*;
#[test]
fn trivium_test_shortint_long() {
let config = ConfigBuilder::default()
.use_custom_parameters(V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.use_custom_parameters(V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
let (hl_client_key, hl_server_key) = generate_keys(config);
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
gen_keys(V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
(&underlying_ck, &underlying_sk),
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
);
let key_string = "0053A6F94C9FF24598EB".to_string();

View File

@@ -29,13 +29,15 @@ template <typename Torus> struct int_aes_lut_buffers {
allocate_gpu_memory, size_tracker);
std::function<Torus(Torus, Torus)> and_lambda =
[](Torus a, Torus b) -> Torus { return a & b; };
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0), this->and_lut->get_lut(0, 0),
this->and_lut->get_degree(0), this->and_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, and_lambda, allocate_gpu_memory);
auto active_streams_and_lut = streams.active_gpu_subset(
SBOX_MAX_AND_GATES * num_aes_inputs * sbox_parallelism,
params.pbs_type);
this->and_lut->generate_and_broadcast_bivariate_lut(
active_streams_and_lut, {0}, {and_lambda}, allocate_gpu_memory);
this->and_lut->broadcast_lut(active_streams_and_lut);
this->and_lut->setup_gemm_batch_ks_temp_buffers(size_tracker);
this->flush_lut = new int_radix_lut<Torus>(
@@ -44,11 +46,14 @@ template <typename Torus> struct int_aes_lut_buffers {
std::function<Torus(Torus)> flush_lambda = [](Torus x) -> Torus {
return x & 1;
};
generate_device_accumulator(
streams.stream(0), streams.gpu_index(0), this->flush_lut->get_lut(0, 0),
this->flush_lut->get_degree(0), this->flush_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, flush_lambda, allocate_gpu_memory);
auto active_streams_flush_lut = streams.active_gpu_subset(
AES_STATE_BITS * num_aes_inputs, params.pbs_type);
this->flush_lut->generate_and_broadcast_lut(
active_streams_flush_lut, {0}, {flush_lambda}, allocate_gpu_memory);
this->flush_lut->broadcast_lut(active_streams_flush_lut);
this->flush_lut->setup_gemm_batch_ks_temp_buffers(size_tracker);
this->carry_lut = new int_radix_lut<Torus>(
@@ -56,11 +61,14 @@ template <typename Torus> struct int_aes_lut_buffers {
std::function<Torus(Torus)> carry_lambda = [](Torus x) -> Torus {
return (x >> 1) & 1;
};
generate_device_accumulator(
streams.stream(0), streams.gpu_index(0), this->carry_lut->get_lut(0, 0),
this->carry_lut->get_degree(0), this->carry_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, carry_lambda, allocate_gpu_memory);
auto active_streams_carry_lut =
streams.active_gpu_subset(num_aes_inputs, params.pbs_type);
this->carry_lut->generate_and_broadcast_lut(
active_streams_carry_lut, {0}, {carry_lambda}, allocate_gpu_memory);
this->carry_lut->broadcast_lut(active_streams_carry_lut);
this->carry_lut->setup_gemm_batch_ks_temp_buffers(size_tracker);
}

View File

@@ -70,7 +70,7 @@ public:
// Construct an empty set. Invalid use of an empty set should raise an error
// right away through asserts or because of a nullptr dereference
CudaStreams()
: _streams(nullptr), _gpu_indexes(nullptr), _gpu_count((uint32_t)-1),
: _streams(nullptr), _gpu_indexes(nullptr), _gpu_count(0),
_owns_streams(false) {}
// Returns a subset of this set as an active subset. An active subset is one
@@ -114,11 +114,13 @@ public:
// streams on the same GPU
void create_on_same_gpus(const CudaStreams &other) {
PANIC_IF_FALSE(_streams == nullptr,
"Assign clone to non-empty cudastreams");
"Cuda error: Assign clone to non-empty CudaStreams");
PANIC_IF_FALSE(_gpu_count <= 8,
"Cuda error: GPU count should be in the interval [0, 8]");
cudaStream_t *new_streams = new cudaStream_t[other._gpu_count];
uint32_t *gpu_indexes_clone = new uint32_t[_gpu_count];
uint32_t *gpu_indexes_clone = new uint32_t[other._gpu_count];
for (uint32_t i = 0; i < other._gpu_count; ++i) {
new_streams[i] = cuda_create_stream(other._gpu_indexes[i]);
gpu_indexes_clone[i] = other._gpu_indexes[i];
@@ -170,6 +172,7 @@ public:
_streams = nullptr;
delete[] _gpu_indexes;
_gpu_indexes = nullptr;
_gpu_count = 0;
}
}

View File

@@ -65,8 +65,14 @@ template <typename Torus> struct boolean_bitop_buffer {
return x % params.message_modulus;
};
message_extract_lut->generate_and_broadcast_lut(
active_streams, {0}, {lut_f_message_extract}, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
message_extract_lut->get_lut(0, 0),
message_extract_lut->get_degree(0),
message_extract_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
lut_f_message_extract, gpu_memory_allocated);
message_extract_lut->broadcast_lut(active_streams);
}
tmp_lwe_left = new CudaRadixCiphertextFFI;
create_zero_radix_ciphertext_async<Torus>(
@@ -136,8 +142,12 @@ template <typename Torus> struct int_bitop_buffer {
}
};
lut->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {lut_bivariate_f}, gpu_memory_allocated);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0), lut->get_lut(0, 0),
lut->get_degree(0), lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus,
params.carry_modulus, lut_bivariate_f, gpu_memory_allocated);
lut->broadcast_lut(active_streams);
}
break;
default:
@@ -146,8 +156,6 @@ template <typename Torus> struct int_bitop_buffer {
num_radix_blocks, allocate_gpu_memory,
size_tracker);
std::vector<std::function<Torus(Torus)>> lut_funcs;
std::vector<uint32_t> lut_indices;
for (int i = 0; i < params.message_modulus; i++) {
auto rhs = i;
@@ -163,13 +171,14 @@ template <typename Torus> struct int_bitop_buffer {
return x ^ rhs;
}
};
lut_funcs.push_back(lut_univariate_scalar_f);
lut_indices.push_back(i);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), lut->get_lut(0, i),
lut->get_degree(i), lut->get_max_degree(i), params.glwe_dimension,
params.polynomial_size, params.message_modulus,
params.carry_modulus, lut_univariate_scalar_f,
gpu_memory_allocated);
lut->broadcast_lut(active_streams);
}
lut->generate_and_broadcast_lut(active_streams, lut_indices, lut_funcs,
gpu_memory_allocated);
}
}
@@ -202,11 +211,16 @@ template <typename Torus> struct boolean_bitnot_buffer {
return x % message_modulus;
};
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
message_extract_lut->get_lut(0, 0),
message_extract_lut->get_degree(0),
message_extract_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
lut_f_message_extract, gpu_memory_allocated);
auto active_streams =
streams.active_gpu_subset(lwe_ciphertext_count, params.pbs_type);
message_extract_lut->generate_and_broadcast_lut(
active_streams, {0}, {lut_f_message_extract}, gpu_memory_allocated);
message_extract_lut->broadcast_lut(active_streams);
}
}

View File

@@ -28,17 +28,21 @@ template <typename Torus> struct int_extend_radix_with_sign_msb_buffer {
uint32_t bits_per_block = std::log2(params.message_modulus);
uint32_t msg_modulus = params.message_modulus;
auto active_streams =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
lut->generate_and_broadcast_lut(
active_streams, {0}, {[msg_modulus, bits_per_block](Torus x) {
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), lut->get_lut(0, 0),
lut->get_degree(0), lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
[msg_modulus, bits_per_block](Torus x) {
const auto xm = x % msg_modulus;
const auto sign_bit = (xm >> (bits_per_block - 1)) & 1;
return (Torus)((msg_modulus - 1) * sign_bit);
}},
},
allocate_gpu_memory);
auto active_streams =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
lut->broadcast_lut(active_streams);
this->last_block = new CudaRadixCiphertextFFI;
create_zero_radix_ciphertext_async<Torus>(

View File

@@ -85,6 +85,24 @@ template <typename Torus> struct int_cmux_buffer {
new int_radix_lut<Torus>(streams, params, 1, num_radix_blocks,
allocate_gpu_memory, size_tracker);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0), predicate_lut->get_lut(0, 0),
predicate_lut->get_degree(0), predicate_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, inverted_lut_f, gpu_memory_allocated);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0), predicate_lut->get_lut(0, 1),
predicate_lut->get_degree(1), predicate_lut->get_max_degree(1),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, lut_f, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
message_extract_lut->get_lut(0, 0), message_extract_lut->get_degree(0),
message_extract_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
message_extract_lut_f, gpu_memory_allocated);
Torus *h_lut_indexes = predicate_lut->h_lut_indexes;
for (int index = 0; index < 2 * num_radix_blocks; index++) {
if (index < num_radix_blocks) {
@@ -97,18 +115,12 @@ template <typename Torus> struct int_cmux_buffer {
predicate_lut->get_lut_indexes(0, 0), h_lut_indexes,
2 * num_radix_blocks * sizeof(Torus), streams.stream(0),
streams.gpu_index(0), allocate_gpu_memory);
auto active_streams_pred =
streams.active_gpu_subset(2 * num_radix_blocks, params.pbs_type);
predicate_lut->generate_and_broadcast_bivariate_lut(
active_streams_pred, {0, 1}, {inverted_lut_f, lut_f},
gpu_memory_allocated);
predicate_lut->broadcast_lut(active_streams_pred);
auto active_streams_msg =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
message_extract_lut->generate_and_broadcast_lut(
active_streams_msg, {0}, {message_extract_lut_f}, gpu_memory_allocated);
message_extract_lut->broadcast_lut(active_streams_msg);
}
void release(CudaStreams streams) {

View File

@@ -39,21 +39,22 @@ template <typename Torus> struct int_are_all_block_true_buffer {
max_chunks, params.big_lwe_dimension, size_tracker,
allocate_gpu_memory);
preallocated_h_lut = (Torus *)malloc(
(params.glwe_dimension + 1) * params.polynomial_size * sizeof(Torus));
is_max_value = new int_radix_lut<Torus>(streams, params, 2, max_chunks,
allocate_gpu_memory, size_tracker);
auto active_streams =
streams.active_gpu_subset(max_chunks, params.pbs_type);
auto is_max_value_f = [max_value](Torus x) -> Torus {
return x == max_value;
};
preallocated_h_lut = (Torus *)malloc(
(params.glwe_dimension + 1) * params.polynomial_size * sizeof(Torus));
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), is_max_value->get_lut(0, 0),
is_max_value->get_degree(0), is_max_value->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, is_max_value_f, gpu_memory_allocated);
is_max_value->generate_and_broadcast_lut(
active_streams, {0}, {is_max_value_f}, gpu_memory_allocated);
auto active_streams =
streams.active_gpu_subset(max_chunks, params.pbs_type);
is_max_value->broadcast_lut(active_streams);
}
void release(CudaStreams streams) {
@@ -102,10 +103,15 @@ template <typename Torus> struct int_comparison_eq_buffer {
new int_radix_lut<Torus>(streams, params, 1, num_radix_blocks,
allocate_gpu_memory, size_tracker);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), is_non_zero_lut->get_lut(0, 0),
is_non_zero_lut->get_degree(0), is_non_zero_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, is_non_zero_lut_f, gpu_memory_allocated);
auto active_streams =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
is_non_zero_lut->generate_and_broadcast_lut(
active_streams, {0}, {is_non_zero_lut_f}, gpu_memory_allocated);
is_non_zero_lut->broadcast_lut(active_streams);
// Scalar may have up to num_radix_blocks blocks
scalar_comparison_luts = new int_radix_lut<Torus>(
@@ -123,28 +129,32 @@ template <typename Torus> struct int_comparison_eq_buffer {
return (lhs == rhs);
}
};
std::vector<std::function<Torus(Torus)>> lut_funcs;
std::vector<uint32_t> lut_indices;
for (int i = 0; i < total_modulus; i++) {
auto lut_f = [i, operator_f](Torus x) -> Torus {
return operator_f(i, x);
};
lut_funcs.push_back(lut_f);
lut_indices.push_back(i);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
scalar_comparison_luts->get_lut(0, i),
scalar_comparison_luts->get_degree(i),
scalar_comparison_luts->get_max_degree(i), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
lut_f, gpu_memory_allocated);
}
scalar_comparison_luts->generate_and_broadcast_lut(
active_streams, lut_indices, lut_funcs, gpu_memory_allocated);
scalar_comparison_luts->broadcast_lut(active_streams);
if (op == COMPARISON_TYPE::EQ || op == COMPARISON_TYPE::NE) {
operator_lut =
new int_radix_lut<Torus>(streams, params, 1, num_radix_blocks,
allocate_gpu_memory, size_tracker);
operator_lut->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {operator_f}, gpu_memory_allocated);
// operator_lut->broadcast_lut(active_streams);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0), operator_lut->get_lut(0, 0),
operator_lut->get_degree(0), operator_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, operator_f, gpu_memory_allocated);
operator_lut->broadcast_lut(active_streams);
} else {
operator_lut = nullptr;
}
@@ -211,6 +221,9 @@ template <typename Torus> struct int_tree_sign_reduction_buffer {
streams.stream(0), streams.gpu_index(0), tmp_y, num_radix_blocks,
params.big_lwe_dimension, size_tracker, allocate_gpu_memory);
// LUTs
tree_inner_leaf_lut =
new int_radix_lut<Torus>(streams, params, 1, num_radix_blocks,
allocate_gpu_memory, size_tracker);
tree_last_leaf_lut = new int_radix_lut<Torus>(
streams, params, 1, 1, allocate_gpu_memory, size_tracker);
@@ -221,14 +234,15 @@ template <typename Torus> struct int_tree_sign_reduction_buffer {
tree_last_leaf_scalar_lut = new int_radix_lut<Torus>(
streams, params, 1, 1, allocate_gpu_memory, size_tracker);
tree_inner_leaf_lut =
new int_radix_lut<Torus>(streams, params, 1, num_radix_blocks,
allocate_gpu_memory, size_tracker);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
tree_inner_leaf_lut->get_lut(0, 0), tree_inner_leaf_lut->get_degree(0),
tree_inner_leaf_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
block_selector_f, gpu_memory_allocated);
auto active_streams =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
tree_inner_leaf_lut->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {block_selector_f}, allocate_gpu_memory);
tree_inner_leaf_lut->broadcast_lut(active_streams);
}
void release(CudaStreams streams) {
@@ -412,8 +426,12 @@ template <typename Torus> struct int_comparison_buffer {
new int_radix_lut<Torus>(streams, params, 1, num_radix_blocks,
allocate_gpu_memory, size_tracker);
identity_lut->generate_and_broadcast_lut(
active_streams, {0}, {identity_lut_f}, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), identity_lut->get_lut(0, 0),
identity_lut->get_degree(0), identity_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, identity_lut_f, gpu_memory_allocated);
identity_lut->broadcast_lut(active_streams);
uint32_t total_modulus = params.message_modulus * params.carry_modulus;
auto is_zero_f = [total_modulus](Torus x) -> Torus {
@@ -423,8 +441,13 @@ template <typename Torus> struct int_comparison_buffer {
is_zero_lut = new int_radix_lut<Torus>(streams, params, 1, num_radix_blocks,
allocate_gpu_memory, size_tracker);
is_zero_lut->generate_and_broadcast_lut(active_streams, {0}, {is_zero_f},
gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), is_zero_lut->get_lut(0, 0),
is_zero_lut->get_degree(0), is_zero_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, is_zero_f, gpu_memory_allocated);
is_zero_lut->broadcast_lut(active_streams);
switch (op) {
case COMPARISON_TYPE::MAX:
@@ -499,9 +522,13 @@ template <typename Torus> struct int_comparison_buffer {
PANIC("Cuda error: sign_lut creation failed due to wrong function.")
};
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0), signed_lut->get_lut(0, 0),
signed_lut->get_degree(0), signed_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, signed_lut_f, gpu_memory_allocated);
auto active_streams = streams.active_gpu_subset(1, params.pbs_type);
signed_lut->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {signed_lut_f}, gpu_memory_allocated);
signed_lut->broadcast_lut(active_streams);
}
preallocated_h_lut = (Torus *)malloc(
(params.glwe_dimension + 1) * params.polynomial_size * sizeof(Torus));

View File

@@ -283,9 +283,12 @@ template <typename Torus> struct unsigned_int_div_rem_2_2_memory {
zero_out_if_not_1_lut_2};
size_t lut_gpu_indexes[2] = {0, 3};
for (int j = 0; j < 2; j++) {
luts[j]->generate_and_broadcast_lut(streams.get_ith(lut_gpu_indexes[j]),
{0}, {zero_out_if_not_1_lut_f},
gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(lut_gpu_indexes[j]),
streams.gpu_index(lut_gpu_indexes[j]), luts[j]->get_lut(0, 0),
luts[j]->get_degree(0), luts[j]->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, zero_out_if_not_1_lut_f, gpu_memory_allocated);
}
luts[0] = zero_out_if_not_2_lut_1;
@@ -293,9 +296,12 @@ template <typename Torus> struct unsigned_int_div_rem_2_2_memory {
lut_gpu_indexes[0] = 1;
lut_gpu_indexes[1] = 2;
for (int j = 0; j < 2; j++) {
luts[j]->generate_and_broadcast_lut(streams.get_ith(lut_gpu_indexes[j]),
{0}, {zero_out_if_not_2_lut_f},
gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(lut_gpu_indexes[j]),
streams.gpu_index(lut_gpu_indexes[j]), luts[j]->get_lut(0, 0),
luts[j]->get_degree(0), luts[j]->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, zero_out_if_not_2_lut_f, gpu_memory_allocated);
}
quotient_lut_1 =
@@ -315,12 +321,21 @@ template <typename Torus> struct unsigned_int_div_rem_2_2_memory {
};
auto quotient_lut_3_f = [](Torus cond) -> Torus { return cond * 3; };
quotient_lut_1->generate_and_broadcast_lut(
streams.get_ith(2), {0}, {quotient_lut_1_f}, gpu_memory_allocated);
quotient_lut_2->generate_and_broadcast_lut(
streams.get_ith(1), {0}, {quotient_lut_2_f}, gpu_memory_allocated);
quotient_lut_3->generate_and_broadcast_lut(
streams.get_ith(0), {0}, {quotient_lut_3_f}, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(2), streams.gpu_index(2), quotient_lut_1->get_lut(0, 0),
quotient_lut_1->get_degree(0), quotient_lut_1->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, quotient_lut_1_f, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(1), streams.gpu_index(1), quotient_lut_2->get_lut(0, 0),
quotient_lut_2->get_degree(0), quotient_lut_2->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, quotient_lut_2_f, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), quotient_lut_3->get_lut(0, 0),
quotient_lut_3->get_degree(0), quotient_lut_3->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, quotient_lut_3_f, gpu_memory_allocated);
message_extract_lut_1 = new int_radix_lut<Torus>(
streams, params, 1, num_blocks, allocate_gpu_memory, size_tracker);
@@ -335,12 +350,15 @@ template <typename Torus> struct unsigned_int_div_rem_2_2_memory {
luts[0] = message_extract_lut_1;
luts[1] = message_extract_lut_2;
auto active_streams =
streams.active_gpu_subset(num_blocks, params.pbs_type);
for (int j = 0; j < 2; j++) {
luts[j]->generate_and_broadcast_lut(
active_streams, {0}, {lut_f_message_extract}, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), luts[j]->get_lut(0, 0),
luts[j]->get_degree(0), luts[j]->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, lut_f_message_extract, gpu_memory_allocated);
auto active_streams =
streams.active_gpu_subset(num_blocks, params.pbs_type);
luts[j]->broadcast_lut(active_streams);
}
}
@@ -989,14 +1007,24 @@ template <typename Torus> struct unsigned_int_div_rem_memory {
masking_luts_2[i] = new int_radix_lut<Torus>(
streams, params, 1, num_blocks, allocate_gpu_memory, size_tracker);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
masking_luts_1[i]->get_lut(0, 0), masking_luts_1[i]->get_degree(0),
masking_luts_1[i]->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
lut_f_masking, gpu_memory_allocated);
auto active_streams_1 = streams.active_gpu_subset(1, params.pbs_type);
masking_luts_1[i]->generate_and_broadcast_lut(
active_streams_1, {0}, {lut_f_masking}, gpu_memory_allocated);
masking_luts_1[i]->broadcast_lut(active_streams_1);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
masking_luts_2[i]->get_lut(0, 0), masking_luts_2[i]->get_degree(0),
masking_luts_2[i]->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
lut_f_masking, gpu_memory_allocated);
auto active_streams_2 =
streams.active_gpu_subset(num_blocks, params.pbs_type);
masking_luts_2[i]->generate_and_broadcast_lut(
active_streams_2, {0}, {lut_f_masking}, gpu_memory_allocated);
masking_luts_2[i]->broadcast_lut(active_streams_2);
}
// create and generate message_extract_lut_1 and message_extract_lut_2
@@ -1014,12 +1042,15 @@ template <typename Torus> struct unsigned_int_div_rem_memory {
int_radix_lut<Torus> *luts[2] = {message_extract_lut_1,
message_extract_lut_2};
auto active_streams =
streams.active_gpu_subset(num_blocks, params.pbs_type);
for (int j = 0; j < 2; j++) {
luts[j]->generate_and_broadcast_lut(
active_streams, {0}, {lut_f_message_extract}, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), luts[j]->get_lut(0, 0),
luts[j]->get_degree(0), luts[j]->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, lut_f_message_extract, gpu_memory_allocated);
luts[j]->broadcast_lut(active_streams);
}
// Give name to closures to improve readability
@@ -1110,8 +1141,14 @@ template <typename Torus> struct unsigned_int_div_rem_memory {
merge_overflow_flags_luts[i] = new int_radix_lut<Torus>(
streams, params, 1, 1, allocate_gpu_memory, size_tracker);
merge_overflow_flags_luts[i]->generate_and_broadcast_bivariate_lut(
active_gpu_count_for_bits, {0}, {lut_f_bit}, gpu_memory_allocated);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
merge_overflow_flags_luts[i]->get_lut(0, 0),
merge_overflow_flags_luts[i]->get_degree(0),
merge_overflow_flags_luts[i]->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, lut_f_bit, gpu_memory_allocated);
merge_overflow_flags_luts[i]->broadcast_lut(active_gpu_count_for_bits);
}
}
@@ -1520,12 +1557,16 @@ template <typename Torus> struct int_div_rem_memory {
compare_signed_bits_lut = new int_radix_lut<Torus>(
streams, params, 1, 1, allocate_gpu_memory, size_tracker);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
compare_signed_bits_lut->get_lut(0, 0),
compare_signed_bits_lut->get_degree(0),
compare_signed_bits_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
f_compare_extracted_signed_bits, gpu_memory_allocated);
auto active_gpu_count_cmp =
streams.active_gpu_subset(1, params.pbs_type); // only 1 block needed
compare_signed_bits_lut->generate_and_broadcast_bivariate_lut(
active_gpu_count_cmp, {0}, {f_compare_extracted_signed_bits},
gpu_memory_allocated);
compare_signed_bits_lut->broadcast_lut(active_gpu_count_cmp);
}
}

View File

@@ -53,8 +53,13 @@ template <typename Torus> struct int_prepare_count_of_consecutive_bits_buffer {
return count;
};
univ_lut_mem->generate_and_broadcast_lut(
active_streams, {0}, {generate_uni_lut_lambda}, allocate_gpu_memory);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), univ_lut_mem->get_lut(0, 0),
univ_lut_mem->get_degree(0), univ_lut_mem->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, generate_uni_lut_lambda, allocate_gpu_memory);
univ_lut_mem->broadcast_lut(active_streams);
auto generate_bi_lut_lambda =
[num_bits](Torus block_num_bit_count,
@@ -65,8 +70,13 @@ template <typename Torus> struct int_prepare_count_of_consecutive_bits_buffer {
return 0;
};
biv_lut_mem->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {generate_bi_lut_lambda}, allocate_gpu_memory);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0), biv_lut_mem->get_lut(0, 0),
biv_lut_mem->get_degree(0), biv_lut_mem->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, generate_bi_lut_lambda, allocate_gpu_memory);
biv_lut_mem->broadcast_lut(active_streams);
this->tmp_ct = new CudaRadixCiphertextFFI;
create_zero_radix_ciphertext_async<Torus>(
@@ -222,7 +232,7 @@ template <typename Torus> struct int_ilog2_buffer {
this->sum_output_not_propagated, counter_num_blocks,
params.big_lwe_dimension, size_tracker, allocate_gpu_memory);
lut_message_not =
this->lut_message_not =
new int_radix_lut<Torus>(streams, params, 1, counter_num_blocks,
allocate_gpu_memory, size_tracker);
std::function<Torus(Torus)> lut_message_lambda =
@@ -230,11 +240,16 @@ template <typename Torus> struct int_ilog2_buffer {
uint64_t message = x % this->params.message_modulus;
return (~message) % this->params.message_modulus;
};
generate_device_accumulator(streams.stream(0), streams.gpu_index(0),
this->lut_message_not->get_lut(0, 0),
this->lut_message_not->get_degree(0),
this->lut_message_not->get_max_degree(0),
params.glwe_dimension, params.polynomial_size,
params.message_modulus, params.carry_modulus,
lut_message_lambda, allocate_gpu_memory);
auto active_streams =
streams.active_gpu_subset(counter_num_blocks, params.pbs_type);
lut_message_not->generate_and_broadcast_lut(
active_streams, {0}, {lut_message_lambda}, allocate_gpu_memory);
lut_message_not->broadcast_lut(active_streams);
this->lut_carry_not =
new int_radix_lut<Torus>(streams, params, 1, counter_num_blocks,
@@ -244,8 +259,13 @@ template <typename Torus> struct int_ilog2_buffer {
uint64_t carry = x / this->params.message_modulus;
return (~carry) % this->params.message_modulus;
};
lut_carry_not->generate_and_broadcast_lut(
active_streams, {0}, {lut_carry_lambda}, allocate_gpu_memory);
generate_device_accumulator(
streams.stream(0), streams.gpu_index(0),
this->lut_carry_not->get_lut(0, 0), this->lut_carry_not->get_degree(0),
this->lut_carry_not->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
lut_carry_lambda, allocate_gpu_memory);
lut_carry_not->broadcast_lut(active_streams);
this->message_blocks_not = new CudaRadixCiphertextFFI;
create_zero_radix_ciphertext_async<Torus>(

View File

@@ -9,7 +9,6 @@
#include "utils/helper_multi_gpu.cuh"
#include <cmath>
#include <functional>
#include <map>
#include <queue>
#include <stdio.h>
@@ -836,56 +835,6 @@ struct int_radix_lut_custom_input_output {
}
}
void generate_and_broadcast_lut(
const CudaStreams &streams, std::vector<uint32_t> lut_indexes,
std::vector<std::function<OutputTorus(OutputTorus)>> f,
bool gpu_memory_allocated) {
// streams should be a subset of active_streams
for (uint32_t i = 0; i < lut_indexes.size(); ++i) {
generate_device_accumulator<OutputTorus>(
streams.stream(0), streams.gpu_index(0), get_lut(0, lut_indexes[i]),
get_degree(lut_indexes[i]), get_max_degree(lut_indexes[i]),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, f[i], gpu_memory_allocated);
}
//broadcast_lut(streams);
}
void generate_and_broadcast_bivariate_lut(
const CudaStreams &streams, std::vector<uint32_t> lut_indexes,
std::vector<std::function<OutputTorus(OutputTorus, OutputTorus)>> f,
bool gpu_memory_allocated) {
// streams should be a subset of active_streams
/* for (int fidx = 0; fidx < f.size(); ++fidx) {
__int128_t f_hash = 0;
uint32_t bits_per_lut_val = 5;
uint32_t input_modulus_sup =
params.message_modulus * params.carry_modulus;
for (uint32_t i = 0; i < input_modulus_sup; ++i) {
OutputTorus f_eval =
f[fidx](i / params.message_modulus, i % params.message_modulus);
GPU_ASSERT(f_eval < (1 << bits_per_lut_val),
"LUT value expected bitwidth overflow");
f_hash |= f_eval;
f_hash <<= bits_per_lut_val;
}
printf("%016llX%016llX\n",
(unsigned long long)((f_hash >> 64) & 0xFFFFFFFFFFFFFFFF),
(unsigned long long)(f_hash & 0xFFFFFFFFFFFFFFFF));
}
*/
for (uint32_t i = 0; i < lut_indexes.size(); ++i) {
generate_device_accumulator_bivariate<InputTorus>(
streams.stream(0), streams.gpu_index(0), get_lut(0, lut_indexes[i]),
get_degree(lut_indexes[i]), get_max_degree(lut_indexes[i]),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, f[i], gpu_memory_allocated);
}
//broadcast_lut(streams);
}
void release(CudaStreams streams) {
PANIC_IF_FALSE(lut_indexes_vec.size() == lut_vec.size(),
"Lut vec and Lut vec indexes must have the same size");
@@ -1036,15 +985,18 @@ template <typename Torus> struct int_bit_extract_luts_buffer {
bits_per_block * num_radix_blocks,
allocate_gpu_memory, size_tracker);
std::vector<std::function<Torus(Torus)>> lut_funs;
std::vector<uint32_t> lut_indices;
for (int i = 0; i < bits_per_block; i++) {
auto operator_f = [i, final_offset](Torus x) -> Torus {
Torus y = (x >> i) & 1;
return y << final_offset;
};
lut_funs.push_back(operator_f);
lut_indices.push_back(i);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), lut->get_lut(0, i),
lut->get_degree(i), lut->get_max_degree(i), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
operator_f, gpu_memory_allocated);
}
/**
@@ -1063,10 +1015,7 @@ template <typename Torus> struct int_bit_extract_luts_buffer {
auto active_streams = streams.active_gpu_subset(
bits_per_block * num_radix_blocks, params.pbs_type);
lut->generate_and_broadcast_lut(active_streams, lut_indices, lut_funs,
gpu_memory_allocated);
// lut->broadcast_lut(active_streams);
lut->broadcast_lut(active_streams);
/**
* the input indexes should take the first bits_per_block PBS to target
@@ -1142,6 +1091,24 @@ template <typename Torus> struct int_fullprop_buffer {
};
//
Torus *lut_buffer_message = lut->get_lut(0, 0);
uint64_t *message_degree = lut->get_degree(0);
uint64_t *message_max_degree = lut->get_max_degree(0);
Torus *lut_buffer_carry = lut->get_lut(0, 1);
uint64_t *carry_degree = lut->get_degree(1);
uint64_t *carry_max_degree = lut->get_max_degree(1);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), lut_buffer_message,
message_degree, message_max_degree, params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
lut_f_message, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), lut_buffer_carry, carry_degree,
carry_max_degree, params.glwe_dimension, params.polynomial_size,
params.message_modulus, params.carry_modulus, lut_f_carry,
gpu_memory_allocated);
uint64_t lwe_indexes_size = 2 * sizeof(Torus);
Torus *h_lwe_indexes = (Torus *)malloc(lwe_indexes_size);
@@ -1151,15 +1118,9 @@ template <typename Torus> struct int_fullprop_buffer {
cuda_memcpy_with_size_tracking_async_to_gpu(
lwe_indexes, h_lwe_indexes, lwe_indexes_size, streams.stream(0),
streams.gpu_index(0), allocate_gpu_memory);
//
// No broadcast is needed because full prop is done on 1 single GPU.
// By passing a single-GPU CudaStreams with streams.get_ith(0) the LUT is
// not broadcast.
//
lut->generate_and_broadcast_lut(streams.get_ith(0), {0, 1},
{lut_f_message, lut_f_carry},
gpu_memory_allocated);
tmp_small_lwe_vector = new CudaRadixCiphertextFFI;
create_zero_radix_ciphertext_async<Torus>(
@@ -1277,10 +1238,9 @@ template <typename Torus> struct int_sum_ciphertexts_vec_memory {
if (total_ciphertexts > 0 ||
reduce_degrees_for_single_carry_propagation) {
uint64_t size_tracker = 0;
allocated_luts_message_carry = true;
luts_message_carry = new int_radix_lut<Torus>(
streams, params, 2, pbs_count, true, size_tracker);
allocated_luts_message_carry = true;
uint64_t message_modulus_bits =
(uint64_t)std::log2(params.message_modulus);
uint64_t carry_modulus_bits = (uint64_t)std::log2(params.carry_modulus);
@@ -1296,9 +1256,7 @@ template <typename Torus> struct int_sum_ciphertexts_vec_memory {
streams, upper_bound_num_blocks, size_tracker, true);
}
}
if (allocated_luts_message_carry) {
auto message_acc = luts_message_carry->get_lut(0, 0);
auto carry_acc = luts_message_carry->get_lut(0, 1);
@@ -1310,11 +1268,22 @@ template <typename Torus> struct int_sum_ciphertexts_vec_memory {
return x / message_modulus;
};
// generate accumulators
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), message_acc,
luts_message_carry->get_degree(0),
luts_message_carry->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, message_modulus, params.carry_modulus,
lut_f_message, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), carry_acc,
luts_message_carry->get_degree(1),
luts_message_carry->get_max_degree(1), params.glwe_dimension,
params.polynomial_size, message_modulus, params.carry_modulus,
lut_f_carry, gpu_memory_allocated);
auto active_gpu_count_mc =
streams.active_gpu_subset(pbs_count, params.pbs_type);
luts_message_carry->generate_and_broadcast_lut(
active_gpu_count_mc, {0, 1}, {lut_f_message, lut_f_carry},
gpu_memory_allocated);
luts_message_carry->broadcast_lut(active_gpu_count_mc);
}
}
int_sum_ciphertexts_vec_memory(
@@ -1449,6 +1418,10 @@ template <typename Torus> struct int_seq_group_prop_memory {
uint32_t group_size, uint32_t big_lwe_size_bytes,
bool allocate_gpu_memory, uint64_t &size_tracker) {
gpu_memory_allocated = allocate_gpu_memory;
auto glwe_dimension = params.glwe_dimension;
auto polynomial_size = params.polynomial_size;
auto message_modulus = params.message_modulus;
auto carry_modulus = params.carry_modulus;
grouping_size = group_size;
group_resolved_carries = new CudaRadixCiphertextFFI;
@@ -1458,20 +1431,22 @@ template <typename Torus> struct int_seq_group_prop_memory {
allocate_gpu_memory);
int num_seq_luts = grouping_size - 1;
Torus *h_seq_lut_indexes = (Torus *)malloc(num_seq_luts * sizeof(Torus));
lut_sequential_algorithm =
new int_radix_lut<Torus>(streams, params, num_seq_luts, num_seq_luts,
allocate_gpu_memory, size_tracker);
std::vector<std::function<Torus(Torus)>> lut_funcs;
std::vector<uint32_t> lut_indices;
Torus *h_seq_lut_indexes = (Torus *)malloc(num_seq_luts * sizeof(Torus));
for (int index = 0; index < num_seq_luts; index++) {
auto f_lut_sequential = [index](Torus propa_cum_sum_block) {
return (propa_cum_sum_block >> (index + 1)) & 1;
};
lut_funcs.push_back(f_lut_sequential);
auto seq_lut = lut_sequential_algorithm->get_lut(0, index);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), seq_lut,
lut_sequential_algorithm->get_degree(index),
lut_sequential_algorithm->get_max_degree(index), glwe_dimension,
polynomial_size, message_modulus, carry_modulus, f_lut_sequential,
gpu_memory_allocated);
h_seq_lut_indexes[index] = index;
lut_indices.push_back(index);
}
Torus *seq_lut_indexes = lut_sequential_algorithm->get_lut_indexes(0, 0);
cuda_memcpy_with_size_tracking_async_to_gpu(
@@ -1479,12 +1454,9 @@ template <typename Torus> struct int_seq_group_prop_memory {
streams.stream(0), streams.gpu_index(0), allocate_gpu_memory);
auto active_streams =
streams.active_gpu_subset(num_seq_luts, params.pbs_type);
lut_sequential_algorithm->generate_and_broadcast_lut(
active_streams, lut_indices, lut_funcs, gpu_memory_allocated);
// lut_sequential_algorithm->broadcast_lut(active_streams);
lut_sequential_algorithm->broadcast_lut(active_streams);
free(h_seq_lut_indexes);
}
};
void release(CudaStreams streams) {
release_radix_ciphertext_async(streams.stream(0), streams.gpu_index(0),
group_resolved_carries,
@@ -1506,6 +1478,10 @@ template <typename Torus> struct int_hs_group_prop_memory {
uint32_t num_groups, uint32_t big_lwe_size_bytes,
bool allocate_gpu_memory, uint64_t &size_tracker) {
gpu_memory_allocated = allocate_gpu_memory;
auto glwe_dimension = params.glwe_dimension;
auto polynomial_size = params.polynomial_size;
auto message_modulus = params.message_modulus;
auto carry_modulus = params.carry_modulus;
auto f_lut_hillis_steele = [](Torus msb, Torus lsb) -> Torus {
if (msb == 2) {
@@ -1525,11 +1501,16 @@ template <typename Torus> struct int_hs_group_prop_memory {
lut_hillis_steele = new int_radix_lut<Torus>(
streams, params, 1, num_groups, allocate_gpu_memory, size_tracker);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
lut_hillis_steele->get_lut(0, 0), lut_hillis_steele->get_degree(0),
lut_hillis_steele->get_max_degree(0), glwe_dimension, polynomial_size,
message_modulus, carry_modulus, f_lut_hillis_steele,
gpu_memory_allocated);
auto active_streams =
streams.active_gpu_subset(num_groups, params.pbs_type);
lut_hillis_steele->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {f_lut_hillis_steele}, gpu_memory_allocated);
}
lut_hillis_steele->broadcast_lut(active_streams);
};
void release(CudaStreams streams) {
lut_hillis_steele->release(streams);
@@ -1819,6 +1800,112 @@ template <typename Torus> struct int_prop_simu_group_carries_memory {
num_extra_luts = 1;
}
uint32_t num_luts_second_step = 2 * grouping_size + num_extra_luts;
luts_array_second_step = new int_radix_lut<Torus>(
streams, params, num_luts_second_step, num_radix_blocks,
allocate_gpu_memory, size_tracker);
// luts for first group inner propagation
for (int lut_id = 0; lut_id < grouping_size - 1; lut_id++) {
auto f_first_grouping_inner_propagation =
[lut_id](Torus propa_cum_sum_block) -> Torus {
uint64_t carry = (propa_cum_sum_block >> lut_id) & 1;
if (carry != 0) {
return 2ull; // Generates Carry
} else {
return 0ull; // Does not generate carry
}
};
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
luts_array_second_step->get_lut(0, lut_id),
luts_array_second_step->get_degree(lut_id),
luts_array_second_step->get_max_degree(lut_id), glwe_dimension,
polynomial_size, message_modulus, carry_modulus,
f_first_grouping_inner_propagation, gpu_memory_allocated);
}
auto f_first_grouping_outer_propagation =
[num_bits_in_block](Torus block) -> Torus {
return (block >> (num_bits_in_block - 1)) & 1;
};
int lut_id = grouping_size - 1;
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
luts_array_second_step->get_lut(0, lut_id),
luts_array_second_step->get_degree(lut_id),
luts_array_second_step->get_max_degree(lut_id), glwe_dimension,
polynomial_size, message_modulus, carry_modulus,
f_first_grouping_outer_propagation, gpu_memory_allocated);
// for other groupings inner propagation
for (int index = 0; index < grouping_size; index++) {
uint32_t lut_id = index + grouping_size;
auto f_other_groupings_inner_propagation =
[index](Torus propa_cum_sum_block) -> Torus {
uint64_t mask = (2 << index) - 1;
if (propa_cum_sum_block >= (2 << index)) {
return 2ull; // Generates
} else if ((propa_cum_sum_block & mask) == mask) {
return 1ull; // Propagate
} else {
return 0ull; // Nothing
}
};
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
luts_array_second_step->get_lut(0, lut_id),
luts_array_second_step->get_degree(lut_id),
luts_array_second_step->get_max_degree(lut_id), glwe_dimension,
polynomial_size, message_modulus, carry_modulus,
f_other_groupings_inner_propagation, gpu_memory_allocated);
}
if (use_sequential_algorithm_to_resolve_group_carries) {
for (int index = 0; index < grouping_size - 1; index++) {
uint32_t lut_id = index + 2 * grouping_size;
auto f_group_propagation = [index, block_modulus,
num_bits_in_block](Torus block) -> Torus {
if (block == (block_modulus - 1)) {
return 0ull;
} else {
return ((UINT64_MAX << index) % (1ull << (num_bits_in_block + 1)));
}
};
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
luts_array_second_step->get_lut(0, lut_id),
luts_array_second_step->get_degree(lut_id),
luts_array_second_step->get_max_degree(lut_id), glwe_dimension,
polynomial_size, message_modulus, carry_modulus,
f_group_propagation, gpu_memory_allocated);
}
} else {
uint32_t lut_id = 2 * grouping_size;
auto f_group_propagation = [block_modulus](Torus block) {
if (block == (block_modulus - 1)) {
return 2ull;
} else {
return UINT64_MAX % (block_modulus * 2ull);
}
};
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
luts_array_second_step->get_lut(0, lut_id),
luts_array_second_step->get_degree(lut_id),
luts_array_second_step->get_max_degree(lut_id), glwe_dimension,
polynomial_size, message_modulus, carry_modulus, f_group_propagation,
gpu_memory_allocated);
}
Torus *h_second_lut_indexes = (Torus *)malloc(lut_indexes_size);
for (int index = 0; index < num_radix_blocks; index++) {
@@ -1854,11 +1941,6 @@ template <typename Torus> struct int_prop_simu_group_carries_memory {
}
}
uint32_t num_luts_second_step = 2 * grouping_size + num_extra_luts;
luts_array_second_step = new int_radix_lut<Torus>(
streams, params, num_luts_second_step, num_radix_blocks,
allocate_gpu_memory, size_tracker);
// copy the indexes to the gpu
Torus *second_lut_indexes = luts_array_second_step->get_lut_indexes(0, 0);
cuda_memcpy_with_size_tracking_async_to_gpu(
@@ -1869,92 +1951,9 @@ template <typename Torus> struct int_prop_simu_group_carries_memory {
scalar_array_cum_sum, h_scalar_array_cum_sum,
num_radix_blocks * sizeof(Torus), streams.stream(0),
streams.gpu_index(0), allocate_gpu_memory);
std::vector<std::function<Torus(Torus)>> lut_funcs;
std::vector<uint32_t> lut_ids;
// luts for first group inner propagation
for (int lut_id = 0; lut_id < grouping_size - 1; lut_id++) {
auto f_first_grouping_inner_propagation =
[lut_id](Torus propa_cum_sum_block) -> Torus {
uint64_t carry = (propa_cum_sum_block >> lut_id) & 1;
if (carry != 0) {
return 2ull; // Generates Carry
} else {
return 0ull; // Does not generate carry
}
};
lut_funcs.push_back(f_first_grouping_inner_propagation);
lut_ids.push_back(lut_id);
}
auto f_first_grouping_outer_propagation =
[num_bits_in_block](Torus block) -> Torus {
return (block >> (num_bits_in_block - 1)) & 1;
};
int lut_id = grouping_size - 1;
lut_funcs.push_back(f_first_grouping_outer_propagation);
lut_ids.push_back(lut_id);
// for other groupings inner propagation
for (int index = 0; index < grouping_size; index++) {
uint32_t lut_id = index + grouping_size;
auto f_other_groupings_inner_propagation =
[index](Torus propa_cum_sum_block) -> Torus {
uint64_t mask = (2 << index) - 1;
if (propa_cum_sum_block >= (2 << index)) {
return 2ull; // Generates
} else if ((propa_cum_sum_block & mask) == mask) {
return 1ull; // Propagate
} else {
return 0ull; // Nothing
}
};
lut_funcs.push_back(f_other_groupings_inner_propagation);
lut_ids.push_back(lut_id);
}
if (use_sequential_algorithm_to_resolve_group_carries) {
for (int index = 0; index < grouping_size - 1; index++) {
uint32_t lut_id = index + 2 * grouping_size;
auto f_group_propagation = [index, block_modulus,
num_bits_in_block](Torus block) -> Torus {
if (block == (block_modulus - 1)) {
return 0ull;
} else {
return ((UINT64_MAX << index) % (1ull << (num_bits_in_block + 1)));
}
};
lut_funcs.push_back(f_group_propagation);
lut_ids.push_back(lut_id);
}
} else {
uint32_t lut_id = 2 * grouping_size;
auto f_group_propagation = [block_modulus](Torus block) {
if (block == (block_modulus - 1)) {
return 2ull;
} else {
return UINT64_MAX % (block_modulus * 2ull);
}
};
lut_funcs.push_back(f_group_propagation);
lut_ids.push_back(lut_id);
}
auto active_streams =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
luts_array_second_step->generate_and_broadcast_lut(
active_streams, lut_ids, lut_funcs, gpu_memory_allocated);
// luts_array_second_step->broadcast_lut(active_streams);
luts_array_second_step->broadcast_lut(active_streams);
if (use_sequential_algorithm_to_resolve_group_carries) {
@@ -2042,28 +2041,12 @@ template <typename Torus> struct int_sc_prop_memory {
uint32_t requested_flag;
bool gpu_memory_allocated;
void setup_message_extract_indices_for_carry_async(CudaStreams streams,
uint32_t num_radix_blocks,
bool allocate_gpu_memory) {
Torus *h_lut_indexes = lut_message_extract->h_lut_indexes;
for (int index = 0; index < num_radix_blocks + 1; index++) {
if (index < num_radix_blocks) {
h_lut_indexes[index] = 0;
} else {
h_lut_indexes[index] = 1;
}
}
cuda_memcpy_with_size_tracking_async_to_gpu(
lut_message_extract->get_lut_indexes(0, 0), h_lut_indexes,
(num_radix_blocks + 1) * sizeof(Torus), streams.stream(0),
streams.gpu_index(0), allocate_gpu_memory);
}
int_sc_prop_memory(CudaStreams streams, int_radix_params params,
uint32_t num_radix_blocks, uint32_t requested_flag_in,
bool allocate_gpu_memory, uint64_t &size_tracker) {
gpu_memory_allocated = allocate_gpu_memory;
this->params = params;
auto glwe_dimension = params.glwe_dimension;
auto polynomial_size = params.polynomial_size;
auto message_modulus = params.message_modulus;
auto carry_modulus = params.carry_modulus;
@@ -2086,6 +2069,24 @@ template <typename Torus> struct int_sc_prop_memory {
streams, params, num_radix_blocks, grouping_size, num_groups,
allocate_gpu_memory, size_tracker);
// Step 3 elements
int num_luts_message_extract =
requested_flag == outputFlag::FLAG_NONE ? 1 : 2;
lut_message_extract = new int_radix_lut<Torus>(
streams, params, num_luts_message_extract, num_radix_blocks + 1,
allocate_gpu_memory, size_tracker);
// lut for the first block in the first grouping
auto f_message_extract = [message_modulus](Torus block) -> Torus {
return (block >> 1) % message_modulus;
};
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
lut_message_extract->get_lut(0, 0), lut_message_extract->get_degree(0),
lut_message_extract->get_max_degree(0), glwe_dimension, polynomial_size,
message_modulus, carry_modulus, f_message_extract,
gpu_memory_allocated);
// This store a single block that with be used to store the overflow or
// carry results
output_flag = new CudaRadixCiphertextFFI;
@@ -2136,30 +2137,22 @@ template <typename Torus> struct int_sc_prop_memory {
return output1 << 3 | output2 << 2;
};
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
lut_overflow_flag_prep->get_lut(0, 0),
lut_overflow_flag_prep->get_degree(0),
lut_overflow_flag_prep->get_max_degree(0), glwe_dimension,
polynomial_size, message_modulus, carry_modulus, f_overflow_fp,
gpu_memory_allocated);
auto active_streams = streams.active_gpu_subset(1, params.pbs_type);
lut_overflow_flag_prep->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {f_overflow_fp}, gpu_memory_allocated);
lut_overflow_flag_prep->broadcast_lut(active_streams);
}
// Step 3 elements
int num_luts_message_extract =
requested_flag == outputFlag::FLAG_NONE ? 1 : 2;
lut_message_extract = new int_radix_lut<Torus>(
streams, params, num_luts_message_extract, num_radix_blocks + 1,
allocate_gpu_memory, size_tracker);
// lut for the first block in the first grouping
auto f_message_extract = [message_modulus](Torus block) -> Torus {
return (block >> 1) % message_modulus;
};
auto active_streams =
streams.active_gpu_subset(num_radix_blocks + 1, params.pbs_type);
// For the final cleanup in case of overflow or carry (it seems that I can)
// It seems that this lut could be apply together with the other one but for
// now we won't do it
switch (requested_flag) {
case outputFlag::FLAG_OVERFLOW: { // Overflow case
if (requested_flag == outputFlag::FLAG_OVERFLOW) { // Overflow case
auto f_overflow_last = [num_radix_blocks,
requested_flag_in](Torus block) -> Torus {
uint32_t position = (num_radix_blocks == 1 &&
@@ -2171,38 +2164,62 @@ template <typename Torus> struct int_sc_prop_memory {
Torus does_overflow_if_carry_is_0 = (block >> 2) & 1;
if (input_carry == outputFlag::FLAG_OVERFLOW) {
return does_overflow_if_carry_is_1;
} else {
return does_overflow_if_carry_is_0;
}
return does_overflow_if_carry_is_0;
};
setup_message_extract_indices_for_carry_async(streams, num_radix_blocks,
allocate_gpu_memory);
lut_message_extract->generate_and_broadcast_lut(
active_streams, {0, 1}, {f_message_extract, f_overflow_last},
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
lut_message_extract->get_lut(0, 1),
lut_message_extract->get_degree(1),
lut_message_extract->get_max_degree(1), glwe_dimension,
polynomial_size, message_modulus, carry_modulus, f_overflow_last,
gpu_memory_allocated);
break;
}
case outputFlag::FLAG_CARRY: { // Carry case
setup_message_extract_indices_for_carry_async(streams, num_radix_blocks,
allocate_gpu_memory);
Torus *h_lut_indexes = lut_message_extract->h_lut_indexes;
for (int index = 0; index < num_radix_blocks + 1; index++) {
if (index < num_radix_blocks) {
h_lut_indexes[index] = 0;
} else {
h_lut_indexes[index] = 1;
}
}
cuda_memcpy_with_size_tracking_async_to_gpu(
lut_message_extract->get_lut_indexes(0, 0), h_lut_indexes,
(num_radix_blocks + 1) * sizeof(Torus), streams.stream(0),
streams.gpu_index(0), allocate_gpu_memory);
}
if (requested_flag == outputFlag::FLAG_CARRY) { // Carry case
auto f_carry_last = [](Torus block) -> Torus {
return ((block >> 2) & 1);
};
lut_message_extract->generate_and_broadcast_lut(
active_streams, {0, 1}, {f_message_extract, f_carry_last},
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
lut_message_extract->get_lut(0, 1),
lut_message_extract->get_degree(1),
lut_message_extract->get_max_degree(1), glwe_dimension,
polynomial_size, message_modulus, carry_modulus, f_carry_last,
gpu_memory_allocated);
break;
}
default:
lut_message_extract->generate_and_broadcast_lut(
active_streams, {0}, {f_message_extract}, gpu_memory_allocated);
break;
}
// lut_message_extract->broadcast_lut(active_streams);
Torus *h_lut_indexes = lut_message_extract->h_lut_indexes;
for (int index = 0; index < num_radix_blocks + 1; index++) {
if (index < num_radix_blocks) {
h_lut_indexes[index] = 0;
} else {
h_lut_indexes[index] = 1;
}
}
cuda_memcpy_with_size_tracking_async_to_gpu(
lut_message_extract->get_lut_indexes(0, 0), h_lut_indexes,
(num_radix_blocks + 1) * sizeof(Torus), streams.stream(0),
streams.gpu_index(0), allocate_gpu_memory);
}
auto active_streams =
streams.active_gpu_subset(num_radix_blocks + 1, params.pbs_type);
lut_message_extract->broadcast_lut(active_streams);
};
void release(CudaStreams streams) {
@@ -2500,11 +2517,16 @@ template <typename Torus> struct int_borrow_prop_memory {
return (block >> 1) % message_modulus;
};
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
lut_message_extract->get_lut(0, 0), lut_message_extract->get_degree(0),
lut_message_extract->get_max_degree(0), glwe_dimension, polynomial_size,
message_modulus, carry_modulus, f_message_extract,
gpu_memory_allocated);
active_streams =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
lut_message_extract->generate_and_broadcast_lut(
active_streams, {0}, {f_message_extract}, gpu_memory_allocated);
lut_message_extract->broadcast_lut(active_streams);
if (compute_overflow) {
lut_borrow_flag =
@@ -2515,8 +2537,12 @@ template <typename Torus> struct int_borrow_prop_memory {
return ((block >> 2) & 1);
};
lut_borrow_flag->generate_and_broadcast_lut(
active_streams, {0}, {f_borrow_flag}, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
lut_borrow_flag->get_lut(0, 0), lut_borrow_flag->get_degree(0),
lut_borrow_flag->get_max_degree(0), glwe_dimension, polynomial_size,
message_modulus, carry_modulus, f_borrow_flag, gpu_memory_allocated);
lut_borrow_flag->broadcast_lut(active_streams);
}
active_streams =

View File

@@ -37,14 +37,17 @@ template <typename Torus> struct int_mul_memory {
zero_out_predicate_lut =
new int_radix_lut<Torus>(streams, params, 1, num_radix_blocks,
allocate_gpu_memory, size_tracker);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
zero_out_predicate_lut->get_lut(0, 0),
zero_out_predicate_lut->get_degree(0),
zero_out_predicate_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
zero_out_predicate_lut_f, gpu_memory_allocated);
auto active_streams =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
zero_out_predicate_lut->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {zero_out_predicate_lut_f},
gpu_memory_allocated);
// zero_out_predicate_lut->broadcast_lut(active_streams);
zero_out_predicate_lut->broadcast_lut(active_streams);
zero_out_mem = new int_zero_out_if_buffer<Torus>(
streams, params, num_radix_blocks, allocate_gpu_memory, size_tracker);
@@ -52,7 +55,10 @@ template <typename Torus> struct int_mul_memory {
return;
}
auto glwe_dimension = params.glwe_dimension;
auto polynomial_size = params.polynomial_size;
auto message_modulus = params.message_modulus;
auto carry_modulus = params.carry_modulus;
// 'vector_result_lsb' contains blocks from all possible shifts of
// radix_lwe_left excluding zero ciphertext blocks
@@ -96,6 +102,18 @@ template <typename Torus> struct int_mul_memory {
return (x * y) / message_modulus;
};
// generate accumulators
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0), lsb_acc,
luts_array->get_degree(0), luts_array->get_max_degree(0),
glwe_dimension, polynomial_size, message_modulus, carry_modulus,
lut_f_lsb, gpu_memory_allocated);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0), msb_acc,
luts_array->get_degree(1), luts_array->get_max_degree(1),
glwe_dimension, polynomial_size, message_modulus, carry_modulus,
lut_f_msb, gpu_memory_allocated);
// lut_indexes_vec for luts_array should be reinitialized
// first lsb_vector_block_count value should reference to lsb_acc
// last msb_vector_block_count values should reference to msb_acc
@@ -105,12 +123,9 @@ template <typename Torus> struct int_mul_memory {
streams.stream(0), streams.gpu_index(0),
luts_array->get_lut_indexes(0, lsb_vector_block_count), 1,
msb_vector_block_count);
auto active_streams =
streams.active_gpu_subset(total_block_count, params.pbs_type);
luts_array->generate_and_broadcast_bivariate_lut(
active_streams, {0, 1}, {lut_f_lsb, lut_f_msb}, gpu_memory_allocated);
luts_array->broadcast_lut(active_streams);
// create memory object for sum ciphertexts
sum_ciphertexts_mem = new int_sum_ciphertexts_vec_memory<Torus>(
streams, params, num_radix_blocks, 2 * num_radix_blocks,

View File

@@ -85,11 +85,15 @@ template <typename Torus> struct int_logical_scalar_shift_buffer {
}
// right shift
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
cur_lut_bivariate->get_lut(0, 0), cur_lut_bivariate->get_degree(0),
cur_lut_bivariate->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
shift_lut_f, gpu_memory_allocated);
auto active_streams =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
cur_lut_bivariate->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {shift_lut_f}, gpu_memory_allocated);
cur_lut_bivariate->broadcast_lut(active_streams);
lut_buffers_bivariate.push_back(cur_lut_bivariate);
}
@@ -168,10 +172,16 @@ template <typename Torus> struct int_logical_scalar_shift_buffer {
}
// right shift
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
cur_lut_bivariate->get_lut(0, 0), cur_lut_bivariate->get_degree(0),
cur_lut_bivariate->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
shift_lut_f, gpu_memory_allocated);
auto active_streams =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
cur_lut_bivariate->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {shift_lut_f}, gpu_memory_allocated);
cur_lut_bivariate->broadcast_lut(active_streams);
lut_buffers_bivariate.push_back(cur_lut_bivariate);
}
}
@@ -261,11 +271,16 @@ template <typename Torus> struct int_arithmetic_scalar_shift_buffer {
return shifted | padding;
};
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
shift_last_block_lut_univariate->get_lut(0, 0),
shift_last_block_lut_univariate->get_degree(0),
shift_last_block_lut_univariate->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, last_block_lut_f, gpu_memory_allocated);
auto active_streams_shift_last =
streams.active_gpu_subset(1, params.pbs_type);
shift_last_block_lut_univariate->generate_and_broadcast_lut(
active_streams_shift_last, {0}, {last_block_lut_f},
gpu_memory_allocated);
shift_last_block_lut_univariate->broadcast_lut(active_streams_shift_last);
lut_buffers_univariate.push_back(shift_last_block_lut_univariate);
}
@@ -283,8 +298,15 @@ template <typename Torus> struct int_arithmetic_scalar_shift_buffer {
return (params.message_modulus - 1) * x_sign_bit;
};
padding_block_lut_univariate->generate_and_broadcast_lut(
active_streams, {0}, {padding_block_lut_f}, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
padding_block_lut_univariate->get_lut(0, 0),
padding_block_lut_univariate->get_degree(0),
padding_block_lut_univariate->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
padding_block_lut_f, gpu_memory_allocated);
// auto active_streams = streams.active_gpu_subset(1, params.pbs_type);
padding_block_lut_univariate->broadcast_lut(active_streams);
lut_buffers_univariate.push_back(padding_block_lut_univariate);
@@ -317,11 +339,16 @@ template <typename Torus> struct int_arithmetic_scalar_shift_buffer {
return message_of_current_block + carry_of_previous_block;
};
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
shift_blocks_lut_bivariate->get_lut(0, 0),
shift_blocks_lut_bivariate->get_degree(0),
shift_blocks_lut_bivariate->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
blocks_lut_f, gpu_memory_allocated);
auto active_streams_shift_blocks =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
shift_blocks_lut_bivariate->generate_and_broadcast_bivariate_lut(
active_streams_shift_blocks, {0}, {blocks_lut_f},
gpu_memory_allocated);
shift_blocks_lut_bivariate->broadcast_lut(active_streams_shift_blocks);
lut_buffers_bivariate.push_back(shift_blocks_lut_bivariate);
}

View File

@@ -113,21 +113,27 @@ template <typename Torus> struct int_shift_and_rotate_buffer {
else
return current_bit;
};
;
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), mux_lut->get_lut(0, 0),
mux_lut->get_degree(0), mux_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, mux_lut_f, gpu_memory_allocated);
auto active_gpu_count_mux = streams.active_gpu_subset(
bits_per_block * num_radix_blocks, params.pbs_type);
mux_lut->generate_and_broadcast_lut(active_gpu_count_mux, {0}, {mux_lut_f},
gpu_memory_allocated);
mux_lut->broadcast_lut(active_gpu_count_mux);
auto cleaning_lut_f = [params](Torus x) -> Torus {
return x % params.message_modulus;
};
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), cleaning_lut->get_lut(0, 0),
cleaning_lut->get_degree(0), cleaning_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, cleaning_lut_f, gpu_memory_allocated);
auto active_gpu_count_cleaning =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
cleaning_lut->generate_and_broadcast_lut(
active_gpu_count_cleaning, {0}, {cleaning_lut_f}, gpu_memory_allocated);
cleaning_lut->broadcast_lut(active_gpu_count_cleaning);
}
void release(CudaStreams streams) {

View File

@@ -74,26 +74,45 @@ template <typename Torus> struct int_overflowing_sub_memory {
luts_array, size_tracker,
allocate_gpu_memory, size_tracker);
auto lut_does_block_generate_carry = luts_array->get_lut(0, 0);
auto lut_does_block_generate_or_propagate = luts_array->get_lut(0, 1);
// generate luts (aka accumulators)
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), lut_does_block_generate_carry,
luts_array->get_degree(0), luts_array->get_max_degree(0),
glwe_dimension, polynomial_size, message_modulus, carry_modulus,
f_lut_does_block_generate_carry, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
lut_does_block_generate_or_propagate, luts_array->get_degree(1),
luts_array->get_max_degree(1), glwe_dimension, polynomial_size,
message_modulus, carry_modulus, f_lut_does_block_generate_or_propagate,
gpu_memory_allocated);
if (allocate_gpu_memory)
cuda_set_value_async<Torus>(streams.stream(0), streams.gpu_index(0),
luts_array->get_lut_indexes(0, 1), 1,
num_radix_blocks - 1);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
luts_borrow_propagation_sum->get_lut(0, 0),
luts_borrow_propagation_sum->get_degree(0),
luts_borrow_propagation_sum->get_max_degree(0), glwe_dimension,
polynomial_size, message_modulus, carry_modulus,
f_luts_borrow_propagation_sum, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), message_acc->get_lut(0, 0),
message_acc->get_degree(0), message_acc->get_max_degree(0),
glwe_dimension, polynomial_size, message_modulus, carry_modulus,
f_message_acc, gpu_memory_allocated);
auto active_streams =
streams.active_gpu_subset(num_radix_blocks, params.pbs_type);
luts_borrow_propagation_sum->generate_and_broadcast_bivariate_lut(
active_streams, {0}, {f_luts_borrow_propagation_sum},
gpu_memory_allocated);
luts_array->generate_and_broadcast_lut(
active_streams, {0, 1},
{f_lut_does_block_generate_carry,
f_lut_does_block_generate_or_propagate},
gpu_memory_allocated);
// generate luts (aka accumulators)
message_acc->generate_and_broadcast_lut(
active_streams, {0}, {f_message_acc}, gpu_memory_allocated);
luts_array->broadcast_lut(active_streams);
luts_borrow_propagation_sum->broadcast_lut(active_streams);
message_acc->broadcast_lut(active_streams);
}
void release(CudaStreams streams) {

View File

@@ -298,10 +298,14 @@ template <typename Torus> struct int_aggregate_one_hot_buffer {
int_radix_lut<Torus> *lut = new int_radix_lut<Torus>(
streams, params, 1, num_blocks, allocate_gpu_memory, size_tracker);
lut->generate_and_broadcast_lut(
streams.active_gpu_subset(num_blocks, params.pbs_type), {0}, {id_fn},
allocate_gpu_memory);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0), lut->get_lut(0, 0),
lut->get_degree(0), lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
id_fn, allocate_gpu_memory);
lut->broadcast_lut(
streams.active_gpu_subset(num_blocks, params.pbs_type));
this->stream_identity_luts[i] = lut;
}
@@ -314,17 +318,27 @@ template <typename Torus> struct int_aggregate_one_hot_buffer {
this->message_extract_lut = new int_radix_lut<Torus>(
streams, params, 1, num_blocks, allocate_gpu_memory, size_tracker);
this->message_extract_lut->generate_and_broadcast_lut(
streams.active_gpu_subset(num_blocks, params.pbs_type), {0}, {msg_fn},
allocate_gpu_memory);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
this->message_extract_lut->get_lut(0, 0),
this->message_extract_lut->get_degree(0),
this->message_extract_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
msg_fn, allocate_gpu_memory);
this->message_extract_lut->broadcast_lut(
streams.active_gpu_subset(num_blocks, params.pbs_type));
this->carry_extract_lut = new int_radix_lut<Torus>(
streams, params, 1, num_blocks, allocate_gpu_memory, size_tracker);
this->carry_extract_lut->generate_and_broadcast_lut(
streams.active_gpu_subset(num_blocks, params.pbs_type), {0}, {carry_fn},
allocate_gpu_memory);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
this->carry_extract_lut->get_lut(0, 0),
this->carry_extract_lut->get_degree(0),
this->carry_extract_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
carry_fn, allocate_gpu_memory);
this->carry_extract_lut->broadcast_lut(
streams.active_gpu_subset(num_blocks, params.pbs_type));
this->partial_aggregated_vectors =
new CudaRadixCiphertextFFI *[num_streams];
@@ -1171,9 +1185,15 @@ template <typename Torus> struct int_unchecked_first_index_of_clear_buffer {
this->prefix_sum_lut = new int_radix_lut<Torus>(
streams, params, 2, num_inputs, allocate_gpu_memory, size_tracker);
this->prefix_sum_lut->generate_and_broadcast_bivariate_lut(
streams.active_gpu_subset(num_inputs, params.pbs_type), {0},
{prefix_sum_fn}, allocate_gpu_memory);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
this->prefix_sum_lut->get_lut(0, 0),
this->prefix_sum_lut->get_degree(0),
this->prefix_sum_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
prefix_sum_fn, allocate_gpu_memory);
this->prefix_sum_lut->broadcast_lut(
streams.active_gpu_subset(num_inputs, params.pbs_type));
auto cleanup_fn = [ALREADY_SEEN, params](Torus x) -> Torus {
Torus val = x % params.message_modulus;
@@ -1183,9 +1203,14 @@ template <typename Torus> struct int_unchecked_first_index_of_clear_buffer {
};
this->cleanup_lut = new int_radix_lut<Torus>(
streams, params, 1, num_inputs, allocate_gpu_memory, size_tracker);
this->cleanup_lut->generate_and_broadcast_lut(
streams.active_gpu_subset(num_inputs, params.pbs_type), {0},
{cleanup_fn}, allocate_gpu_memory);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
this->cleanup_lut->get_lut(0, 0), this->cleanup_lut->get_degree(0),
this->cleanup_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
cleanup_fn, allocate_gpu_memory);
this->cleanup_lut->broadcast_lut(
streams.active_gpu_subset(num_inputs, params.pbs_type));
}
void release(CudaStreams streams) {
@@ -1351,9 +1376,15 @@ template <typename Torus> struct int_unchecked_first_index_of_buffer {
this->prefix_sum_lut = new int_radix_lut<Torus>(
streams, params, 2, num_inputs, allocate_gpu_memory, size_tracker);
this->prefix_sum_lut->generate_and_broadcast_bivariate_lut(
streams.active_gpu_subset(num_inputs, params.pbs_type), {0},
{prefix_sum_fn}, allocate_gpu_memory);
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0),
this->prefix_sum_lut->get_lut(0, 0),
this->prefix_sum_lut->get_degree(0),
this->prefix_sum_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
prefix_sum_fn, allocate_gpu_memory);
this->prefix_sum_lut->broadcast_lut(
streams.active_gpu_subset(num_inputs, params.pbs_type));
auto cleanup_fn = [ALREADY_SEEN, params](Torus x) -> Torus {
Torus val = x % params.message_modulus;
@@ -1363,9 +1394,14 @@ template <typename Torus> struct int_unchecked_first_index_of_buffer {
};
this->cleanup_lut = new int_radix_lut<Torus>(
streams, params, 1, num_inputs, allocate_gpu_memory, size_tracker);
this->cleanup_lut->generate_and_broadcast_lut(
streams.active_gpu_subset(num_inputs, params.pbs_type), {0},
{cleanup_fn}, allocate_gpu_memory);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
this->cleanup_lut->get_lut(0, 0), this->cleanup_lut->get_degree(0),
this->cleanup_lut->get_max_degree(0), params.glwe_dimension,
params.polynomial_size, params.message_modulus, params.carry_modulus,
cleanup_fn, allocate_gpu_memory);
this->cleanup_lut->broadcast_lut(
streams.active_gpu_subset(num_inputs, params.pbs_type));
}
void release(CudaStreams streams) {

View File

@@ -30,10 +30,15 @@ template <typename Torus> struct int_trivium_lut_buffers {
std::function<Torus(Torus, Torus)> and_lambda =
[](Torus a, Torus b) -> Torus { return (a & 1) & (b & 1); };
generate_device_accumulator_bivariate<Torus>(
streams.stream(0), streams.gpu_index(0), this->and_lut->get_lut(0, 0),
this->and_lut->get_degree(0), this->and_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, and_lambda, allocate_gpu_memory);
auto active_streams_and =
streams.active_gpu_subset(total_lut_ops, params.pbs_type);
this->and_lut->generate_and_broadcast_bivariate_lut(
active_streams_and, {0}, {and_lambda}, allocate_gpu_memory);
this->and_lut->broadcast_lut(active_streams_and);
this->and_lut->setup_gemm_batch_ks_temp_buffers(size_tracker);
uint32_t total_flush_ops = num_trivium_inputs * BATCH_SIZE * 4;
@@ -45,10 +50,15 @@ template <typename Torus> struct int_trivium_lut_buffers {
return x & 1;
};
generate_device_accumulator(
streams.stream(0), streams.gpu_index(0), this->flush_lut->get_lut(0, 0),
this->flush_lut->get_degree(0), this->flush_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, flush_lambda, allocate_gpu_memory);
auto active_streams_flush =
streams.active_gpu_subset(total_flush_ops, params.pbs_type);
this->flush_lut->generate_and_broadcast_lut(
active_streams_flush, {0}, {flush_lambda}, allocate_gpu_memory);
this->flush_lut->broadcast_lut(active_streams_flush);
this->flush_lut->setup_gemm_batch_ks_temp_buffers(size_tracker);
}

View File

@@ -174,6 +174,40 @@ template <typename Torus> struct zk_expand_mem {
message_and_carry_extract_luts = new int_radix_lut<Torus>(
streams, params, 4, 2 * num_lwes, allocate_gpu_memory, size_tracker);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
message_and_carry_extract_luts->get_lut(0, 0),
message_and_carry_extract_luts->get_degree(0),
message_and_carry_extract_luts->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, message_extract_lut_f, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
message_and_carry_extract_luts->get_lut(0, 1),
message_and_carry_extract_luts->get_degree(1),
message_and_carry_extract_luts->get_max_degree(1),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, carry_extract_lut_f, gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
message_and_carry_extract_luts->get_lut(0, 2),
message_and_carry_extract_luts->get_degree(2),
message_and_carry_extract_luts->get_max_degree(2),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, message_extract_and_sanitize_bool_lut_f,
gpu_memory_allocated);
generate_device_accumulator<Torus>(
streams.stream(0), streams.gpu_index(0),
message_and_carry_extract_luts->get_lut(0, 3),
message_and_carry_extract_luts->get_degree(3),
message_and_carry_extract_luts->get_max_degree(3),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, carry_extract_and_sanitize_bool_lut_f,
gpu_memory_allocated);
// We are always packing two LWEs. We just need to be sure we have enough
// space in the carry part to store a message of the same size as is in the
// message part.
@@ -258,13 +292,7 @@ template <typename Torus> struct zk_expand_mem {
auto active_streams =
streams.active_gpu_subset(2 * num_lwes, params.pbs_type);
message_and_carry_extract_luts->generate_and_broadcast_lut(
active_streams, {0, 1, 2, 3},
{message_extract_lut_f, carry_extract_lut_f,
message_extract_and_sanitize_bool_lut_f,
carry_extract_and_sanitize_bool_lut_f},
gpu_memory_allocated);
message_and_carry_extract_luts->broadcast_lut(active_streams);
message_and_carry_extract_luts->allocate_lwe_vector_for_non_trivial_indexes(
active_streams, 2 * num_lwes, size_tracker, allocate_gpu_memory);

View File

@@ -136,9 +136,9 @@ host_integer_compress(CudaStreams streams,
}
// Modulus switch
int size = num_glwes * compression_params.glwe_dimension *
compression_params.polynomial_size +
glwe_array_out->total_lwe_bodies_count;
uint32_t size = num_glwes * compression_params.glwe_dimension *
compression_params.polynomial_size +
glwe_array_out->total_lwe_bodies_count;
host_modulus_switch_inplace<Torus>(streams.stream(0), streams.gpu_index(0),
tmp_glwe_array_out, size,

View File

@@ -1067,85 +1067,6 @@ void generate_device_accumulator_bivariate(
POP_RANGE()
}
template <typename Torus> struct int_lut_cache {
int_lut_cache() {}
Torus *get_cached_univariate_lut(std::function<Torus(Torus)> &f, uint64_t *degree,
uint64_t *max_degree, uint32_t glwe_dimension,
uint32_t polynomial_size,
uint32_t input_message_modulus,
uint32_t input_carry_modulus,
uint32_t output_message_modulus,
uint32_t output_carry_modulus) {
/*__int128_t f_hash = 0;
uint32_t bits_per_lut_val = 5;
uint32_t input_modulus_sup = input_message_modulus * input_carry_modulus;
for (uint32_t i = 0; i < input_modulus_sup; ++i) {
Torus f_eval = f(i);
GPU_ASSERT(f_eval < (1 << bits_per_lut_val),
"LUT value expected bitwidth overflow");
f_hash |= f_eval;
f_hash <<= bits_per_lut_val;
}
std::lock_guard cache_lock(_mutex);
if (_lut_cache.find(f_hash) != _lut_cache.end()) {
lut_ptr &ptr = _lut_cache[f_hash];
GPU_ASSERT(ptr.output_message_modulus == output_message_modulus,
"Error modulus");
GPU_ASSERT(ptr.input_message_modulus == input_message_modulus,
"Error modulus");
GPU_ASSERT(ptr.glwe_dimension == glwe_dimension, "Error modulus");
*max_degree = ptr.max_degree;
*degree = ptr.degree;
return ptr.ptr;
}*/
// host lut
Torus *h_lut =
(Torus *)malloc((glwe_dimension + 1) * polynomial_size * sizeof(Torus));
*max_degree = input_message_modulus * input_carry_modulus - 1;
*degree = generate_lookup_table_with_encoding<Torus>(
h_lut, glwe_dimension, polynomial_size, input_message_modulus,
input_carry_modulus, output_message_modulus, output_carry_modulus, f);
/*lut_ptr new_ptr = {h_lut,
glwe_dimension,
input_message_modulus,
input_carry_modulus,
output_message_modulus,
output_carry_modulus,
*max_degree,
*degree};*/
//_lut_cache[f_hash] = new_ptr;
return h_lut;
}
~int_lut_cache() {
std::lock_guard cache_lock(_mutex);
for (auto v : _lut_cache) {
free(v.second.ptr);
}
_lut_cache.clear();
}
private:
struct lut_ptr {
Torus *ptr;
uint32_t glwe_dimension;
uint32_t input_message_modulus;
uint32_t input_carry_modulus;
uint32_t output_message_modulus;
uint32_t output_carry_modulus;
uint64_t max_degree;
uint64_t degree;
};
std::map<__int128_t, lut_ptr> _lut_cache;
std::mutex _mutex;
};
static int_lut_cache<uint64_t> g_LutCache64;
/*
* generate bivariate accumulator with factor scaling for device pointer
* v_stream - cuda stream
@@ -1177,8 +1098,8 @@ void generate_device_accumulator_bivariate_with_factor(
(glwe_dimension + 1) * polynomial_size * sizeof(Torus), stream, gpu_index,
gpu_memory_allocated);
// cuda_synchronize_stream(stream, gpu_index);
// free(h_lut);
cuda_synchronize_stream(stream, gpu_index);
free(h_lut);
}
/*
* generate bivariate accumulator for device pointer
@@ -1224,36 +1145,23 @@ void generate_device_accumulator_with_encoding(
uint32_t output_message_modulus, uint32_t output_carry_modulus,
std::function<Torus(Torus)> f, bool gpu_memory_allocated) {
static constexpr auto is_u64 = std::is_same_v<Torus, uint64_t>;
Torus *h_lut = nullptr;
// host lut
if constexpr (is_u64) {
h_lut = g_LutCache64.get_cached_univariate_lut(
f, degree, max_degree, glwe_dimension, polynomial_size,
input_message_modulus, input_carry_modulus, output_message_modulus,
output_carry_modulus);
} else {
h_lut =
(Torus *)malloc((glwe_dimension + 1) * polynomial_size * sizeof(Torus));
Torus *h_lut =
(Torus *)malloc((glwe_dimension + 1) * polynomial_size * sizeof(Torus));
*max_degree = input_message_modulus * input_carry_modulus - 1;
// fill accumulator
*degree = generate_lookup_table_with_encoding<Torus>(
h_lut, glwe_dimension, polynomial_size, input_message_modulus,
input_carry_modulus, output_message_modulus, output_carry_modulus, f);
*max_degree = input_message_modulus * input_carry_modulus - 1;
// fill accumulator
*degree = generate_lookup_table_with_encoding<Torus>(
h_lut, glwe_dimension, polynomial_size, input_message_modulus,
input_carry_modulus, output_message_modulus, output_carry_modulus, f);
}
/*
// copy host lut and lut_indexes_vec to device
cuda_memcpy_with_size_tracking_async_to_gpu(
acc, h_lut, (glwe_dimension + 1) * polynomial_size * sizeof(Torus),
stream, gpu_index, gpu_memory_allocated);
*/
if (!std::is_same_v<Torus, uint64_t>) {
cuda_synchronize_stream(stream, gpu_index);
free(h_lut);
}
cuda_synchronize_stream(stream, gpu_index);
free(h_lut);
}
template <typename Torus>
void generate_device_accumulator_with_encoding_with_cpu_prealloc(
cudaStream_t stream, uint32_t gpu_index, Torus *acc, uint64_t *degree,
@@ -1356,8 +1264,8 @@ void generate_many_lut_device_accumulator(
acc, h_lut, (glwe_dimension + 1) * polynomial_size * sizeof(Torus),
stream, gpu_index, gpu_memory_allocated);
//cuda_synchronize_stream(stream, gpu_index);
//free(h_lut);
cuda_synchronize_stream(stream, gpu_index);
free(h_lut);
POP_RANGE()
}

View File

@@ -75,7 +75,7 @@ Other optional configuration knobs are available:
* `--freq-hz`, `--register`, `isc-depth`: These knobs are used to override some parameters on the flight. They are useful for quick exploration.
* `--dump-out`, `--dump-reg`: Use for RTL stimuli generation and debug
* `--report-out`, `report-trace`: Use for detailed analysis of the performances report
* `--nops`: Disable tfhe-rs computation. Obsviously led to incorrect behavior but accurate performance estimation.
* `--nops`: Disable tfhe-rs computation. Obviously led to incorrect behavior but accurate performance estimation.
* `--log-out`: Write trace message in the given file instead of stdio.
On top of that `tfhe-hpu-mockup` could generate a detailed set of trace points at runtime to help during the debug/exploration phase (e.g. When writing new Hpu firmware).

View File

@@ -872,35 +872,35 @@ impl HpuSim {
impl HpuSim {
fn dump_op_reg(&self, op: &hpu_asm::DOp) {
if self.options.dump_out.is_some() && self.options.dump_reg {
let dump_out = self.options.dump_out.as_ref().unwrap();
if self.options.dump_reg {
if let Some(dump_out) = &self.options.dump_out {
// Dump register value
let regid = match op {
hpu_asm::DOp::LD(op_impl) => op_impl.0.rid.0 as usize,
hpu_asm::DOp::ST(op_impl) => op_impl.0.rid.0 as usize,
hpu_asm::DOp::ADDS(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::SUBS(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::SSUB(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::MULS(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::ADD(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::SUB(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::MAC(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML2(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML4(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML8(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_F(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML2_F(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML4_F(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML8_F(op_impl) => op_impl.0.dst_rid.0 as usize,
_ => return,
};
let regf = self.regfile[regid].as_view();
// Dump register value
let regid = match op {
hpu_asm::DOp::LD(op_impl) => op_impl.0.rid.0 as usize,
hpu_asm::DOp::ST(op_impl) => op_impl.0.rid.0 as usize,
hpu_asm::DOp::ADDS(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::SUBS(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::SSUB(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::MULS(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::ADD(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::SUB(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::MAC(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML2(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML4(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML8(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_F(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML2_F(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML4_F(op_impl) => op_impl.0.dst_rid.0 as usize,
hpu_asm::DOp::PBS_ML8_F(op_impl) => op_impl.0.dst_rid.0 as usize,
_ => return,
};
let regf = self.regfile[regid].as_view();
// Create base-path
let base_path = format!("{}/blwe/run/blwe_isc{}_reg", dump_out, self.pc,);
self.dump_regf(regf, &base_path);
// Create base-path
let base_path = format!("{}/blwe/run/blwe_isc{}_reg", dump_out, self.pc,);
self.dump_regf(regf, &base_path);
}
}
}

View File

@@ -46,10 +46,11 @@ impl MockupOptions {
}
}
pub fn report_trace(&self, iop: hpu_asm::AsmIOpcode) -> Option<File> {
if self.report_out.is_some() && self.report_trace {
let report_out = &self.report_out.as_ref().unwrap();
let iop_file = format!("{report_out}/{iop}.json");
Some(Self::open_wr_file(&iop_file))
if self.report_trace {
self.report_out.as_ref().map(|report_out| {
let iop_file = format!("{report_out}/{iop}.json");
Self::open_wr_file(&iop_file)
})
} else {
None
}

View File

@@ -1 +1 @@
nightly-2025-11-19
nightly-2026-01-14

View File

@@ -37,7 +37,7 @@ if [[ "${RUN_VALGRIND}" == "1" ]]; then
# Since, when output is directed to a file, nextest outputs a list of `<executable name> <test name>` the `grep -o '[^ ]\+$'` filter
# will keep only the test name and the `tfhe` executable is assumed. To sanitize tests from another
# executable changes might be needed
TESTS_TO_RUN=$(sed -e $'s/\x1b\[[0-9;]*m//g' < /tmp/test_list.txt | grep -E 'high_level_api::.*gpu.*' | grep -v 'array' | grep -v 'flip' | grep -o '[^ ]\+$')
TESTS_TO_RUN=$(sed -e $'s/\x1b\[[0-9;]*m//g' < /tmp/test_list.txt | grep -E 'high_level_api::.*gpu.*' | grep -v 'test_uniformity' | grep -v 'array' | grep -v 'flip' | grep -o '[^ ]\+$')
# Build the tests but don't run them
RUSTFLAGS="$RUSTFLAGS" cargo test --no-run --profile "${CARGO_PROFILE}" \
@@ -64,7 +64,7 @@ if [[ "${RUN_COMPUTE_SANITIZER}" == "1" ]]; then
# Since, when output is directed to a file, nextest outputs a list of `<executable name> <test name>` the `grep -o '[^ ]\+$'` filter
# will keep only the test name and the `tfhe` executable is assumed. To sanitize tests from another
# executable changes might be needed
TESTS_TO_RUN=$(sed -e $'s/\x1b\[[0-9;]*m//g' < /tmp/test_list.txt | grep -E 'high_level_api::.*gpu.*|core_crypto::.*gpu.*' | grep -v 'array' | grep -v 'modulus_switch' | grep -v '3_3' | grep -v 'noise_distribution' | grep -v 'flip' | grep -o '[^ ]\+$')
TESTS_TO_RUN=$(sed -e $'s/\x1b\[[0-9;]*m//g' < /tmp/test_list.txt | grep -E 'high_level_api::.*gpu.*|core_crypto::.*gpu.*' | grep -v 'array' | grep -v 'modulus_switch' | grep -v '3_3' | grep -v 'noise_distribution' | grep -v 'flip' | grep -v 'test_uniformity' | grep -o '[^ ]\+$')
# Build the tests but don't run them
RUSTFLAGS="$RUSTFLAGS" cargo test --no-run --profile "${CARGO_PROFILE}" \
--features=integer,internal-keycache,gpu,zk-pok -p tfhe

View File

@@ -3,21 +3,23 @@
set -e
function usage() {
echo "$0: integer test runner"
echo
echo "--help Print this message"
echo "--rust-toolchain The toolchain to run the tests with default: stable"
echo "--multi-bit Run multi-bit tests only: default off"
echo "--unsigned-only Run only unsigned integer tests, by default both signed and unsigned tests are run"
echo "--signed-only Run only signed integer tests, by default both signed and unsigned tests are run"
echo "--nightly-tests Run integer tests configured for nightly runs (3_3 params)"
echo "--fast-tests Run integer set but skip a subset of longer tests"
echo "--long-tests Run only long run integer tests"
echo "--cargo-profile The cargo profile used to build tests"
echo "--backend Backend to use with tfhe-rs"
echo "--avx512-support Set to ON to enable avx512"
echo "--tfhe-package The package spec like tfhe@0.4.2, default=tfhe"
echo
echo "$0: integer test runner"
echo
echo "--help Print this message"
echo "--no-run Does not run the tests, but prints which tests would be ran (except doctests)"
echo "--rust-toolchain The toolchain to run the tests with default: stable"
echo "--multi-bit Run multi-bit tests only: default off"
echo "--unsigned-only Run only unsigned integer tests, by default both signed and unsigned tests are run"
echo "--signed-only Run only signed integer tests, by default both signed and unsigned tests are run"
echo "--run-prod-only Run only the tests using the prod parameters"
echo "--nightly-tests Run integer tests configured for nightly runs (3_3 params)"
echo "--fast-tests Run integer set but skip a subset of longer tests"
echo "--long-tests Run only long run integer tests"
echo "--cargo-profile The cargo profile used to build tests"
echo "--backend Backend to use with tfhe-rs"
echo "--avx512-support Set to ON to enable avx512"
echo "--tfhe-package The package spec like tfhe@0.4.2, default=tfhe"
echo
}
RUST_TOOLCHAIN=""
@@ -33,87 +35,96 @@ backend="cpu"
gpu_feature=""
avx512_feature=""
tfhe_package="tfhe"
prod_param_argument=
no_run=false
while [ -n "$1" ]
do
case "$1" in
"--help" | "-h" )
usage
exit 0
;;
while [ -n "$1" ]; do
case "$1" in
"--help" | "-h")
usage
exit 0
;;
"--rust-toolchain" )
shift
RUST_TOOLCHAIN="$1"
;;
"--no-run")
no_run=true
;;
"--multi-bit" )
multi_bit_argument=--multi-bit
;;
"--run-prod-only")
prod_param_argument="--run-prod-only"
;;
"--unsigned-only" )
sign_argument=--unsigned-only
;;
"--rust-toolchain")
shift
RUST_TOOLCHAIN="$1"
;;
"--signed-only" )
sign_argument=--signed-only
;;
"--multi-bit")
multi_bit_argument=--multi-bit
;;
"--cargo-profile" )
shift
cargo_profile="$1"
;;
"--unsigned-only")
sign_argument=--unsigned-only
;;
"--backend" )
shift
backend="$1"
;;
"--avx512-support" )
shift
if [[ "$1" == "ON" ]]; then
avx512_feature=avx512
fi
;;
"--signed-only")
sign_argument=--signed-only
;;
"--tfhe-package" )
shift
tfhe_package="$1"
;;
"--cargo-profile")
shift
cargo_profile="$1"
;;
*)
echo "Unknown param : $1"
exit 1
;;
esac
shift
"--backend")
shift
backend="$1"
;;
"--avx512-support")
shift
if [[ "$1" == "ON" ]]; then
avx512_feature=avx512
fi
;;
"--tfhe-package")
shift
tfhe_package="$1"
;;
*)
echo "Unknown param : $1"
exit 1
;;
esac
shift
done
if [[ "${RUST_TOOLCHAIN::1}" != "+" ]]; then
RUST_TOOLCHAIN=${RUST_TOOLCHAIN:+"+${RUST_TOOLCHAIN}"}
RUST_TOOLCHAIN=${RUST_TOOLCHAIN:+"+${RUST_TOOLCHAIN}"}
fi
if [[ "${FAST_TESTS}" == TRUE ]]; then
fast_tests_argument=--fast-tests
fast_tests_argument=--fast-tests
fi
if [[ "${LONG_TESTS}" == TRUE ]]; then
long_tests_argument=--long-tests
long_tests_argument=--long-tests
fi
if [[ "${NIGHTLY_TESTS}" == TRUE ]]; then
nightly_tests_argument=--nightly-tests
nightly_tests_argument=--nightly-tests
fi
if [[ "${NO_BIG_PARAMS}" == TRUE ]]; then
no_big_params_argument=--no-big-params
no_big_params_argument=--no-big-params
fi
if [[ "${NO_BIG_PARAMS_GPU}" == TRUE ]]; then
no_big_params_argument_gpu=--no-big-params-gpu
no_big_params_argument_gpu=--no-big-params-gpu
fi
if [[ "${backend}" == "gpu" ]]; then
gpu_feature="gpu"
gpu_feature="gpu"
fi
CURR_DIR="$(dirname "$0")"
@@ -122,70 +133,80 @@ CURR_DIR="$(dirname "$0")"
num_cpu_threads="$("${CURR_DIR}"/cpu_count.sh)"
if uname -a | grep "arm64"; then
if [[ $(uname) == "Darwin" ]]; then
# Keys are 4.7 gigs at max, CI M1 macs only has 8 gigs of RAM
small_instance_n_threads=1
fi
if [[ $(uname) == "Darwin" ]]; then
# Keys are 4.7 gigs at max, CI M1 macs only has 8 gigs of RAM
small_instance_n_threads=1
fi
else
# Keys are 4.7 gigs at max, test machine has 32 gigs of RAM
small_instance_n_threads=6
# Keys are 4.7 gigs at max, test machine has 32 gigs of RAM
small_instance_n_threads=6
fi
if [[ "${BIG_TESTS_INSTANCE}" == TRUE ]]; then
test_threads="$((num_cpu_threads * 1 / 4))"
doctest_threads="${num_cpu_threads}"
test_threads="$((num_cpu_threads * 1 / 4))"
doctest_threads="${num_cpu_threads}"
else
test_threads="${small_instance_n_threads}"
doctest_threads="${num_cpu_threads}"
test_threads="${small_instance_n_threads}"
doctest_threads="${num_cpu_threads}"
fi
# Override test-threads number to avoid Out-of-memory issues on GPU instances
if [[ "${backend}" == "gpu" ]]; then
if [[ "${BIG_TESTS_INSTANCE}" == TRUE ]]; then
test_threads=8
doctest_threads=8
else
test_threads=4
doctest_threads=4
fi
if [[ "${BIG_TESTS_INSTANCE}" == TRUE ]]; then
test_threads=8
doctest_threads=8
else
test_threads=4
doctest_threads=4
fi
fi
filter_expression=$(/usr/bin/python3 scripts/test_filtering.py --layer integer --backend "${backend}" ${fast_tests_argument:+$fast_tests_argument} ${long_tests_argument:+$long_tests_argument} ${nightly_tests_argument:+$nightly_tests_argument} ${no_big_params_argument_gpu:+$no_big_params_argument_gpu} ${multi_bit_argument:+$multi_bit_argument} ${sign_argument:+$sign_argument} ${no_big_params_argument:+$no_big_params_argument})
filter_expression=$(/usr/bin/python3 scripts/test_filtering.py --layer integer --backend "${backend}" ${fast_tests_argument:+$fast_tests_argument} ${long_tests_argument:+$long_tests_argument} ${nightly_tests_argument:+$nightly_tests_argument} ${no_big_params_argument_gpu:+$no_big_params_argument_gpu} ${multi_bit_argument:+$multi_bit_argument} ${sign_argument:+$sign_argument} ${no_big_params_argument:+$no_big_params_argument} ${prod_param_argument:+$prod_param_argument})
if [[ "${FAST_TESTS}" == "TRUE" ]]; then
echo "Running 'fast' test set"
echo "Running 'fast' test set"
elif [[ "${LONG_TESTS}" == "FALSE" ]]; then
echo "Running 'slow' test set"
echo "Running 'slow' test set"
fi
if [[ "${LONG_TESTS}" == "TRUE" ]]; then
echo "Running 'long run' test set"
echo "Running 'long run' test set"
fi
if [[ "${NIGHTLY_TESTS}" == "TRUE" ]]; then
echo "Running 'nightly' test set"
echo "Running 'nightly' test set"
fi
echo "${filter_expression}"
cargo ${RUST_TOOLCHAIN:+"$RUST_TOOLCHAIN"} nextest run \
--tests \
--cargo-profile "${cargo_profile}" \
--package "${tfhe_package}" \
--profile ci \
--no-default-features \
--features=integer,internal-keycache,zk-pok,experimental,"${avx512_feature}","${gpu_feature}" \
--test-threads "${test_threads}" \
-E "$filter_expression"
if $no_run; then
nextest_command="list"
nextest_extra_flags=""
else
nextest_command="run"
nextest_extra_flags="--profile ci --test-threads ${test_threads}"
fi
if [[ -z ${multi_bit_argument} && -z ${long_tests_argument} ]]; then
cargo ${RUST_TOOLCHAIN:+"$RUST_TOOLCHAIN"} test \
--profile "${cargo_profile}" \
--package "${tfhe_package}" \
--no-default-features \
--features=integer,internal-keycache,experimental,"${avx512_feature}","${gpu_feature}" \
--doc \
-- --test-threads="${doctest_threads}" integer::"${gpu_feature}"
cargo ${RUST_TOOLCHAIN:+"$RUST_TOOLCHAIN"} nextest ${nextest_command} \
--tests \
--cargo-profile "${cargo_profile}" \
--package "${tfhe_package}" \
--no-default-features \
--features=integer,internal-keycache,zk-pok,experimental,"${avx512_feature}","${gpu_feature}" \
${nexttest_extra_flags} \
-E "$filter_expression"
if ! $no_run; then
# Unfortunately, we cannot skip running doctest with `--no-run`
if [[ -z ${multi_bit_argument} && -z ${long_tests_argument} ]]; then
cargo ${RUST_TOOLCHAIN:+"$RUST_TOOLCHAIN"} test \
--profile "${cargo_profile}" \
--package "${tfhe_package}" \
--no-default-features \
--features=integer,internal-keycache,experimental,"${avx512_feature}","${gpu_feature}" \
--doc \
-- --test-threads="${doctest_threads}" integer::"${gpu_feature}"
fi
fi
echo "Test ran in $SECONDS seconds"

View File

@@ -8,6 +8,7 @@ function usage() {
echo "--help Print this message"
echo "--rust-toolchain The toolchain to run the tests with default: stable"
echo "--multi-bit Run multi-bit tests only: default off"
echo "--run-prod-only Run only the tests using the prod parameters"
echo "--cargo-profile The cargo profile used to build tests"
echo "--tfhe-package The package spec like tfhe@0.4.2, default=tfhe"
echo
@@ -19,6 +20,7 @@ multi_bit_argument=
fast_tests_argument=
cargo_profile="release"
tfhe_package="tfhe"
prod_param_argument=
while [ -n "$1" ]
do
@@ -38,6 +40,9 @@ do
multi_bit_argument=--multi-bit
;;
"--run-prod-only")
prod_param_argument="--run-prod-only"
;;
"--cargo-profile" )
shift
cargo_profile="$1"
@@ -85,7 +90,7 @@ else
fi
if [[ "${BIG_TESTS_INSTANCE}" != TRUE ]]; then
filter_expression_small_params=$(/usr/bin/python3 scripts/test_filtering.py --layer shortint ${fast_tests_argument} ${multi_bit_argument})
filter_expression_small_params=$(/usr/bin/python3 scripts/test_filtering.py --layer shortint ${fast_tests_argument} ${multi_bit_argument} ${prod_param_argument})
# Run tests only no examples or benches with small params and more threads
cargo ${RUST_TOOLCHAIN:+"$RUST_TOOLCHAIN"} nextest run \
@@ -125,7 +130,7 @@ and not test(~smart_add_and_mul)"""
fi
fi
else
filter_expression=$(/usr/bin/python3 scripts/test_filtering.py --layer shortint --big-instance ${fast_tests_argument} ${multi_bit_argument})
filter_expression=$(/usr/bin/python3 scripts/test_filtering.py --layer shortint --big-instance ${fast_tests_argument} ${multi_bit_argument} ${prod_param_argument})
# Run tests only no examples or benches with small params and more threads
cargo ${RUST_TOOLCHAIN:+"$RUST_TOOLCHAIN"} nextest run \

View File

@@ -74,12 +74,17 @@ parser.add_argument(
action="store_true",
help="Do not run tests with big parameters set (e.g. 3bits message with 3 bits carry) for GPU",
)
parser.add_argument(
"--run-prod-only",
action="store_true",
help="Specify to run the CPU tests with the prod KS_PBS 2_2 parameters, \
only the 'layer' parameter will be taken into account if this flag is specified",
)
# block PBS are too slow for high params
# mul_crt_4_4 is extremely flaky (~80% failure)
# test_wopbs_bivariate_crt_wopbs_param_message generate tables that are too big at the moment
# test_integer_smart_mul_param_message_4_carry_4_ks_pbs_gaussian_2m64 is too slow
# so is test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs_gaussian_2m64
# skip smart_div, smart_rem which are already covered by the smar_div_rem test
# skip default_div, default_rem which are covered by default_div_rem
EXCLUDED_INTEGER_TESTS = [
@@ -91,7 +96,6 @@ EXCLUDED_INTEGER_TESTS = [
"~mul_crt_param_message_4_carry_4_ks_pbs_gaussian_2m64",
"/.*test_wopbs_bivariate_crt_wopbs_param_message_[34]_carry_[34]_ks_pbs_gaussian_2m64$/",
"/.*test_integer_smart_mul_param_message_4_carry_4_ks_pbs_gaussian_2m64$/",
"/.*test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs_gaussian_2m64$/",
"/.*::tests_long_run::.*/",
]
@@ -100,7 +104,6 @@ EXCLUDED_INTEGER_FAST_TESTS = [
"/.*integer_default_div_param/",
"/.*integer_default_rem_param/",
"/.*_param_message_[14]_carry_[14]_ks_pbs_gaussian_2m64$/",
"/.*default_add_sequence_multi_thread_param_message_3_carry_3_ks_pbs_gaussian_2m64$/",
]
EXCLUDED_BIG_PARAMETERS = [
@@ -125,7 +128,13 @@ def filter_integer_tests(input_args):
# For now, GPU only has specific parameters set for multi-bit
multi_bit_filter = "_gpu_multi_bit"
filter_expression = [f"test(/^integer::{backend_filter}.*/)"]
if input_args.run_prod_only:
filter_expression = [f"test(/^integer::{backend_filter}.*_param_prod.*/)"]
else:
filter_expression = [
f"test(/^integer::{backend_filter}.*/)",
"not test(~_param_prod)",
]
if input_args.multi_bit:
filter_expression.append("test(~_multi_bit)")
@@ -161,29 +170,32 @@ def filter_integer_tests(input_args):
f"test(/.*_default_.*?_param{multi_bit_filter}{group_filter}_message_3_carry_3_.*/)"
)
excluded_tests = (
EXCLUDED_INTEGER_FAST_TESTS if input_args.fast_tests else EXCLUDED_INTEGER_TESTS
EXCLUDED_INTEGER_FAST_TESTS
if input_args.fast_tests
else EXCLUDED_INTEGER_TESTS
)
for pattern in excluded_tests:
filter_expression.append(f"not test({pattern})")
else:
if input_args.backend == "gpu":
filter_expression = ["test(/^integer::gpu::server_key::radix::tests_long_run.*/)"]
filter_expression = [
"test(/^integer::gpu::server_key::radix::tests_long_run.*/)"
]
elif input_args.backend == "cpu":
filter_expression = ["test(/^integer::server_key::radix_parallel::tests_long_run.*/)"]
filter_expression = [
"test(/^integer::server_key::radix_parallel::tests_long_run.*/)"
]
# Do not run noise check tests by default as they can be very slow
# they will be run e.g. nightly or on demand
filter = filter_expression.append(f"not test(/^integer::gpu::server_key::radix::tests_noise_distribution::.*::test_gpu_noise_check.*/)")
filter_expression.append(
"not test(/^integer::gpu::server_key::radix::tests_noise_distribution::.*::test_gpu_noise_check.*/)"
)
return " and ".join(filter_expression)
def filter_shortint_tests(input_args):
multi_bit_filter, group_filter = (
("_multi_bit", "_group_[0-9]") if input_args.multi_bit else ("", "")
)
def shortint_normal_filter(input_args):
multi_bit_filter = "_multi_bit_group_[0-9]" if input_args.multi_bit else ""
if input_args.fast_tests:
msg_carry_pairs = [(2, 1), (2, 2), (2, 3)]
@@ -206,19 +218,31 @@ def filter_shortint_tests(input_args):
msg_carry_pairs.append((4, 4))
filter_expression = [
f"test(/^shortint::.*_param{multi_bit_filter}{group_filter}_message_{msg}_carry_{carry}(_compact_pk)?_ks(32)?_pbs.*/)"
f"test(/^shortint::.*_param{multi_bit_filter}_message_{msg}_carry_{carry}\
(_compact_pk)?_ks(32)?_pbs.*/)"
for msg, carry in msg_carry_pairs
]
filter_expression.append("test(/^shortint::.*meta_param_cpu_2_2/)")
filter_expression.append("test(/^shortint::.*meta_param_cpu_2_2_ks32_pbs/)")
filter_expression.append("test(/^shortint::.*_ci_run_filter/)")
return filter_expression
def filter_shortint_tests(input_args):
# We special case the CPU KS_PBS 2_2 parameters to be able to run them alone
filter_expression = shortint_normal_filter(input_args)
opt_in_tests = " or ".join(filter_expression)
# Do not run noise check tests by default as they can be very slow
# they will be run e.g. nightly or on demand
filter = f"({opt_in_tests}) and not test(/^shortint::.*test_noise_check/)"
if input_args.run_prod_only:
filter = f"({filter}) and test(/^shortint::.*_param_prod.*/)"
else:
filter = f"({filter}) and not test(/^shortint::.*_param_prod.*/)"
return filter

View File

@@ -1,25 +1,17 @@
use benchmark::params_aliases::BENCH_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
#[cfg(feature = "gpu")]
use benchmark::params_aliases::BENCH_PARAM_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
use criterion::{black_box, criterion_group, Criterion};
use std::num::NonZeroU64;
use tfhe::{set_server_key, ClientKey, ConfigBuilder, FheUint64, RangeForRandom, Seed, ServerKey};
pub fn oprf_any_range(c: &mut Criterion) {
let bench_name = "hlapi::oprf_any_range";
fn oprf_any_range_bench(c: &mut Criterion, bench_name: &str) {
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(15)
.measurement_time(std::time::Duration::from_secs(30));
let param = BENCH_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(param).build();
let cks = ClientKey::generate(config);
let sks = ServerKey::new(&cks);
rayon::broadcast(|_| set_server_key(sks.clone()));
set_server_key(sks);
for excluded_upper_bound in [3, 52] {
let range = RangeForRandom::new_from_excluded_upper_bound(
NonZeroU64::new(excluded_upper_bound).unwrap(),
@@ -41,4 +33,34 @@ pub fn oprf_any_range(c: &mut Criterion) {
bench_group.finish()
}
criterion_group!(oprf_any_range2, oprf_any_range);
pub fn oprf_any_range_cpu(c: &mut Criterion) {
let param = BENCH_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(param).build();
let cks = ClientKey::generate(config);
let sks = ServerKey::new(&cks);
rayon::broadcast(|_| set_server_key(sks.clone()));
set_server_key(sks);
oprf_any_range_bench(c, "hlapi::oprf_any_range_cpu");
}
#[cfg(feature = "gpu")]
pub fn oprf_any_range_gpu(c: &mut Criterion) {
let param = BENCH_PARAM_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(param).build();
let cks = ClientKey::generate(config);
let sks = tfhe::CompressedServerKey::new(&cks).decompress_to_gpu();
set_server_key(sks);
oprf_any_range_bench(c, "hlapi::oprf_any_range_gpu");
}
#[cfg(not(feature = "gpu"))]
criterion_group!(oprf_any_range2, oprf_any_range_cpu);
#[cfg(feature = "gpu")]
criterion_group!(oprf_any_range2, oprf_any_range_cpu, oprf_any_range_gpu);

View File

@@ -137,24 +137,22 @@ pub fn ct_sizes(results_file: &Path) {
println!("\t* SNS CT: {sns_ct_size} bytes");
write_and_record_result(sns_ct_size, &test_name, "sns-ct-size");
if meta_param
.noise_squashing_parameters
.unwrap()
.compression_parameters
.is_some()
{
let test_name = format!("hlapi_compressed_sns_ct_size::{}", param_fhe.name());
let compressed_sns_ct = CompressedSquashedNoiseCiphertextList::builder()
.push(sns_ct)
.build()
.unwrap();
let compressed_sns_ct_size = bincode::serialize(&compressed_sns_ct).unwrap().len();
println!("\t* Compressed SNS CT: {compressed_sns_ct_size} bytes");
write_and_record_result(
compressed_sns_ct_size,
&test_name,
"compressed-sns-ct-size",
);
if let Some(ns_params) = meta_param.noise_squashing_parameters {
if ns_params.compression_parameters.is_some() {
let test_name = format!("hlapi_compressed_sns_ct_size::{}", param_fhe.name());
let compressed_sns_ct = CompressedSquashedNoiseCiphertextList::builder()
.push(sns_ct)
.build()
.unwrap();
let compressed_sns_ct_size =
bincode::serialize(&compressed_sns_ct).unwrap().len();
println!("\t* Compressed SNS CT: {compressed_sns_ct_size} bytes");
write_and_record_result(
compressed_sns_ct_size,
&test_name,
"compressed-sns-ct-size",
);
}
}
}

View File

@@ -531,11 +531,11 @@ pub mod shortint_params {
pub fn get_classical_tuniform_groups() -> Vec<MetaParameters> {
vec![
// Most complete 2_2 parameters set
V1_5_META_PARAM_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_2_2_KS32_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_1_1_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_3_3_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_4_4_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_2_2_KS32_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_1_1_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_3_3_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_4_4_KS_PBS_TUNIFORM_2M128,
]
}
@@ -544,37 +544,37 @@ pub mod shortint_params {
vec![
// Group 2
// CPU ---
V1_5_META_PARAM_CPU_1_1_MULTI_BIT_GROUP_2_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_2_2_MULTI_BIT_GROUP_2_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_3_3_MULTI_BIT_GROUP_2_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_4_4_MULTI_BIT_GROUP_2_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_1_1_MULTI_BIT_GROUP_2_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_2_2_MULTI_BIT_GROUP_2_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_3_3_MULTI_BIT_GROUP_2_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_4_4_MULTI_BIT_GROUP_2_KS_PBS_TUNIFORM_2M128,
// GPU ---
V1_5_META_PARAM_GPU_1_1_MULTI_BIT_GROUP_2_KS_PBS_GAUSSIAN_2M128,
V1_5_META_PARAM_GPU_2_2_MULTI_BIT_GROUP_2_KS_PBS_GAUSSIAN_2M128,
V1_5_META_PARAM_GPU_3_3_MULTI_BIT_GROUP_2_KS_PBS_GAUSSIAN_2M128,
V1_5_META_PARAM_GPU_4_4_MULTI_BIT_GROUP_2_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_1_1_MULTI_BIT_GROUP_2_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_2_2_MULTI_BIT_GROUP_2_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_3_3_MULTI_BIT_GROUP_2_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_4_4_MULTI_BIT_GROUP_2_KS_PBS_GAUSSIAN_2M128,
// Group 3
// CPU ---
V1_5_META_PARAM_CPU_1_1_MULTI_BIT_GROUP_3_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_2_2_MULTI_BIT_GROUP_3_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_3_3_MULTI_BIT_GROUP_3_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_4_4_MULTI_BIT_GROUP_3_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_1_1_MULTI_BIT_GROUP_3_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_2_2_MULTI_BIT_GROUP_3_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_3_3_MULTI_BIT_GROUP_3_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_4_4_MULTI_BIT_GROUP_3_KS_PBS_TUNIFORM_2M128,
// GPU ---
V1_5_META_PARAM_GPU_1_1_MULTI_BIT_GROUP_3_KS_PBS_GAUSSIAN_2M128,
V1_5_META_PARAM_GPU_2_2_MULTI_BIT_GROUP_3_KS_PBS_GAUSSIAN_2M128,
V1_5_META_PARAM_GPU_3_3_MULTI_BIT_GROUP_3_KS_PBS_GAUSSIAN_2M128,
V1_5_META_PARAM_GPU_4_4_MULTI_BIT_GROUP_3_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_1_1_MULTI_BIT_GROUP_3_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_2_2_MULTI_BIT_GROUP_3_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_3_3_MULTI_BIT_GROUP_3_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_4_4_MULTI_BIT_GROUP_3_KS_PBS_GAUSSIAN_2M128,
// Group 4
// CPU ---
V1_5_META_PARAM_CPU_1_1_MULTI_BIT_GROUP_4_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_2_2_MULTI_BIT_GROUP_4_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_3_3_MULTI_BIT_GROUP_4_KS_PBS_TUNIFORM_2M128,
V1_5_META_PARAM_CPU_4_4_MULTI_BIT_GROUP_4_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_1_1_MULTI_BIT_GROUP_4_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_2_2_MULTI_BIT_GROUP_4_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_3_3_MULTI_BIT_GROUP_4_KS_PBS_TUNIFORM_2M128,
V1_6_META_PARAM_CPU_4_4_MULTI_BIT_GROUP_4_KS_PBS_TUNIFORM_2M128,
// GPU ---
V1_5_META_PARAM_GPU_1_1_MULTI_BIT_GROUP_4_KS_PBS_GAUSSIAN_2M128,
V1_5_META_PARAM_GPU_2_2_MULTI_BIT_GROUP_4_KS_PBS_GAUSSIAN_2M128,
V1_5_META_PARAM_GPU_3_3_MULTI_BIT_GROUP_4_KS_PBS_GAUSSIAN_2M128,
V1_5_META_PARAM_GPU_4_4_MULTI_BIT_GROUP_4_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_1_1_MULTI_BIT_GROUP_4_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_2_2_MULTI_BIT_GROUP_4_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_3_3_MULTI_BIT_GROUP_4_KS_PBS_GAUSSIAN_2M128,
V1_6_META_PARAM_GPU_4_4_MULTI_BIT_GROUP_4_KS_PBS_GAUSSIAN_2M128,
]
}
}

View File

@@ -10,38 +10,38 @@ pub mod shortint_params_aliases {
// KS PBS Gaussian
#[cfg(not(feature = "gpu"))]
pub const BENCH_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
#[cfg(feature = "gpu")]
pub const BENCH_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128: ClassicPBSParameters =
V1_5_PARAM_GPU_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_GPU_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M128: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M128;
// KS PBS TUniform
pub const BENCH_PARAM_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64;
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64;
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64;
V1_6_PARAM_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M64: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M64;
V1_6_PARAM_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MESSAGE_2_CARRY_2_KS_PBS: ClassicPBSParameters =
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MESSAGE_2_CARRY_2_KS32_PBS: KeySwitch32PBSParameters =
V1_5_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
V1_6_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
pub const BENCH_ALL_CLASSIC_PBS_PARAMETERS: [(&ClassicPBSParameters, &str); 141] =
VEC_ALL_CLASSIC_PBS_PARAMETERS;
@@ -50,136 +50,136 @@ pub mod shortint_params_aliases {
// CPU Gaussian
pub const BENCH_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128;
// CPU TUniform
// --- Grouping factor 2
pub const BENCH_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_2_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
// --- Grouping factor 3
pub const BENCH_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_3_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
// --- Grouping factor 4
pub const BENCH_PARAM_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64:
MultiBitPBSParameters = V1_5_PARAM_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64;
MultiBitPBSParameters = V1_6_PARAM_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64:
MultiBitPBSParameters = V1_5_PARAM_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64;
MultiBitPBSParameters = V1_6_PARAM_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64:
MultiBitPBSParameters = V1_5_PARAM_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64;
MultiBitPBSParameters = V1_6_PARAM_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M64:
MultiBitPBSParameters = V1_5_PARAM_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M64;
MultiBitPBSParameters = V1_6_PARAM_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
// GPU Gaussian
// --- Grouping factor 4
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128;
// GPU TUniform
// --- Grouping factor 2
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_2_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
// --- Grouping factor 3
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
// --- Grouping factor 4
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M64:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M64;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M64;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128:
MultiBitPBSParameters =
V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128;
pub const BENCH_ALL_MULTI_BIT_PBS_PARAMETERS: [(&MultiBitPBSParameters, &str); 240] =
VEC_ALL_MULTI_BIT_PBS_PARAMETERS;
@@ -187,88 +187,88 @@ pub mod shortint_params_aliases {
// PKE
pub const BENCH_PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
CompactPublicKeyEncryptionParameters =
V1_5_PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1:
CompactPublicKeyEncryptionParameters =
V1_5_PARAM_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
V1_6_PARAM_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
// KS
pub const BENCH_PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
ShortintKeySwitchingParameters =
V1_5_PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128:
ShortintKeySwitchingParameters =
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128;
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128;
pub const BENCH_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
ShortintKeySwitchingParameters =
V1_5_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
ShortintKeySwitchingParameters =
V1_5_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
// ZKV1
pub const BENCH_PARAM_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1:
CompactPublicKeyEncryptionParameters =
V1_5_PARAM_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
V1_6_PARAM_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
pub const BENCH_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1:
ShortintKeySwitchingParameters =
V1_5_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
V1_6_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
pub const BENCH_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1:
ShortintKeySwitchingParameters =
V1_5_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
V1_6_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
// ZKV2
pub const BENCH_PARAM_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2:
CompactPublicKeyEncryptionParameters =
V1_5_PARAM_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2;
V1_6_PARAM_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2;
pub const BENCH_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2:
ShortintKeySwitchingParameters =
V1_5_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2;
V1_6_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2;
pub const BENCH_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2:
ShortintKeySwitchingParameters =
V1_5_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2;
V1_6_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2;
// Compression
pub const BENCH_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128: CompressionParameters =
V1_5_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
CompressionParameters =
V1_5_COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
// Noise Squashing
pub const BENCH_NOISE_SQUASHING_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
NoiseSquashingParameters =
V1_5_NOISE_SQUASHING_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_NOISE_SQUASHING_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
NoiseSquashingCompressionParameters =
V1_5_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_NOISE_SQUASHING_PARAM_GPU_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
NoiseSquashingParameters =
V1_5_NOISE_SQUASHING_PARAM_GPU_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_NOISE_SQUASHING_PARAM_GPU_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_NOISE_SQUASHING_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
NoiseSquashingParameters =
V1_5_NOISE_SQUASHING_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_NOISE_SQUASHING_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const BENCH_COMP_NOISE_SQUASHING_PARAM_GPU_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
NoiseSquashingCompressionParameters =
V1_5_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
#[cfg(feature = "hpu")]
// KS PBS Gaussian for Hpu
pub const BENCH_HPU_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_GAUSSIAN_2M64: KeySwitch32PBSParameters =
V1_5_HPU_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_GAUSSIAN_2M64;
V1_6_HPU_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_GAUSSIAN_2M64;
#[cfg(feature = "hpu")]
// KS PBS TUniform
pub const BENCH_HPU_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M64: KeySwitch32PBSParameters =
V1_5_HPU_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M64;
V1_6_HPU_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M64;
#[cfg(feature = "hpu")]
// KS PBS TUniform pfail -128
pub const BENCH_HPU_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128: KeySwitch32PBSParameters =
V1_5_HPU_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
V1_6_HPU_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
}
#[cfg(any(feature = "shortint", feature = "integer"))]

View File

@@ -1,6 +1,6 @@
[package]
name = "tfhe"
version = "1.5.0"
version = "1.6.0"
edition = "2021"
readme = "../README.md"
keywords = ["fully", "homomorphic", "encryption", "fhe", "cryptography"]

View File

@@ -647,7 +647,7 @@ int main(void) {
assert(ok == 0);
// Then use small parameters, those are gaussians as we don't have small TUniform params
ok = config_builder_use_custom_parameters(
&builder, SHORTINT_V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128);
&builder, SHORTINT_V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128);
ok = config_builder_build(builder, &config);
assert(ok == 0);

View File

@@ -15,7 +15,7 @@ void test_predefined_keygen_w_serde(void) {
ShortintCompressedCiphertext *cct = NULL;
ShortintCompressedCiphertext *deser_cct = NULL;
ShortintCiphertext *decompressed_ct = NULL;
ShortintPBSParameters params = SHORTINT_V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
ShortintPBSParameters params = SHORTINT_V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
int gen_keys_ok = shortint_gen_keys_with_parameters(params, &cks, &sks);
assert(gen_keys_ok == 0);
@@ -79,7 +79,7 @@ void test_server_key_trivial_encrypt(void) {
ShortintClientKey *cks = NULL;
ShortintServerKey *sks = NULL;
ShortintCiphertext *ct = NULL;
ShortintPBSParameters params = SHORTINT_V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
ShortintPBSParameters params = SHORTINT_V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
int gen_keys_ok = shortint_gen_keys_with_parameters(params, &cks, &sks);
assert(gen_keys_ok == 0);
@@ -219,10 +219,10 @@ void test_compressed_public_keygen(ShortintPBSParameters params) {
int main(void) {
test_predefined_keygen_w_serde();
test_custom_keygen();
test_public_keygen(SHORTINT_V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128);
test_public_keygen(SHORTINT_V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128);
test_compressed_public_keygen(SHORTINT_V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128);
test_compressed_public_keygen(SHORTINT_V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128);
test_public_keygen(SHORTINT_V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128);
test_public_keygen(SHORTINT_V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128);
test_compressed_public_keygen(SHORTINT_V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128);
test_compressed_public_keygen(SHORTINT_V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128);
test_server_key_trivial_encrypt();
return EXIT_SUCCESS;
}

View File

@@ -41,7 +41,7 @@ void test_shortint_pbs_2_bits_message(void) {
ShortintPBSLookupTable *lookup_table = NULL;
ShortintClientKey *cks = NULL;
ShortintServerKey *sks = NULL;
ShortintPBSParameters params = SHORTINT_V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
ShortintPBSParameters params = SHORTINT_V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
int gen_keys_ok = shortint_gen_keys_with_parameters(params, &cks, &sks);
assert(gen_keys_ok == 0);
@@ -115,7 +115,7 @@ void test_shortint_bivariate_pbs_2_bits_message(void) {
ShortintBivariatePBSLookupTable *lookup_table = NULL;
ShortintClientKey *cks = NULL;
ShortintServerKey *sks = NULL;
ShortintPBSParameters params = SHORTINT_V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
ShortintPBSParameters params = SHORTINT_V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
int gen_keys_ok = shortint_gen_keys_with_parameters(params, &cks, &sks);
assert(gen_keys_ok == 0);

View File

@@ -541,7 +541,7 @@ void test_server_key(void) {
ShortintPBSParameters params = SHORTINT_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
// We don't have TUniform small params, use gaussian instead
ShortintPBSParameters params_small = SHORTINT_V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintPBSParameters params_small = SHORTINT_V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
assert(params.message_modulus == 1 << message_bits);
assert(params.carry_modulus == 1 << carry_bits);

View File

@@ -74,7 +74,7 @@ To compile and execute GPU TFHE-rs programs, make sure your system has the follo
To use the **TFHE-rs** GPU backend in your project, add the following dependency in your `Cargo.toml`.
```toml
tfhe = { version = "~1.5.0", features = ["boolean", "shortint", "integer", "gpu"] }
tfhe = { version = "~1.6.0", features = ["boolean", "shortint", "integer", "gpu"] }
```
If none of the supported backends is configured in `Cargo.toml`, the CPU backend is used.

View File

@@ -17,7 +17,7 @@ This guide explains how to update your existing program to leverage HPU accelera
To use the **TFHE-rs** HPU backend in your project, add the following dependency in your `Cargo.toml`.
```toml
tfhe = { version = "~1.5.0", features = ["integer", "hpu-v80"] }
tfhe = { version = "~1.6.0", features = ["integer", "hpu-v80"] }
```
{% hint style="success" %}

View File

@@ -13,11 +13,11 @@ The following example shows how to use parallelized bootstrapping by choosing mu
```rust
use tfhe::prelude::*;
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint32};
use tfhe::shortint::parameters::current_params::V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64;
use tfhe::shortint::parameters::current_params::V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConfigBuilder::default()
.use_custom_parameters(V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64)
.use_custom_parameters(V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64)
.build();
let (keys, server_keys) = generate_keys(config);
@@ -45,12 +45,12 @@ Here's an example:
```rust
use tfhe::prelude::*;
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint32};
use tfhe::shortint::parameters::current_params::V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64;
use tfhe::shortint::parameters::current_params::V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConfigBuilder::default()
.use_custom_parameters(
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64.with_deterministic_execution(),
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64.with_deterministic_execution(),
)
.build();

View File

@@ -97,11 +97,11 @@ use tfhe::zk::{CompactPkeCrs, ZkComputeLoad};
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut rng = thread_rng();
let params = tfhe::shortint::parameters::current_params::V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = tfhe::shortint::parameters::current_params::V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
// Indicate which parameters to use for the Compact Public Key encryption
let cpk_params = tfhe::shortint::parameters::current_params::compact_public_key_only::p_fail_2_minus_128::ks_pbs::V1_5_PARAM_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
let cpk_params = tfhe::shortint::parameters::current_params::compact_public_key_only::p_fail_2_minus_128::ks_pbs::V1_6_PARAM_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
// And parameters allowing to keyswitch/cast to the computation parameters.
let casting_params = tfhe::shortint::parameters::current_params::key_switching::p_fail_2_minus_128::ks_pbs::V1_5_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
let casting_params = tfhe::shortint::parameters::current_params::key_switching::p_fail_2_minus_128::ks_pbs::V1_6_PARAM_KEYSWITCH_PKE_TO_SMALL_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1;
// Enable the dedicated parameters on the config
let config = tfhe::ConfigBuilder::with_custom_parameters(params)
.use_dedicated_compact_public_key_parameters((cpk_params, casting_params)).build();

View File

@@ -112,11 +112,11 @@ You can override the default parameters with the `with_custom_parameters(block_p
```rust
use tfhe::{ConfigBuilder, generate_keys};
use tfhe::shortint::parameters::current_params::V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
use tfhe::shortint::parameters::current_params::V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
fn main() {
let config =
ConfigBuilder::with_custom_parameters(V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
ConfigBuilder::with_custom_parameters(V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
// Client-side

View File

@@ -16,7 +16,7 @@ You can load serialized data with the `unversionize` function, even in newer ver
[dependencies]
# ...
tfhe = { version = "~1.5.0", features = ["integer"] }
tfhe = { version = "~1.6.0", features = ["integer"] }
tfhe-versionable = "0.6.0"
bincode = "1.3.3"
```

View File

@@ -161,7 +161,7 @@ In the following example, we use [bincode](https://crates.io/crates/bincode) for
[dependencies]
# ...
tfhe = { version = "~1.5.0", features = ["integer"] }
tfhe = { version = "~1.6.0", features = ["integer"] }
bincode = "1.3.3"
```

View File

@@ -19,7 +19,7 @@ The following example shows a complete workflow of working with encrypted arrays
# Cargo.toml
[dependencies]
tfhe = { version = "~1.5.0", features = ["integer"] }
tfhe = { version = "~1.6.0", features = ["integer"] }
```
```rust

View File

@@ -36,7 +36,7 @@ To serialize a `KVStore`, it must first be compressed.
# Cargo.toml
[dependencies]
tfhe = { version = "~1.5.0", features = ["integer"] }
tfhe = { version = "~1.6.0", features = ["integer"] }
```
```rust

View File

@@ -29,7 +29,7 @@ Here is an example:
# Cargo.toml
[dependencies]
tfhe = { version = "~1.5.0", features = ["integer", "strings"] }
tfhe = { version = "~1.6.0", features = ["integer", "strings"] }
```
```rust

View File

@@ -7,7 +7,7 @@ This document provides instructions to set up **TFHE-rs** in your project.
First, add **TFHE-rs** as a dependency in your `Cargo.toml`.
```toml
tfhe = { version = "~1.5.0", features = ["boolean", "shortint", "integer"] }
tfhe = { version = "~1.6.0", features = ["boolean", "shortint", "integer"] }
```
{% hint style="info" %}
@@ -35,7 +35,7 @@ By default, **TFHE-rs** makes the assumption that hardware AES features are enab
To add support for older CPU, import **TFHE-rs** with the `software-prng` feature in your `Cargo.toml`:
```toml
tfhe = { version = "~1.5.0", features = ["boolean", "shortint", "integer", "software-prng"] }
tfhe = { version = "~1.6.0", features = ["boolean", "shortint", "integer", "software-prng"] }
```
## Hardware acceleration

View File

@@ -59,7 +59,7 @@ edition = "2021"
Then add the following configuration to include **TFHE-rs**:
```toml
tfhe = { version = "~1.5.0", features = ["integer"] }
tfhe = { version = "~1.6.0", features = ["integer"] }
```
Your updated `Cargo.toml` file should look like this:
@@ -71,7 +71,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
tfhe = { version = "~1.5.0", features = ["integer"] }
tfhe = { version = "~1.6.0", features = ["integer"] }
```
If you are on a different platform please refer to the [installation documentation](installation.md) for configuration options of other supported platforms.

View File

@@ -37,7 +37,7 @@ function fhe_uint32_example() {
const U32_MAX = 4294967295;
const block_params = new ShortintParameters(ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS_GAUSSIAN_2M64);
const block_params = new ShortintParameters(ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS_GAUSSIAN_2M64);
let config = TfheConfigBuilder.default()
.build();
@@ -90,7 +90,7 @@ async function example() {
await initThreadPool(navigator.hardwareConcurrency);
await init_panic_hook();
const block_params = new ShortintParameters(ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS_GAUSSIAN_2M64);
const block_params = new ShortintParameters(ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS_GAUSSIAN_2M64);
// ....
}
```

View File

@@ -9,7 +9,7 @@ Welcome to this tutorial about `TFHE-rs` `core_crypto` module.
To use `TFHE-rs`, it first has to be added as a dependency in the `Cargo.toml`:
```toml
tfhe = { version = "~1.5.0" }
tfhe = { version = "~1.6.0" }
```
### Commented code to double a 2-bit message in a leveled fashion and using a PBS with the `core_crypto` module.

View File

@@ -28,7 +28,7 @@ To use the `FheUint8` type, enable the `integer` feature:
# Cargo.toml
[dependencies]
tfhe = { version = "~1.5.0", features = ["integer"] }
tfhe = { version = "~1.6.0", features = ["integer"] }
```
The `MyFheString::encrypt` function performs data validation to ensure the input string contains only ASCII characters.
@@ -167,7 +167,7 @@ First, add the feature in your `Cargo.toml`
# Cargo.toml
[dependencies]
tfhe = { version = "~1.5.0", features = ["strings"] }
tfhe = { version = "~1.6.0", features = ["strings"] }
```
The `FheAsciiString` type allows to simply do homomorphic case changing of encrypted strings (and much more!):

View File

@@ -17,7 +17,7 @@ This function returns a Boolean (`true` or `false`) so that the total count of `
```toml
# Cargo.toml
tfhe = { version = "~1.5.0", features = ["integer"] }
tfhe = { version = "~1.6.0", features = ["integer"] }
```
First, define the verification function.

View File

@@ -5,8 +5,8 @@ use std::mem::MaybeUninit;
use std::{array, iter};
use tfhe::prelude::*;
use tfhe::shortint::parameters::current_params::{
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
};
use tfhe::{set_server_key, ClientKey, CompressedServerKey, ConfigBuilder, Device, FheUint32};
@@ -190,10 +190,10 @@ fn main() -> Result<(), std::io::Error> {
let config = match args.multibit {
None => ConfigBuilder::default(),
Some(2) => ConfigBuilder::with_custom_parameters(
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
),
Some(3) => ConfigBuilder::with_custom_parameters(
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
),
Some(v) => {
panic!("Invalid multibit setting {v}");

View File

@@ -17,7 +17,8 @@ use tfhe::shortint::parameters::key_switching::ShortintKeySwitchingParameters;
use tfhe::shortint::parameters::current_params::*;
use tfhe::shortint::parameters::{
ClassicPBSParameters, PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
AtomicPatternParameters, ClassicPBSParameters, PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128,
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
};
#[cfg(feature = "experimental")]
use tfhe::shortint::parameters::{
@@ -32,9 +33,9 @@ const KSK_PARAMS: [(
ClassicPBSParameters,
ShortintKeySwitchingParameters,
); 1] = [(
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_KEYSWITCH_1_1_KS_PBS_TO_2_2_KS_PBS_GAUSSIAN_2M128,
)];
fn client_server_keys() {
@@ -64,12 +65,12 @@ fn client_server_keys() {
let coverage_only: bool = matches.get_flag("coverage_only");
if multi_bit_only {
const MULTI_BIT_PARAMS: [MultiBitPBSParameters; 6] = [
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_5_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_5_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
];
generate_pbs_multi_bit_keys(&MULTI_BIT_PARAMS);
@@ -97,7 +98,7 @@ fn client_server_keys() {
#[cfg(feature = "experimental")]
{
const WOPBS_PARAMS: [(ClassicPBSParameters, WopbsParameters); 1] = [(
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
LEGACY_WOPBS_PARAM_MESSAGE_2_CARRY_2_KS_PBS,
)];
generate_wopbs_keys(&WOPBS_PARAMS);
@@ -111,41 +112,43 @@ fn client_server_keys() {
// TUniform
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
// Gaussian
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_1_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_1_CARRY_3_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_1_CARRY_4_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_1_CARRY_5_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_1_CARRY_6_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_2_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_2_CARRY_3_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_3_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_3_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128,
V1_5_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_3_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_4_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_5_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_1_CARRY_6_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_3_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_3_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_3_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128,
V1_6_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M128,
// 2M64 as backup as 2M128 is too slow
V1_5_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M64,
];
generate_pbs_keys(&PBS_KEYS);
generate_pbs_keys(&[PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128]);
#[cfg(feature = "experimental")]
{
const WOPBS_PARAMS: [(ClassicPBSParameters, WopbsParameters); 4] = [
(
V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
LEGACY_WOPBS_PARAM_MESSAGE_1_CARRY_1_KS_PBS,
),
(
V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
LEGACY_WOPBS_PARAM_MESSAGE_2_CARRY_2_KS_PBS,
),
(
V1_5_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
LEGACY_WOPBS_PARAM_MESSAGE_3_CARRY_3_KS_PBS,
),
(
V1_5_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M64,
V1_6_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M64,
LEGACY_WOPBS_PARAM_MESSAGE_4_CARRY_4_KS_PBS,
),
];
@@ -155,10 +158,11 @@ fn client_server_keys() {
}
}
fn generate_pbs_keys(params: &[ClassicPBSParameters]) {
fn generate_pbs_keys<P: Into<AtomicPatternParameters> + Copy>(params: &[P]) {
println!("Generating shortint (ClientKey, ServerKey)");
for (i, param) in params.iter().copied().enumerate() {
let param: AtomicPatternParameters = param.into();
println!(
"Generating [{} / {}] : {}",
i + 1,

View File

@@ -100,7 +100,7 @@ test("hlapi_compressed_public_client_int8_big", (t) => {
test("hlapi_public_key_encrypt_decrypt_int32_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -127,7 +127,7 @@ test("hlapi_public_key_encrypt_decrypt_int32_small", (t) => {
test("hlapi_decompress_public_key_then_encrypt_decrypt_int32_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -213,7 +213,7 @@ test("hlapi_client_key_encrypt_decrypt_int128_big", (t) => {
test("hlapi_client_key_encrypt_decrypt_int128_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -323,7 +323,7 @@ test("hlapi_client_key_encrypt_decrypt_int256_big", (t) => {
test("hlapi_client_key_encrypt_decrypt_int256_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -384,7 +384,7 @@ test("hlapi_client_key_encrypt_decrypt_int256_small", (t) => {
test("hlapi_decompress_public_key_then_encrypt_decrypt_int256_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -412,7 +412,7 @@ test("hlapi_decompress_public_key_then_encrypt_decrypt_int256_small", (t) => {
test("hlapi_public_key_encrypt_decrypt_int256_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -470,7 +470,7 @@ function hlapi_compact_public_key_encrypt_decrypt_int32_single(config) {
test("hlapi_compact_public_key_encrypt_decrypt_int32_big_single", (t) => {
const block_params = new ShortintParameters(
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS_GAUSSIAN_2M128,
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS_GAUSSIAN_2M128,
);
let config = TfheConfigBuilder.default()
.use_custom_parameters(block_params)
@@ -481,7 +481,7 @@ test("hlapi_compact_public_key_encrypt_decrypt_int32_big_single", (t) => {
test("hlapi_compact_public_key_encrypt_decrypt_int32_small_single", (t) => {
const block_params = new ShortintParameters(
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS_GAUSSIAN_2M128,
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS_GAUSSIAN_2M128,
);
let config = TfheConfigBuilder.default()
.use_custom_parameters(block_params)

View File

@@ -80,7 +80,7 @@ test("hlapi_key_gen_big", (t) => {
test("hlapi_key_gen_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -151,7 +151,7 @@ test("hlapi_compressed_public_client_uint8_big", (t) => {
test("hlapi_public_key_encrypt_decrypt_uint32_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -178,7 +178,7 @@ test("hlapi_public_key_encrypt_decrypt_uint32_small", (t) => {
test("hlapi_decompress_public_key_then_encrypt_decrypt_uint32_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -264,7 +264,7 @@ test("hlapi_client_key_encrypt_decrypt_uint128_big", (t) => {
test("hlapi_client_key_encrypt_decrypt_uint128_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -365,7 +365,7 @@ test("hlapi_client_key_encrypt_decrypt_uint256_big", (t) => {
test("hlapi_client_key_encrypt_decrypt_uint256_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -417,7 +417,7 @@ test("hlapi_client_key_encrypt_decrypt_uint256_small", (t) => {
test("hlapi_decompress_public_key_then_encrypt_decrypt_uint256_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();
@@ -445,7 +445,7 @@ test("hlapi_decompress_public_key_then_encrypt_decrypt_uint256_small", (t) => {
test("hlapi_public_key_encrypt_decrypt_uint256_small", (t) => {
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let config = TfheConfigBuilder.with_custom_parameters(params_small).build();

View File

@@ -139,7 +139,7 @@ test("shortint_encrypt_decrypt", (t) => {
// Encryption using small keys
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let cks_small = Shortint.new_client_key(params_small);
@@ -175,7 +175,7 @@ test("shortint_compressed_encrypt_decrypt", (t) => {
// Encryption using small keys
// We don't have TUniform small params so use previous gaussian ones.
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let cks_small = Shortint.new_client_key(params_small);
@@ -195,7 +195,7 @@ test("shortint_compressed_encrypt_decrypt", (t) => {
test("shortint_public_encrypt_decrypt", (t) => {
let params_name_2_0 =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_0_KS_PBS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_0_KS_PBS_GAUSSIAN_2M128;
let params_2_0 = new ShortintParameters(params_name_2_0);
let cks = Shortint.new_client_key(params_2_0);
let pk = Shortint.new_public_key(cks);
@@ -210,7 +210,7 @@ test("shortint_public_encrypt_decrypt", (t) => {
// Small
let params_name_2_2_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_2_2_small = new ShortintParameters(params_name_2_2_small);
let cks_small = Shortint.new_client_key(params_2_2_small);
@@ -228,7 +228,7 @@ test("shortint_public_encrypt_decrypt", (t) => {
test("shortint_compressed_public_encrypt_decrypt", (t) => {
let params_name =
ShortintParametersName.V1_5_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128;
let params = new ShortintParameters(params_name);
let cks = Shortint.new_client_key(params);
let pk = Shortint.new_compressed_public_key(cks);
@@ -250,7 +250,7 @@ test("shortint_compressed_public_encrypt_decrypt", (t) => {
// Small
let params_name_small =
ShortintParametersName.V1_5_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
ShortintParametersName.V1_6_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128;
let params_small = new ShortintParameters(params_name_small);
let cks_small = Shortint.new_client_key(params_small);

View File

@@ -9,6 +9,7 @@ use crate::shortint::parameters::v1_2::*;
use crate::shortint::parameters::v1_3::*;
use crate::shortint::parameters::v1_4::*;
use crate::shortint::parameters::v1_5::*;
use crate::shortint::parameters::v1_6::*;
pub use crate::shortint::parameters::*;
use crate::shortint::parameters::{
ModulusSwitchNoiseReductionParams as RustModulusSwitchNoiseReductionParams,
@@ -497,6 +498,10 @@ expose_as_shortint_compact_public_key_parameters!(
PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
),
(
V1_6_PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
V1_6_PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
),
(
V1_5_PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
V1_5_PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
@@ -658,6 +663,7 @@ macro_rules! expose_as_shortint_pbs_parameters(
);
expose_as_shortint_pbs_parameters!(
(V1_6, M128),
(V1_5, M128),
(V1_4, M128),
(V1_3, M128),
@@ -692,6 +698,9 @@ macro_rules! expose_as_shortint_compression_parameters(
expose_as_shortint_compression_parameters!(
COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
// v1.6
V1_6_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
V1_6_COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
// v1.5
V1_5_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
V1_5_COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,

View File

@@ -30,7 +30,7 @@ pub fn ggsw_encryption_multiplicative_factor<Scalar: UnsignedInteger>(
cleartext.0.wrapping_neg(),
ciphertext_modulus,
)
.to_approximate_recomposition_summand(),
.to_recomposition_summand(),
CiphertextModulusKind::Native | CiphertextModulusKind::NonNativePowerOfTwo => {
let native_decomp_term =
DecompositionTerm::new(decomp_level, decomp_base_log, cleartext.0.wrapping_neg())
@@ -906,7 +906,7 @@ where
Scalar::ONE,
ciphertext_modulus,
)
.to_approximate_recomposition_summand();
.to_recomposition_summand();
let decoded = divide_round(*cleartext_ref.0, delta)
.wrapping_rem(Scalar::ONE << (decomp_level.0 * decomp_base_log.0));

View File

@@ -290,7 +290,7 @@ pub fn generate_glwe_keyswitch_key_other_mod<
input_key_polynomial.as_ref(),
ciphertext_modulus,
);
term.to_approximate_recomposition_summand(message_polynomial.as_mut());
term.to_recomposition_summand(message_polynomial.as_mut());
}
let decomposition_plaintexts_buffer =

View File

@@ -274,7 +274,7 @@ pub fn generate_lwe_keyswitch_key_other_mod<
CastInto::<OutputScalar>::cast_into(*input_key_element),
ciphertext_modulus,
)
.to_approximate_recomposition_summand();
.to_recomposition_summand();
}
encrypt_lwe_ciphertext_list(
@@ -1026,7 +1026,7 @@ pub fn generate_chunked_lwe_keyswitch_key_other_mod<
CastInto::<OutputScalar>::cast_into(*input_key_element),
ciphertext_modulus,
)
.to_approximate_recomposition_summand();
.to_recomposition_summand();
}
encrypt_lwe_ciphertext_list(

View File

@@ -637,7 +637,7 @@ where
if decomp.is_fresh() {
Some(decomp.fold(Scalar::ZERO, |acc, term| {
acc.wrapping_add_custom_mod(
term.to_approximate_recomposition_summand(),
term.to_recomposition_summand(),
ciphertext_modulus_as_scalar,
)
}))

View File

@@ -129,7 +129,7 @@ where
}
}
/// Turn this term into a summand.
/// Turn this term into a summand. The returned value is under the provided modulus.
///
/// If our member represents one $\tilde{\theta}\_i$ of the decomposition, this method returns
/// $\tilde{\theta}\_i\frac{v}{B^i}$ where $\lambda = \lceil{\log_2{q}}\rceil$ and
@@ -148,9 +148,9 @@ where
/// CiphertextModulus::try_new((1 << 64) - (1 << 32) + 1).unwrap(),
/// );
/// let output = decomposer.decompose(2u64.pow(52)).next().unwrap();
/// assert_eq!(output.to_approximate_recomposition_summand(), 2u64.pow(52));
/// assert_eq!(output.to_recomposition_summand(), 2u64.pow(52));
/// ```
pub fn to_approximate_recomposition_summand(&self) -> T {
pub fn to_recomposition_summand(&self) -> T {
let modulus_as_t = T::cast_from(self.ciphertext_modulus.get_custom_modulus());
let ciphertext_modulus_bit_count: usize = modulus_as_t.ceil_ilog2().try_into().unwrap();
let shift: usize = ciphertext_modulus_bit_count - self.base_log * self.level;
@@ -359,7 +359,8 @@ where
}
}
/// Fills the output tensor with the terms turned to summands.
/// Fills the output tensor with the terms turned to summands. The values are under the provided
/// modulus.
///
/// If our term tensor represents a set of $(\tilde{\theta}^{(a)}\_i)\_{a\in\mathbb{N}}$ of the
/// decomposition, this method fills the output tensor with a set of
@@ -381,10 +382,10 @@ where
/// let mut decomp = decomposer.decompose_slice(&input);
/// let term = decomp.next_term().unwrap();
/// let mut output = vec![0; 2];
/// term.to_approximate_recomposition_summand(&mut output);
/// term.to_recomposition_summand(&mut output);
/// assert!(output.iter().all(|&x| x == 1048576));
/// ```
pub fn to_approximate_recomposition_summand(&self, output: &mut [T]) {
pub fn to_recomposition_summand(&self, output: &mut [T]) {
assert_eq!(self.slice.len(), output.len());
let modulus_as_t = T::cast_from(self.ciphertext_modulus.get_custom_modulus());
let ciphertext_modulus_bit_count: usize = modulus_as_t.ceil_ilog2().try_into().unwrap();

View File

@@ -320,7 +320,7 @@ mod cpu {
use super::*;
use crate::high_level_api::booleans::compressed::CompressedFheBoolConformanceParams;
use crate::safe_serialization::{DeserializationConfig, SerializationConfig};
use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS;
use crate::shortint::parameters::test_params::TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
use crate::FheBoolConformanceParams;
use rand::random;
@@ -675,7 +675,7 @@ mod cpu {
#[test]
fn test_safe_deserialize_conformant_fhe_bool() {
let block_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS;
let block_params = TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
let (keys, server_key) = generate_keys(ConfigBuilder::with_custom_parameters(block_params));
set_server_key(server_key.clone());
@@ -698,7 +698,7 @@ mod cpu {
#[test]
fn test_safe_deserialize_conformant_compressed_fhe_bool() {
let block_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS;
let block_params = TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
let (keys, server_key) = generate_keys(ConfigBuilder::with_custom_parameters(block_params));
set_server_key(server_key.clone());
let clear_a = random::<bool>();

View File

@@ -850,7 +850,7 @@ mod zk {
fn conformance_zk_compact_ciphertext_list() {
let mut rng = thread_rng();
let params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
let cpk_params = PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;

View File

@@ -957,12 +957,13 @@ pub mod gpu {
mod tests {
use crate::prelude::*;
use crate::safe_serialization::{safe_deserialize, safe_serialize};
#[cfg(any(not(feature = "gpu"), feature = "strings"))]
use crate::shortint::parameters::test_params::TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
#[cfg(feature = "gpu")]
use crate::shortint::parameters::COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
#[cfg(feature = "gpu")]
use crate::shortint::parameters::PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
#[cfg(not(feature = "gpu"))]
use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
use crate::shortint::parameters::{
COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
};
@@ -983,9 +984,10 @@ mod tests {
),
#[cfg(not(feature = "gpu"))]
(
PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128.into(),
TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128.into(),
COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
),
#[cfg(feature = "gpu")]
(
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128.into(),
COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
@@ -1147,7 +1149,7 @@ mod tests {
#[cfg(feature = "strings")]
#[test]
fn test_compressed_strings_cpu() {
let params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
let config = crate::ConfigBuilder::with_custom_parameters(params)
.enable_compression(COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128)
.build();

View File

@@ -628,24 +628,25 @@ mod tests {
use super::*;
use crate::prelude::*;
use crate::safe_serialization::{safe_deserialize, safe_serialize};
use crate::shortint::parameters::current_params::*;
use crate::{generate_keys, set_server_key, ConfigBuilder, FheBool, FheInt32, FheUint32};
use crate::shortint::parameters::test_params::TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
#[cfg(feature = "gpu")]
use crate::shortint::parameters::v1_6::{
V1_6_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
V1_6_NOISE_SQUASHING_PARAM_GPU_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
V1_6_NOISE_SQUASHING_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
};
#[cfg(feature = "gpu")]
use crate::ConfigBuilder;
use crate::{generate_keys, set_server_key, FheBool, FheInt32, FheUint32};
use rand::Rng;
#[test]
fn test_compressed_squashed_noise_ciphertext_list() {
let params = V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let noise_squashing_params =
V1_5_NOISE_SQUASHING_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let noise_squashing_compression_params =
V1_5_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let meta_params = TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(params)
.enable_noise_squashing(noise_squashing_params)
.enable_noise_squashing_compression(noise_squashing_compression_params)
.build();
let (cks, sks) = generate_keys(config);
let (cks, sks) = generate_keys(meta_params);
let mut rng = rand::thread_rng();
@@ -692,11 +693,11 @@ mod tests {
#[test]
#[cfg(feature = "gpu")]
fn test_gpu_compressed_squashed_noise_ciphertext_list() {
let params = V1_5_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = V1_6_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let noise_squashing_params =
V1_5_NOISE_SQUASHING_PARAM_GPU_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_NOISE_SQUASHING_PARAM_GPU_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let noise_squashing_compression_params =
V1_5_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(params)
.enable_noise_squashing(noise_squashing_params)
@@ -754,11 +755,11 @@ mod tests {
#[test]
#[cfg(feature = "gpu")]
fn test_gpu_compressed_squashed_noise_ciphertext_list_multibit() {
let params = V1_5_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = V1_6_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let noise_squashing_params =
V1_5_NOISE_SQUASHING_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_NOISE_SQUASHING_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let noise_squashing_compression_params =
V1_5_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
V1_6_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(params)
.enable_noise_squashing(noise_squashing_params)

View File

@@ -238,8 +238,28 @@ impl<Id: FheUintId> FheUint<Id> {
Self::new(ct, key.tag.clone(), ReRandomizationMetadata::default())
}
#[cfg(feature = "gpu")]
InternalServerKey::Cuda(_cuda_key) => {
panic!("Gpu does not support this operation yet.")
InternalServerKey::Cuda(cuda_key) => {
let message_modulus = cuda_key.message_modulus();
let num_input_random_bits = num_input_random_bits_for_max_distance(
excluded_upper_bound,
max_distance,
message_modulus,
);
let num_blocks_output = Id::num_blocks(cuda_key.message_modulus()) as u64;
let ct = cuda_key
.pbs_key()
.par_generate_oblivious_pseudo_random_unsigned_custom_range(
seed,
num_input_random_bits,
excluded_upper_bound.get(),
num_blocks_output,
&cuda_key.streams,
);
Self::new(ct, cuda_key.tag.clone(), ReRandomizationMetadata::default())
}
#[cfg(feature = "hpu")]
InternalServerKey::Hpu(_device) => {
@@ -551,6 +571,8 @@ mod test {
};
use crate::prelude::FheDecrypt;
use crate::shortint::oprf::test::test_uniformity;
#[cfg(feature = "gpu")]
use crate::shortint::parameters::PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
use crate::{generate_keys, set_server_key, ClientKey, ConfigBuilder, FheUint8, Seed};
use num_bigint::BigUint;
@@ -678,19 +700,12 @@ mod test {
(random_input * excluded_upper_bound) >> num_input_random_bits
}
#[test]
fn test_uniformity_generate_oblivious_pseudo_random_custom_range() {
fn test_case_uniformity_generate_oblivious_pseudo_random_custom_range(cks: &ClientKey) {
let base_sample_count: usize = 10_000;
let p_value_limit: f64 = 0.001;
let params = PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(params).build();
let (cks, sks) = generate_keys(config);
rayon::broadcast(|_| set_server_key(sks.clone()));
let message_modulus = params.message_modulus;
let message_modulus = cks.message_modulus();
// [0.7, 0.1] for `max_distance` chosen to have `num_input_random_bits` be [2, 4]
// for any of the listed `excluded_upper_bound`
@@ -714,7 +729,7 @@ mod test {
sample_count,
p_value_limit,
message_modulus,
&cks,
cks,
excluded_upper_bound,
max_distance,
);
@@ -722,6 +737,26 @@ mod test {
}
}
#[test]
fn test_uniformity_generate_oblivious_pseudo_random_custom_range_cpu() {
let params = PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(params).build();
let (cks, sks) = generate_keys(config);
rayon::broadcast(|_| set_server_key(sks.clone()));
test_case_uniformity_generate_oblivious_pseudo_random_custom_range(&cks);
}
#[test]
#[cfg(feature = "gpu")]
fn test_uniformity_generate_oblivious_pseudo_random_custom_range_gpu() {
let params = PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(params).build();
let cks = ClientKey::generate(config);
let sks = crate::CompressedServerKey::new(&cks).decompress_to_gpu();
rayon::broadcast(|_| set_server_key(sks.clone()));
test_case_uniformity_generate_oblivious_pseudo_random_custom_range(&cks);
}
fn test_uniformity_generate_oblivious_pseudo_random_custom_range2(
sample_count: usize,
p_value_limit: f64,

View File

@@ -1,4 +1,10 @@
use crate::high_level_api::tests::{setup_cpu, setup_default_cpu};
use super::{
test_case_abs, test_case_flip, test_case_if_then_else, test_case_ilog2,
test_case_int32_bitwise, test_case_int32_compare, test_case_int32_div_rem,
test_case_int64_rotate, test_case_integer_casting, test_case_integer_compress_decompress,
test_case_leading_trailing_zeros_ones, test_case_min_max, test_case_scalar_flip,
};
use crate::high_level_api::tests::create_parameterized_test;
use crate::integer::I256;
use crate::prelude::{
CiphertextList, FheDecrypt, FheEncrypt, FheTryEncrypt, FheTryTrivialEncrypt,
@@ -8,16 +14,30 @@ use crate::shortint::parameters::test_params::{
TEST_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS_GAUSSIAN_2M128,
TEST_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS_GAUSSIAN_2M128,
TEST_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128,
TEST_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
TEST_PARAM_PROD_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
};
use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
use crate::{
generate_keys, set_server_key, CompactCiphertextList, CompactPublicKey, CompressedFheInt16,
CompressedFheInt32, CompressedFheInt32ConformanceParams, ConfigBuilder, DeserializationConfig,
FheInt256, FheInt32, FheInt32ConformanceParams, FheInt8, SerializationConfig,
generate_keys, set_server_key, ClientKey, CompactCiphertextList, CompactPublicKey,
CompressedFheInt16, CompressedFheInt32, CompressedFheInt32ConformanceParams, ConfigBuilder,
DeserializationConfig, FheInt256, FheInt32, FheInt32ConformanceParams, FheInt8,
SerializationConfig, ServerKey,
};
use rand::{random, thread_rng, Rng};
create_parameterized_test!(test_case_int32_compare);
create_parameterized_test!(test_case_int32_bitwise);
create_parameterized_test!(test_case_int64_rotate);
create_parameterized_test!(test_case_int32_div_rem);
create_parameterized_test!(test_case_integer_casting);
create_parameterized_test!(test_case_if_then_else);
create_parameterized_test!(test_case_flip);
create_parameterized_test!(test_case_scalar_flip);
create_parameterized_test!(test_case_abs);
create_parameterized_test!(test_case_min_max);
create_parameterized_test!(test_case_ilog2);
create_parameterized_test!(test_case_leading_trailing_zeros_ones);
create_parameterized_test!(test_case_integer_compress_decompress);
#[test]
fn test_signed_integer_compressed() {
let config = ConfigBuilder::default().build();
@@ -46,88 +66,6 @@ fn test_integer_compressed_small() {
assert_eq!(clear_decompressed, clear);
}
#[test]
fn test_int32_compare() {
let client_key = setup_default_cpu();
super::test_case_int32_compare(&client_key);
}
#[test]
fn test_int32_bitwise() {
let client_key = setup_default_cpu();
super::test_case_int32_bitwise(&client_key);
}
#[test]
fn test_int64_rotate() {
let client_key = setup_default_cpu();
super::test_case_int64_rotate(&client_key);
}
#[test]
fn test_multi_bit_rotate() {
let client_key = setup_cpu(Some(
TEST_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
));
super::test_case_int64_rotate(&client_key);
}
#[test]
fn test_int32_div_rem() {
let client_key = setup_default_cpu();
super::test_case_int32_div_rem(&client_key);
}
#[test]
fn test_multi_div_rem() {
let client_key = setup_cpu(Some(
TEST_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
));
super::test_case_int32_div_rem(&client_key);
}
#[test]
fn test_integer_casting() {
let client_key = setup_default_cpu();
super::test_case_integer_casting(&client_key);
}
#[test]
fn test_if_then_else() {
let client_key = setup_default_cpu();
super::test_case_if_then_else(&client_key);
}
#[test]
fn test_flip() {
let client_key = setup_default_cpu();
super::test_case_flip(&client_key);
}
#[test]
fn test_scalar_flip() {
let client_key = setup_default_cpu();
super::test_case_scalar_flip(&client_key);
}
#[test]
fn test_abs() {
let client_key = setup_default_cpu();
super::test_case_abs(&client_key);
}
#[test]
fn test_integer_compress_decompress() {
let client_key = setup_default_cpu();
super::test_case_integer_compress_decompress(&client_key);
}
#[test]
fn test_min_max() {
let client_key = setup_default_cpu();
super::test_case_min_max(&client_key);
}
#[test]
fn test_trivial_fhe_int8() {
let config = ConfigBuilder::default().build();
@@ -155,6 +93,7 @@ fn test_trivial_fhe_int256_small() {
let clear: I256 = a.decrypt(&client_key);
assert_eq!(clear, clear_a);
}
#[test]
fn test_compact_public_key_big() {
let config = ConfigBuilder::default()
@@ -191,65 +130,73 @@ fn test_compact_public_key_small() {
assert_eq!(clear, -123i8);
}
#[test]
fn test_ilog2() {
let client_key = setup_default_cpu();
super::test_case_ilog2(&client_key);
}
#[test]
fn test_leading_trailing_zeros_ones() {
let client_key = setup_default_cpu();
super::test_case_leading_trailing_zeros_ones(&client_key);
}
#[test]
fn test_safe_deserialize_conformant_fhe_int32() {
let block_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let (client_key, server_key) =
generate_keys(ConfigBuilder::with_custom_parameters(block_params));
set_server_key(server_key.clone());
fn test_case_safe_deserialize_conformant_fhe_int32(client_key: &ClientKey, server_key: &ServerKey) {
let clear_a = random::<i32>();
let a = FheInt32::encrypt(clear_a, &client_key);
let a = FheInt32::encrypt(clear_a, client_key);
let mut serialized = vec![];
SerializationConfig::new(1 << 20)
.serialize_into(&a, &mut serialized)
.unwrap();
let params = FheInt32ConformanceParams::from(&server_key);
let params = FheInt32ConformanceParams::from(server_key);
let deserialized_a = DeserializationConfig::new(1 << 20)
.deserialize_from::<FheInt32>(serialized.as_slice(), &params)
.unwrap();
let decrypted: i32 = deserialized_a.decrypt(&client_key);
let decrypted: i32 = deserialized_a.decrypt(client_key);
assert_eq!(decrypted, clear_a);
let params = FheInt32ConformanceParams::from(block_params);
assert!(deserialized_a.is_conformant(&params));
}
#[test]
fn test_safe_deserialize_conformant_compressed_fhe_int32() {
let block_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let (client_key, server_key) =
generate_keys(ConfigBuilder::with_custom_parameters(block_params));
fn test_safe_deserialize_conformant_fhe_int32_default() {
let (client_key, server_key) = generate_keys(ConfigBuilder::default());
set_server_key(server_key.clone());
test_case_safe_deserialize_conformant_fhe_int32(&client_key, &server_key);
}
#[test]
fn test_safe_deserialize_conformant_fhe_int32_prod_param() {
let (client_key, server_key) = generate_keys(ConfigBuilder::with_custom_parameters(
TEST_PARAM_PROD_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
));
set_server_key(server_key.clone());
test_case_safe_deserialize_conformant_fhe_int32(&client_key, &server_key);
}
fn test_case_safe_deserialize_conformant_compressed_fhe_int32(
client_key: &ClientKey,
server_key: &ServerKey,
) {
let clear_a = random::<i32>();
let a = CompressedFheInt32::encrypt(clear_a, &client_key);
let a = CompressedFheInt32::encrypt(clear_a, client_key);
let mut serialized = vec![];
SerializationConfig::new(1 << 20)
.serialize_into(&a, &mut serialized)
.unwrap();
let params = CompressedFheInt32ConformanceParams::from(&server_key);
let params = CompressedFheInt32ConformanceParams::from(server_key);
let deserialized_a = DeserializationConfig::new(1 << 20)
.deserialize_from::<CompressedFheInt32>(serialized.as_slice(), &params)
.unwrap();
let params = CompressedFheInt32ConformanceParams::from(block_params);
assert!(deserialized_a.is_conformant(&params));
let decrypted: i32 = deserialized_a.decompress().decrypt(&client_key);
let decrypted: i32 = deserialized_a.decompress().decrypt(client_key);
assert_eq!(decrypted, clear_a);
}
#[test]
fn test_safe_deserialize_conformant_compressed_fhe_int32_default() {
let (client_key, server_key) = generate_keys(ConfigBuilder::default());
set_server_key(server_key.clone());
test_case_safe_deserialize_conformant_compressed_fhe_int32(&client_key, &server_key);
}
#[test]
fn test_safe_deserialize_conformant_compressed_fhe_int32_prod_param() {
let (client_key, server_key) = generate_keys(ConfigBuilder::with_custom_parameters(
TEST_PARAM_PROD_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
));
set_server_key(server_key.clone());
test_case_safe_deserialize_conformant_compressed_fhe_int32(&client_key, &server_key);
}

View File

@@ -443,11 +443,14 @@ fn test_case_abs(cks: &ClientKey) {
}
fn test_case_integer_compress_decompress(cks: &ClientKey) {
let a = FheInt8::try_encrypt(-83i8, cks).unwrap();
let mut rng = rand::thread_rng();
let clear_a: i8 = rng.gen();
let a = FheInt8::try_encrypt(clear_a, cks).unwrap();
let clear: i8 = a.compress().decompress().decrypt(cks);
assert_eq!(clear, -83i8);
assert_eq!(clear, clear_a);
}
fn test_case_leading_trailing_zeros_ones(cks: &ClientKey) {

View File

@@ -1850,7 +1850,10 @@ mod test {
use super::*;
use crate::core_crypto::prelude::UnsignedInteger;
use crate::prelude::*;
use crate::shortint::parameters::{AtomicPatternKind, PARAM_MESSAGE_2_CARRY_2_KS_PBS};
use crate::shortint::parameters::{
AtomicPatternKind, PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128,
PARAM_MESSAGE_2_CARRY_2_KS_PBS,
};
use crate::shortint::{CiphertextModulus, PBSOrder};
use crate::{generate_keys, set_server_key, ConfigBuilder, FheUint8};
use rand::{thread_rng, Rng};
@@ -1880,7 +1883,7 @@ mod test {
let ct = FheUint8::try_encrypt(0_u64, &client_key).unwrap();
assert!(ct.is_conformant(&FheUintConformanceParams::from(
PARAM_MESSAGE_2_CARRY_2_KS_PBS,
PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128,
)));
let breaker_lists = [
@@ -1940,7 +1943,7 @@ mod test {
breaker(i, &mut ct_clone);
assert!(!ct_clone.is_conformant(&FheUintConformanceParams::from(
PARAM_MESSAGE_2_CARRY_2_KS_PBS,
PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128,
)));
}
}
@@ -1957,7 +1960,7 @@ mod test {
let ct = FheUint8::try_encrypt(0_u64, &client_key).unwrap();
assert!(ct.is_conformant(&FheUintConformanceParams::from(
PARAM_MESSAGE_2_CARRY_2_KS_PBS,
PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128,
)));
let mut rng = thread_rng();
@@ -1975,7 +1978,7 @@ mod test {
}
assert!(ct.is_conformant(&FheUintConformanceParams::from(
PARAM_MESSAGE_2_CARRY_2_KS_PBS,
PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128,
)));
ct_clone += &ct_clone.clone();

View File

@@ -263,7 +263,7 @@ where
mod test {
use super::*;
use crate::core_crypto::prelude::UnsignedInteger;
use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
use crate::shortint::{CiphertextModulus, CompressedCiphertext};
use crate::{generate_keys, set_server_key, CompressedFheUint8, ConfigBuilder};
use rand::{thread_rng, Rng};
@@ -315,7 +315,7 @@ mod test {
let ct = CompressedFheUint8::try_encrypt(0_u64, &client_key).unwrap();
assert!(ct.is_conformant(&CompressedFheUintConformanceParams::from(
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128
)));
let breaker_lists = [
@@ -340,7 +340,7 @@ mod test {
assert!(
!ct_clone.is_conformant(&CompressedFheUintConformanceParams::from(
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128
))
);
}
@@ -373,7 +373,7 @@ mod test {
assert!(
!ct_clone.is_conformant(&CompressedFheUintConformanceParams::from(
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128
))
);
}
@@ -391,7 +391,7 @@ mod test {
let ct = CompressedFheUint8::try_encrypt(0_u64, &client_key).unwrap();
assert!(ct.is_conformant(&CompressedFheUintConformanceParams::from(
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128
)));
let mut rng = thread_rng();
@@ -410,9 +410,10 @@ mod test {
.seed
.0 = rng.gen::<u128>();
}
assert!(
ct_clone.is_conformant(&CompressedFheUintConformanceParams::from(
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128
))
);

View File

@@ -1,18 +1,112 @@
use crate::conformance::ListSizeConstraint;
use crate::high_level_api::prelude::*;
use crate::high_level_api::tests::{setup_cpu, setup_default_cpu};
use crate::high_level_api::tests::create_parameterized_test;
use crate::high_level_api::{generate_keys, set_server_key, ConfigBuilder, FheUint8};
use crate::integer::U256;
use crate::safe_serialization::{DeserializationConfig, SerializationConfig};
use crate::shortint::parameters::test_params::*;
use crate::shortint::parameters::*;
use crate::{
ClientKey, CompactCiphertextList, CompactCiphertextListConformanceParams, CompactPublicKey,
CompressedCompactPublicKey, CompressedFheUint16, CompressedFheUint256, CompressedFheUint32,
CompressedFheUint32ConformanceParams, CompressedPublicKey, CompressedServerKey, FheInt16,
FheInt32, FheInt8, FheUint128, FheUint16, FheUint256, FheUint32, FheUint32ConformanceParams,
use crate::{CompressedFheUint256, CompressedPublicKey, FheUint256};
use super::{
test_case_bitslice, test_case_clone, test_case_flip, test_case_if_then_else,
test_case_if_then_zero, test_case_ilog2, test_case_integer_casting, test_case_is_even_is_odd,
test_case_leading_trailing_zeros_ones, test_case_match_value, test_case_match_value_or,
test_case_min_max, test_case_scalar_flip, test_case_sum, test_case_uint256_trivial,
test_case_uint32_arith, test_case_uint32_arith_assign, test_case_uint32_bitwise,
test_case_uint32_bitwise_assign, test_case_uint32_div_rem, test_case_uint32_quickstart,
test_case_uint32_rotate, test_case_uint32_scalar_arith, test_case_uint32_scalar_arith_assign,
test_case_uint32_scalar_bitwise, test_case_uint32_shift, test_case_uint64_quickstart,
test_case_uint8_compare, test_case_uint8_compare_scalar, test_case_uint8_quickstart,
test_case_uint8_trivial, test_dedicated_compact_public_key,
test_dedicated_compressed_compact_public_key, test_integer_compress_decompress,
test_integer_compressed, test_safe_deserialize_conformant_compact_fhe_uint32,
test_safe_deserialize_conformant_compressed_fhe_uint32,
test_safe_deserialize_conformant_fhe_uint32, test_scalar_shift_when_clear_type_is_small,
};
use rand::prelude::*;
create_parameterized_test!(test_case_match_value_or);
create_parameterized_test!(test_case_uint8_quickstart);
create_parameterized_test!(test_case_uint32_quickstart);
create_parameterized_test!(test_case_uint64_quickstart);
create_parameterized_test!(test_case_uint32_arith);
create_parameterized_test!(test_case_uint32_arith_assign);
create_parameterized_test!(test_case_uint32_scalar_arith);
create_parameterized_test!(test_case_uint32_scalar_arith_assign);
create_parameterized_test!(test_case_clone);
create_parameterized_test!(test_case_uint8_compare);
create_parameterized_test!(test_case_uint8_compare_scalar);
create_parameterized_test!(test_case_uint32_shift);
create_parameterized_test!(test_case_uint32_bitwise);
create_parameterized_test!(test_case_uint32_bitwise_assign);
create_parameterized_test!(test_case_uint32_scalar_bitwise);
create_parameterized_test!(test_case_uint32_rotate);
create_parameterized_test!(test_case_uint32_div_rem);
create_parameterized_test!(test_case_if_then_else);
create_parameterized_test!(test_case_flip);
create_parameterized_test!(test_case_scalar_flip);
create_parameterized_test!(test_case_ilog2);
create_parameterized_test!(test_case_is_even_is_odd);
create_parameterized_test!(test_case_bitslice);
create_parameterized_test!(test_case_leading_trailing_zeros_ones);
create_parameterized_test!(test_case_sum);
create_parameterized_test!(test_case_min_max);
create_parameterized_test!(test_case_match_value);
create_parameterized_test!(test_case_uint8_trivial);
create_parameterized_test!(test_case_uint256_trivial);
create_parameterized_test!(test_case_integer_casting);
create_parameterized_test!(test_scalar_shift_when_clear_type_is_small);
create_parameterized_test!(test_integer_compress_decompress);
create_parameterized_test!(test_safe_deserialize_conformant_compact_fhe_uint32);
create_parameterized_test!(test_integer_compressed);
create_parameterized_test!(test_case_if_then_zero);
#[test]
fn test_safe_deserialize_conformant_fhe_uint32_default() {
let (client_key, server_key) = generate_keys(ConfigBuilder::default());
test_safe_deserialize_conformant_fhe_uint32(&client_key, &server_key);
}
#[test]
fn test_safe_deserialize_conformant_compressed_fhe_uint32_default() {
let (client_key, server_key) = generate_keys(ConfigBuilder::default());
test_safe_deserialize_conformant_compressed_fhe_uint32(&client_key, &server_key);
}
#[test]
fn test_integer_compressed_small() {
let config =
ConfigBuilder::with_custom_parameters(TEST_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128)
.build();
let (client_key, _) = generate_keys(config);
test_integer_compressed(&client_key);
}
#[test]
fn test_dedicated_compact_public_default() {
let param_fhe = TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
let param_pke_only = TEST_PARAM_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2;
let param_ksk = TEST_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(param_fhe)
.use_dedicated_compact_public_key_parameters((param_pke_only, param_ksk))
.build();
let (client_key, sks) = generate_keys(config);
set_server_key(sks);
test_dedicated_compact_public_key(&client_key);
}
#[test]
fn test_dedicated_compressed_compact_public_default() {
let param_fhe = TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
let param_pke_only = TEST_PARAM_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2;
let param_ksk = TEST_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(param_fhe)
.use_dedicated_compact_public_key_parameters((param_pke_only, param_ksk))
.build();
let (client_key, sks) = generate_keys(config);
set_server_key(sks);
test_dedicated_compressed_compact_public_key(&client_key);
}
#[test]
fn test_integer_compressed_can_be_serialized() {
@@ -31,176 +125,15 @@ fn test_integer_compressed_can_be_serialized() {
}
#[test]
fn test_integer_compressed() {
let config = ConfigBuilder::default().build();
let (client_key, _) = generate_keys(config);
let clear = 12_837u16;
let compressed = CompressedFheUint16::try_encrypt(clear, &client_key).unwrap();
let decompressed = FheUint16::from(compressed.decompress());
let clear_decompressed: u16 = decompressed.decrypt(&client_key);
assert_eq!(clear_decompressed, clear);
}
#[test]
fn test_integer_compressed_small() {
let config =
ConfigBuilder::with_custom_parameters(TEST_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128)
.build();
let (client_key, _) = generate_keys(config);
let clear = 12_837u16;
let compressed = CompressedFheUint16::try_encrypt(clear, &client_key).unwrap();
let decompressed = FheUint16::from(compressed.decompress());
let clear_decompressed: u16 = decompressed.decrypt(&client_key);
assert_eq!(clear_decompressed, clear);
}
#[test]
fn test_uint8_quickstart() {
let client_key = setup_default_cpu();
super::test_case_uint8_quickstart(&client_key);
}
#[test]
fn test_uint32_quickstart() {
let client_key = setup_default_cpu();
super::test_case_uint32_quickstart(&client_key);
}
#[test]
fn test_uint64_quickstart() {
let client_key = setup_default_cpu();
super::test_case_uint64_quickstart(&client_key);
}
#[test]
fn test_uint32_arith() {
let client_key = setup_default_cpu();
super::test_case_uint32_arith(&client_key);
}
#[test]
fn test_uint32_arith_assign() {
let client_key = setup_default_cpu();
super::test_case_uint32_arith_assign(&client_key);
}
#[test]
fn test_uint32_scalar_arith() {
let client_key = setup_default_cpu();
super::test_case_uint32_scalar_arith(&client_key);
}
#[test]
fn test_uint32_scalar_arith_assign() {
let client_key = setup_default_cpu();
super::test_case_uint32_scalar_arith_assign(&client_key);
}
#[test]
fn test_uint32_clone() {
let client_key = setup_default_cpu();
super::test_case_clone(&client_key);
}
#[test]
fn test_uint8_compare() {
let client_key = setup_default_cpu();
super::test_case_uint8_compare(&client_key);
}
#[test]
fn test_uint8_compare_scalar() {
let client_key = setup_default_cpu();
super::test_case_uint8_compare_scalar(&client_key);
}
#[test]
fn test_uint32_shift() {
let client_key = setup_default_cpu();
super::test_case_uint32_shift(&client_key);
}
#[test]
fn test_uint32_shift_multibit() {
let config = ConfigBuilder::default()
.use_custom_parameters(TEST_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64)
.build();
let (client_key, server_key) = generate_keys(config);
set_server_key(server_key);
super::test_case_uint32_shift(&client_key);
}
#[test]
fn test_uint32_bitwise() {
let client_key = setup_default_cpu();
super::test_case_uint32_bitwise(&client_key);
}
#[test]
fn test_uint32_bitwise_assign() {
let client_key = setup_default_cpu();
super::test_case_uint32_bitwise_assign(&client_key);
}
#[test]
fn test_uint32_scalar_bitwise() {
let client_key = setup_default_cpu();
super::test_case_uint32_scalar_bitwise(&client_key);
}
#[test]
fn test_uint32_rotate() {
let client_key = setup_default_cpu();
super::test_case_uint32_rotate(&client_key);
}
#[test]
fn test_multi_bit_rotate() {
let client_key = setup_cpu(Some(
TEST_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
));
super::test_case_uint32_rotate(&client_key);
}
#[test]
fn test_uint32_div_rem() {
let client_key = setup_default_cpu();
super::test_case_uint32_div_rem(&client_key);
}
#[test]
fn test_multi_div_rem() {
let client_key = setup_cpu(Some(
TEST_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
));
super::test_case_uint32_div_rem(&client_key);
}
#[test]
fn test_small_uint128() {
fn test_case_uint64_quickstart_small() {
let config =
ConfigBuilder::with_custom_parameters(TEST_PARAM_MESSAGE_2_CARRY_2_PBS_KS_GAUSSIAN_2M128)
.build();
let (cks, sks) = generate_keys(config);
let mut rng = rand::thread_rng();
let clear_a = rng.gen::<u128>();
let clear_b = rng.gen::<u128>();
let a = FheUint128::try_encrypt(clear_a, &cks).unwrap();
let b = FheUint128::try_encrypt(clear_b, &cks).unwrap();
set_server_key(sks);
let c = a + b;
let decrypted: u128 = c.decrypt(&cks);
assert_eq!(decrypted, clear_a.wrapping_add(clear_b));
test_case_uint64_quickstart(&cks);
}
#[test]
@@ -227,442 +160,3 @@ fn test_decompressed_public_key_encrypt() {
let clear: u8 = a.decrypt(&client_key);
assert_eq!(clear, 255u8);
}
#[test]
fn test_compact_public_key_big() {
let config = ConfigBuilder::default()
.use_custom_parameters(TEST_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS_GAUSSIAN_2M128)
.build();
let (client_key, _) = generate_keys(config);
let public_key = CompactPublicKey::new(&client_key);
let compact_list = CompactCiphertextList::builder(&public_key)
.push(255u8)
.build();
let expanded = compact_list.expand().unwrap();
let a: FheUint8 = expanded.get(0).unwrap().unwrap();
let clear: u8 = a.decrypt(&client_key);
assert_eq!(clear, 255u8);
}
#[test]
fn test_compact_public_key_small() {
let config = ConfigBuilder::default()
.use_custom_parameters(TEST_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS_GAUSSIAN_2M128)
.build();
let (client_key, _) = generate_keys(config);
let public_key = CompactPublicKey::new(&client_key);
let compact_list = CompactCiphertextList::builder(&public_key)
.push(255u8)
.build();
let expanded = compact_list.expand().unwrap();
let a: FheUint8 = expanded.get(0).unwrap().unwrap();
let clear: u8 = a.decrypt(&client_key);
assert_eq!(clear, 255u8);
}
#[test]
fn test_integer_compress_decompress() {
let config = ConfigBuilder::default().build();
let (client_key, server_key) = generate_keys(config);
set_server_key(server_key);
let a = FheUint8::try_encrypt(213u8, &client_key).unwrap();
let clear: u8 = a.compress().decompress().decrypt(&client_key);
assert_eq!(clear, 213u8);
}
#[test]
fn test_trivial_uint8() {
let client_key = setup_default_cpu();
super::test_case_uint8_trivial(&client_key);
}
#[test]
fn test_trivial_uint256_small() {
let client_key = setup_default_cpu();
super::test_case_uint256_trivial(&client_key);
}
#[test]
fn test_integer_casting() {
let config = ConfigBuilder::default().build();
let (client_key, server_key) = generate_keys(config);
set_server_key(server_key);
let mut rng = rand::thread_rng();
let clear = rng.gen::<u16>();
// Downcasting then Upcasting
{
let a = FheUint16::encrypt(clear, &client_key);
// Downcasting
let a: FheUint8 = a.cast_into();
let da: u8 = a.decrypt(&client_key);
assert_eq!(da, clear as u8);
// Upcasting
let a: FheUint32 = a.cast_into();
let da: u32 = a.decrypt(&client_key);
assert_eq!(da, (clear as u8) as u32);
}
// Upcasting then Downcasting
{
let a = FheUint16::encrypt(clear, &client_key);
// Upcasting
let a = FheUint32::cast_from(a);
let da: u32 = a.decrypt(&client_key);
assert_eq!(da, clear as u32);
// Downcasting
let a = FheUint8::cast_from(a);
let da: u8 = a.decrypt(&client_key);
assert_eq!(da, (clear as u32) as u8);
}
// Casting to self, it not useful but is supported
{
let a = FheUint16::encrypt(clear, &client_key);
let a = FheUint16::cast_from(a);
let da: u16 = a.decrypt(&client_key);
assert_eq!(da, clear);
}
// Downcasting to smaller signed integer then Upcasting back to unsigned
{
let clear = rng.gen_range((i16::MAX) as u16 + 1..u16::MAX);
let a = FheUint16::encrypt(clear, &client_key);
// Downcasting
let a: FheInt8 = a.cast_into();
let da: i8 = a.decrypt(&client_key);
assert_eq!(da, clear as i8);
// Upcasting
let a: FheUint32 = a.cast_into();
let da: u32 = a.decrypt(&client_key);
assert_eq!(da, (clear as i8) as u32);
}
{
let clear = rng.gen_range(i16::MIN..0);
let a = FheInt16::encrypt(clear, &client_key);
// Upcasting
let a: FheUint32 = a.cast_into();
let da: u32 = a.decrypt(&client_key);
assert_eq!(da, clear as u32);
}
// Upcasting to bigger signed integer then downcasting back to unsigned
{
let clear = rng.gen_range((i16::MAX) as u16 + 1..u16::MAX);
let a = FheUint16::encrypt(clear, &client_key);
// Upcasting
let a: FheInt32 = a.cast_into();
let da: i32 = a.decrypt(&client_key);
assert_eq!(da, clear as i32);
// Downcasting
let a: FheUint16 = a.cast_into();
let da: u16 = a.decrypt(&client_key);
assert_eq!(da, (clear as i32) as u16);
}
}
#[test]
fn test_if_then_else() {
let client_key = setup_default_cpu();
super::test_case_if_then_else(&client_key);
}
#[test]
fn test_if_then_zero() {
let client_key = setup_default_cpu();
super::test_case_if_then_zero(&client_key);
}
#[test]
fn test_flip() {
let client_key = setup_default_cpu();
super::test_case_flip(&client_key);
}
#[test]
fn test_scalar_flip() {
let client_key = setup_default_cpu();
super::test_case_scalar_flip(&client_key);
}
#[test]
fn test_scalar_shift_when_clear_type_is_small() {
// This is a regression tests
// The goal is to make sure that doing a scalar shift / rotate
// with a clear type that does not have enough bits to represent
// the number of bits of the fhe type correctly works.
let config = ConfigBuilder::default().build();
let (client_key, server_key) = generate_keys(config);
set_server_key(server_key);
let mut a = FheUint256::encrypt(U256::ONE, &client_key);
// The fhe type has 256 bits, the clear type is u8,
// a u8 cannot represent the value '256'.
// This used to result in the shift/rotate panicking
let clear = 1u8;
let _ = &a << clear;
let _ = &a >> clear;
let _ = (&a).rotate_left(clear);
let _ = (&a).rotate_right(clear);
a <<= clear;
a >>= clear;
a.rotate_left_assign(clear);
a.rotate_right_assign(clear);
}
#[test]
fn test_ilog2() {
let client_key = setup_default_cpu();
super::test_case_ilog2(&client_key);
}
#[test]
fn test_is_even_is_odd() {
let client_key = setup_default_cpu();
super::test_case_is_even_is_odd(&client_key);
}
#[test]
fn test_bitslice() {
let client_key = setup_default_cpu();
super::test_case_bitslice(&client_key);
}
#[test]
fn test_leading_trailing_zeros_ones() {
let client_key = setup_default_cpu();
super::test_case_leading_trailing_zeros_ones(&client_key);
}
#[test]
fn test_sum() {
let client_key = setup_default_cpu();
super::test_case_sum(&client_key);
}
#[test]
fn test_min_max() {
let client_key = setup_default_cpu();
super::test_case_min_max(&client_key);
}
#[test]
fn test_match_value() {
let client_key = setup_default_cpu();
super::test_case_match_value(&client_key);
}
#[test]
fn test_safe_deserialize_conformant_fhe_uint32() {
let block_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let (client_key, server_key) =
generate_keys(ConfigBuilder::with_custom_parameters(block_params));
set_server_key(server_key.clone());
let clear_a = random::<u32>();
let a = FheUint32::encrypt(clear_a, &client_key);
let mut serialized = vec![];
SerializationConfig::new(1 << 20)
.serialize_into(&a, &mut serialized)
.unwrap();
let params = FheUint32ConformanceParams::from(&server_key);
let deserialized_a = DeserializationConfig::new(1 << 20)
.deserialize_from::<FheUint32>(serialized.as_slice(), &params)
.unwrap();
let decrypted: u32 = deserialized_a.decrypt(&client_key);
assert_eq!(decrypted, clear_a);
assert!(deserialized_a.is_conformant(&FheUint32ConformanceParams::from(block_params)));
}
#[test]
fn test_safe_deserialize_conformant_compressed_fhe_uint32() {
let block_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS;
let (client_key, server_key) =
generate_keys(ConfigBuilder::with_custom_parameters(block_params));
set_server_key(server_key.clone());
let clear_a = random::<u32>();
let a = CompressedFheUint32::encrypt(clear_a, &client_key);
let mut serialized = vec![];
SerializationConfig::new(1 << 20)
.serialize_into(&a, &mut serialized)
.unwrap();
let params = CompressedFheUint32ConformanceParams::from(&server_key);
let deserialized_a = DeserializationConfig::new(1 << 20)
.deserialize_from::<CompressedFheUint32>(serialized.as_slice(), &params)
.unwrap();
assert!(deserialized_a.is_conformant(&CompressedFheUint32ConformanceParams::from(block_params)));
let decrypted: u32 = deserialized_a.decompress().decrypt(&client_key);
assert_eq!(decrypted, clear_a);
}
#[test]
fn test_safe_deserialize_conformant_compact_fhe_uint32() {
let block_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS;
let (client_key, server_key) =
generate_keys(ConfigBuilder::with_custom_parameters(block_params));
set_server_key(server_key);
let pk = CompactPublicKey::new(&client_key);
let clears = [random::<u32>(), random::<u32>(), random::<u32>()];
let a = CompactCiphertextList::builder(&pk)
.extend(clears.iter().copied())
.build();
let mut serialized = vec![];
SerializationConfig::new(1 << 20)
.serialize_into(&a, &mut serialized)
.unwrap();
let params = CompactCiphertextListConformanceParams::from_parameters_and_size_constraint(
pk.parameters(),
ListSizeConstraint::exact_size(clears.len()),
)
.allow_unpacked();
let deserialized_a = DeserializationConfig::new(1 << 20)
.deserialize_from::<CompactCiphertextList>(serialized.as_slice(), &params)
.unwrap();
let expander = deserialized_a.expand().unwrap();
for (i, clear) in clears.into_iter().enumerate() {
let encrypted: FheUint32 = expander.get(i).unwrap().unwrap();
let decrypted: u32 = encrypted.decrypt(&client_key);
assert_eq!(decrypted, clear);
}
assert!(deserialized_a.is_conformant(&params));
}
#[test]
fn test_cpk_encrypt_cast_compute_hl() {
let param_pke_only = PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let param_fhe = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let param_ksk = PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let num_block = 4usize;
assert_eq!(param_pke_only.message_modulus, param_fhe.message_modulus);
assert_eq!(param_pke_only.carry_modulus, param_fhe.carry_modulus);
let modulus = param_fhe.message_modulus.0.pow(num_block as u32);
let (client_key, server_key) = generate_keys(
ConfigBuilder::with_custom_parameters(param_fhe)
.use_dedicated_compact_public_key_parameters((param_pke_only, param_ksk)),
);
set_server_key(server_key);
use rand::Rng;
let mut rng = rand::thread_rng();
let input_msg: u64 = rng.gen_range(0..modulus);
let pk = CompactPublicKey::new(&client_key);
// Encrypt a value and cast
let mut builder = CompactCiphertextList::builder(&pk);
let list = builder
.push_with_num_bits(input_msg, 8)
.unwrap()
.build_packed();
let expander = list.expand().unwrap();
let ct1_extracted_and_cast = expander.get::<FheUint8>(0).unwrap().unwrap();
let sanity_cast: u64 = ct1_extracted_and_cast.decrypt(&client_key);
assert_eq!(sanity_cast, input_msg);
let multiplier = rng.gen_range(0..modulus);
// Classical AP: DP, KS, PBS
let mul = &ct1_extracted_and_cast * multiplier as u8;
// High level decryption and test
let clear: u64 = mul.decrypt(&client_key);
assert_eq!(clear, (input_msg * multiplier) % modulus);
}
#[test]
fn test_compressed_cpk_encrypt_cast_compute_hl() {
let param_pke_only = PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let param_fhe = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let param_ksk = PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let num_block = 4usize;
assert_eq!(param_pke_only.message_modulus, param_fhe.message_modulus);
assert_eq!(param_pke_only.carry_modulus, param_fhe.carry_modulus);
let modulus = param_fhe.message_modulus.0.pow(num_block as u32);
let config = ConfigBuilder::with_custom_parameters(param_fhe)
.use_dedicated_compact_public_key_parameters((param_pke_only, param_ksk))
.build();
let client_key = ClientKey::generate(config);
let compressed_server_key = CompressedServerKey::new(&client_key);
let server_key = compressed_server_key.decompress();
set_server_key(server_key);
use rand::Rng;
let mut rng = rand::thread_rng();
let input_msg: u64 = rng.gen_range(0..modulus);
let compressed_pk = CompressedCompactPublicKey::new(&client_key);
let pk = compressed_pk.decompress();
// Encrypt a value and cast
let mut builder = CompactCiphertextList::builder(&pk);
let list = builder
.push_with_num_bits(input_msg, 8)
.unwrap()
.build_packed();
let expander = list.expand().unwrap();
let ct1_extracted_and_cast = expander.get::<FheUint8>(0).unwrap().unwrap();
let sanity_cast: u64 = ct1_extracted_and_cast.decrypt(&client_key);
assert_eq!(sanity_cast, input_msg);
let multiplier = rng.gen_range(0..modulus);
// Classical AP: DP, KS, PBS
let mul = &ct1_extracted_and_cast * multiplier as u8;
// High level decryption and test
let clear: u64 = mul.decrypt(&client_key);
assert_eq!(clear, (input_msg * multiplier) % modulus);
}
#[test]
fn test_match_value_or() {
let client_key = setup_default_cpu();
super::test_case_match_value_or(&client_key);
}

View File

@@ -1,8 +1,15 @@
use crate::conformance::ListSizeConstraint;
use crate::high_level_api::traits::BitSlice;
use crate::integer::U256;
use crate::prelude::*;
use crate::{ClientKey, FheBool, FheUint256, FheUint32, FheUint64, FheUint8, MatchValues};
use rand::{thread_rng, Rng};
use crate::{
ClientKey, CompactCiphertextList, CompactCiphertextListConformanceParams, CompactPublicKey,
CompressedCompactPublicKey, CompressedFheUint16, CompressedFheUint32,
CompressedFheUint32ConformanceParams, DeserializationConfig, FheBool, FheInt16, FheInt32,
FheInt8, FheUint16, FheUint256, FheUint32, FheUint32ConformanceParams, FheUint64, FheUint8,
MatchValues, SerializationConfig, ServerKey,
};
use rand::{random, thread_rng, Rng};
use std::collections::HashMap;
mod cpu;
@@ -299,6 +306,193 @@ fn test_case_uint8_compare_scalar(client_key: &ClientKey) {
assert_eq!(decrypted_result, clear_result);
}
fn test_safe_deserialize_conformant_fhe_uint32(client_key: &ClientKey, server_key: &ServerKey) {
let clear_a = random::<u32>();
let a = FheUint32::encrypt(clear_a, client_key);
let mut serialized = vec![];
SerializationConfig::new(1 << 20)
.serialize_into(&a, &mut serialized)
.unwrap();
let params = FheUint32ConformanceParams::from(server_key);
let deserialized_a = DeserializationConfig::new(1 << 20)
.deserialize_from::<FheUint32>(serialized.as_slice(), &params)
.unwrap();
let decrypted: u32 = deserialized_a.decrypt(client_key);
assert_eq!(decrypted, clear_a);
assert!(deserialized_a.is_conformant(&params));
}
fn test_safe_deserialize_conformant_compressed_fhe_uint32(
client_key: &ClientKey,
server_key: &ServerKey,
) {
let clear_a = random::<u32>();
let a = CompressedFheUint32::encrypt(clear_a, client_key);
let mut serialized = vec![];
SerializationConfig::new(1 << 20)
.serialize_into(&a, &mut serialized)
.unwrap();
let params = CompressedFheUint32ConformanceParams::from(server_key);
let deserialized_a = DeserializationConfig::new(1 << 20)
.deserialize_from::<CompressedFheUint32>(serialized.as_slice(), &params)
.unwrap();
let decrypted: u32 = deserialized_a.decompress().decrypt(client_key);
assert_eq!(decrypted, clear_a);
}
fn test_safe_deserialize_conformant_compact_fhe_uint32(client_key: &ClientKey) {
let pk = CompactPublicKey::new(client_key);
let clears = [random::<u32>(), random::<u32>(), random::<u32>()];
let a = CompactCiphertextList::builder(&pk)
.extend(clears.iter().copied())
.build();
let mut serialized = vec![];
SerializationConfig::new(1 << 20)
.serialize_into(&a, &mut serialized)
.unwrap();
let params = CompactCiphertextListConformanceParams::from_parameters_and_size_constraint(
pk.parameters(),
ListSizeConstraint::exact_size(clears.len()),
)
.allow_unpacked();
let deserialized_a = DeserializationConfig::new(1 << 20)
.deserialize_from::<CompactCiphertextList>(serialized.as_slice(), &params)
.unwrap();
let expander = deserialized_a.expand().unwrap();
for (i, clear) in clears.into_iter().enumerate() {
let encrypted: FheUint32 = expander.get(i).unwrap().unwrap();
let decrypted: u32 = encrypted.decrypt(client_key);
assert_eq!(decrypted, clear);
}
assert!(deserialized_a.is_conformant(&params));
}
fn test_case_integer_casting(client_key: &ClientKey) {
let mut rng = rand::thread_rng();
let clear = rng.gen::<u16>();
// Downcasting then Upcasting
{
let a = FheUint16::encrypt(clear, client_key);
// Downcasting
let a: FheUint8 = a.cast_into();
let da: u8 = a.decrypt(client_key);
assert_eq!(da, clear as u8);
// Upcasting
let a: FheUint32 = a.cast_into();
let da: u32 = a.decrypt(client_key);
assert_eq!(da, (clear as u8) as u32);
}
// Upcasting then Downcasting
{
let a = FheUint16::encrypt(clear, client_key);
// Upcasting
let a = FheUint32::cast_from(a);
let da: u32 = a.decrypt(client_key);
assert_eq!(da, clear as u32);
// Downcasting
let a = FheUint8::cast_from(a);
let da: u8 = a.decrypt(client_key);
assert_eq!(da, (clear as u32) as u8);
}
// Casting to self, it not useful but is supported
{
let a = FheUint16::encrypt(clear, client_key);
let a = FheUint16::cast_from(a);
let da: u16 = a.decrypt(client_key);
assert_eq!(da, clear);
}
// Downcasting to smaller signed integer then Upcasting back to unsigned
{
let clear = rng.gen_range((i16::MAX) as u16 + 1..u16::MAX);
let a = FheUint16::encrypt(clear, client_key);
// Downcasting
let a: FheInt8 = a.cast_into();
let da: i8 = a.decrypt(client_key);
assert_eq!(da, clear as i8);
// Upcasting
let a: FheUint32 = a.cast_into();
let da: u32 = a.decrypt(client_key);
assert_eq!(da, (clear as i8) as u32);
}
{
let clear = rng.gen_range(i16::MIN..0);
let a = FheInt16::encrypt(clear, client_key);
// Upcasting
let a: FheUint32 = a.cast_into();
let da: u32 = a.decrypt(client_key);
assert_eq!(da, clear as u32);
}
// Upcasting to bigger signed integer then downcasting back to unsigned
{
let clear = rng.gen_range((i16::MAX) as u16 + 1..u16::MAX);
let a = FheUint16::encrypt(clear, client_key);
// Upcasting
let a: FheInt32 = a.cast_into();
let da: i32 = a.decrypt(client_key);
assert_eq!(da, clear as i32);
// Downcasting
let a: FheUint16 = a.cast_into();
let da: u16 = a.decrypt(client_key);
assert_eq!(da, (clear as i32) as u16);
}
}
fn test_scalar_shift_when_clear_type_is_small(client_key: &ClientKey) {
// This is a regression tests
// The goal is to make sure that doing a scalar shift / rotate
// with a clear type that does not have enough bits to represent
// the number of bits of the fhe type correctly works.
let mut a = FheUint256::encrypt(U256::ONE, client_key);
// The fhe type has 256 bits, the clear type is u8,
// a u8 cannot represent the value '256'.
// This used to result in the shift/rotate panicking
let clear = 1u8;
let _ = &a << clear;
let _ = &a >> clear;
let _ = (&a).rotate_left(clear);
let _ = (&a).rotate_right(clear);
a <<= clear;
a >>= clear;
a.rotate_left_assign(clear);
a.rotate_right_assign(clear);
}
fn test_integer_compressed(client_key: &ClientKey) {
let mut rng = rand::thread_rng();
let clear: u16 = rng.gen();
let compressed = CompressedFheUint16::try_encrypt(clear, client_key).unwrap();
let decompressed = FheUint16::from(compressed.decompress());
let clear_decompressed: u16 = decompressed.decrypt(client_key);
assert_eq!(clear_decompressed, clear);
}
fn test_case_uint32_shift(cks: &ClientKey) {
let mut rng = rand::thread_rng();
let clear_a = rng.gen::<u32>();
@@ -353,6 +547,16 @@ fn test_case_uint32_shift(cks: &ClientKey) {
}
}
fn test_integer_compress_decompress(client_key: &ClientKey) {
let mut rng = rand::thread_rng();
let clear_a: u8 = rng.gen();
let a = FheUint8::try_encrypt(clear_a, client_key).unwrap();
let clear: u8 = a.compress().decompress().decrypt(client_key);
assert_eq!(clear, clear_a);
}
fn test_case_uint32_bitwise(cks: &ClientKey) {
let mut rng = rand::thread_rng();
let clear_a = rng.gen::<u32>();
@@ -910,3 +1114,66 @@ fn test_case_match_value_or(cks: &ClientKey) {
);
}
}
fn test_dedicated_compact_public_key(client_key: &ClientKey) {
use rand::Rng;
let mut rng = rand::thread_rng();
let input_msg: u8 = rng.gen();
let pk = CompactPublicKey::new(client_key);
// Encrypt a value and cast
let mut builder = CompactCiphertextList::builder(&pk);
let list = builder
.push_with_num_bits(input_msg, 8)
.unwrap()
.build_packed();
let expander = list.expand().unwrap();
let ct1_extracted_and_cast = expander.get::<FheUint8>(0).unwrap().unwrap();
let sanity_cast: u8 = ct1_extracted_and_cast.decrypt(client_key);
assert_eq!(sanity_cast, input_msg);
let multiplier: u8 = rng.gen();
// Classical AP: DP, KS, PBS
let mul = &ct1_extracted_and_cast * multiplier as u8;
// High level decryption and test
let clear: u8 = mul.decrypt(client_key);
assert_eq!(clear, input_msg * multiplier);
}
fn test_dedicated_compressed_compact_public_key(client_key: &ClientKey) {
use rand::Rng;
let mut rng = rand::thread_rng();
let input_msg: u8 = rng.gen();
let compressed_pk = CompressedCompactPublicKey::new(client_key);
let pk = compressed_pk.decompress();
// Encrypt a value and cast
let mut builder = CompactCiphertextList::builder(&pk);
let list = builder
.push_with_num_bits(input_msg, 8)
.unwrap()
.build_packed();
let expander = list.expand().unwrap();
let ct1_extracted_and_cast = expander.get::<FheUint8>(0).unwrap().unwrap();
let sanity_cast: u8 = ct1_extracted_and_cast.decrypt(client_key);
assert_eq!(sanity_cast, input_msg);
let multiplier: u8 = rng.gen();
// Classical AP: DP, KS, PBS
let mul = &ct1_extracted_and_cast * multiplier as u8;
// High level decryption and test
let clear: u8 = mul.decrypt(client_key);
assert_eq!(clear, (input_msg * multiplier));
}

View File

@@ -117,7 +117,7 @@ impl Default for IntegerConfig {
fn default() -> Self {
#[cfg(not(feature = "gpu"))]
let params =
crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128.into();
crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128.into();
#[cfg(feature = "gpu")]
let params =
crate::shortint::parameters::PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128

View File

@@ -57,7 +57,7 @@ impl PublicKey {
}
pub(crate) fn message_modulus(&self) -> MessageModulus {
self.key.parameters().message_modulus()
self.key.key.parameters.message_modulus()
}
}

View File

@@ -3,9 +3,9 @@ use crate::high_level_api::{
CompactPublicKey, CompressedCiphertextListBuilder, ConfigBuilder, FheBool, FheInt8, FheUint64,
ReRandomizationContext,
};
use crate::shortint::parameters::v1_5::meta::cpu::V1_5_META_PARAM_CPU_2_2_KS_PBS_PKE_TO_BIG_ZKV2_TUNIFORM_2M128;
use crate::shortint::parameters::test_params::TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
#[cfg(feature = "gpu")]
use crate::shortint::parameters::v1_5::meta::gpu::V1_5_META_PARAM_GPU_2_2_MULTI_BIT_GROUP_4_KS_PBS_PKE_TO_BIG_ZKV2_TUNIFORM_2M128;
use crate::shortint::parameters::v1_6::meta::gpu::V1_6_META_PARAM_GPU_2_2_MULTI_BIT_GROUP_4_KS_PBS_PKE_TO_BIG_ZKV2_TUNIFORM_2M128;
use crate::shortint::parameters::{MetaParameters, ShortintKeySwitchingParameters};
use crate::{set_server_key, ClientKey, CompressedServerKey};
@@ -211,7 +211,7 @@ fn setup_re_rand_test(
#[test]
fn test_re_rand() {
let params = V1_5_META_PARAM_CPU_2_2_KS_PBS_PKE_TO_BIG_ZKV2_TUNIFORM_2M128;
let params = TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
let (cks, sks, cpk) = setup_re_rand_test(params);
set_server_key(sks.decompress());
@@ -222,7 +222,7 @@ fn test_re_rand() {
#[cfg(feature = "gpu")]
#[test]
fn test_gpu_re_rand() {
let params = V1_5_META_PARAM_GPU_2_2_MULTI_BIT_GROUP_4_KS_PBS_PKE_TO_BIG_ZKV2_TUNIFORM_2M128;
let params = V1_6_META_PARAM_GPU_2_2_MULTI_BIT_GROUP_4_KS_PBS_PKE_TO_BIG_ZKV2_TUNIFORM_2M128;
let (cks, sks, cpk) = setup_re_rand_test(params);
set_server_key(sks.decompress_to_gpu());

View File

@@ -10,6 +10,10 @@ use crate::high_level_api::{
generate_keys, ClientKey, ConfigBuilder, FheBool, FheUint256, FheUint8, PublicKey, ServerKey,
};
use crate::integer::U256;
use crate::shortint::parameters::test_params::{
TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128,
TEST_PARAM_PROD_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
};
use crate::shortint::parameters::TestParameters;
use crate::shortint::ClassicPBSParameters;
use crate::{
@@ -37,6 +41,48 @@ pub(crate) fn setup_default_cpu() -> ClientKey {
setup_cpu(Option::<ClassicPBSParameters>::None)
}
pub(crate) fn setup_param_prod_cpu() -> ClientKey {
setup_cpu(Some(
TEST_PARAM_PROD_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
))
}
macro_rules! create_parameterized_test {
(
$test_case_func:ident
) => {
create_parameterized_test!(
$test_case_func,
{
{default, $crate::high_level_api::tests::setup_default_cpu},
{param_prod, $crate::high_level_api::tests::setup_param_prod_cpu},
}
);
};
(
$test_case_func:ident,
{
$({
$suffix:ident,
$setup_func:path
}),*
$(,)?
}
) => {
::paste::paste! {
$(
#[test]
fn [<$test_case_func _ $suffix>]() {
let client_key = $setup_func();
$test_case_func(&client_key);
}
)*
}
};
}
pub(in crate::high_level_api) use create_parameterized_test;
fn assert_that_public_key_encryption_is_decrypted_by_client_key<FheType, ClearType>(
clear: ClearType,
pks: &PublicKey,
@@ -186,7 +232,7 @@ fn test_serialize_deserialize_are_implemented() {
#[test]
fn test_try_from_single_lwe_encryption_key() {
let parameters = crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let parameters = TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
let lwe_sk = crate::shortint::engine::ShortintEngine::with_thread_local_mut(|engine| {
crate::core_crypto::algorithms::allocate_and_generate_new_binary_lwe_secret_key(
parameters

View File

@@ -15,6 +15,7 @@ use crate::shortint::parameters::{
AtomicPatternParameters, ClassicPBSParameters, CompactPublicKeyEncryptionParameters,
ShortintKeySwitchingParameters,
};
use crate::shortint::AtomicPatternKind;
use crate::{ClientKey, CompactCiphertextList, CompactPublicKey, ConfigBuilder, FheUint2};
use rayon::prelude::*;
@@ -120,8 +121,9 @@ fn noise_check_compact_public_key_encryption_noise_tuniform(
block_params: ClassicPBSParameters,
) {
// Hack to avoid server key needs and get the ciphertext directly
cpke_params.expansion_kind =
CompactCiphertextListExpansionKind::NoCasting(block_params.encryption_key_choice.into());
cpke_params.expansion_kind = CompactCiphertextListExpansionKind::NoCasting(
AtomicPatternKind::Standard(block_params.encryption_key_choice.into_pbs_order()),
);
let modulus_as_f64 = cpke_params.ciphertext_modulus.raw_modulus_float();

View File

@@ -549,7 +549,7 @@ mod tests {
use crate::shortint::parameters::test_params::{
TEST_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128,
};
use crate::upgrade::{DecompressionUpgradeKey, UpgradeKeyChain};
use crate::*;
@@ -621,7 +621,7 @@ mod tests {
#[test]
fn test_keychain_upgrade() {
let compute_params = TEST_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let compute_params = TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
let compression_parameters = TEST_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(compute_params)

View File

@@ -1306,6 +1306,7 @@ mod zk_pok_tests {
};
use crate::shortint::ciphertext::Degree;
use crate::shortint::parameters::test_params::{
TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128,
TEST_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1,
TEST_PARAM_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV1,
};
@@ -1319,9 +1320,16 @@ mod zk_pok_tests {
use rand::random;
fn test_zk_list(is_packed: bool) {
let pke_params = PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let ksk_params = PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let fhe_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
let pke_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.pke_params;
let ksk_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.ksk_params;
let fhe_params = params.compute_parameters;
let metadata = [b'i', b'n', b't', b'e', b'g', b'e', b'r'];
@@ -1411,9 +1419,16 @@ mod zk_pok_tests {
#[test]
fn test_zk_empty_list() {
let pke_params = PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let ksk_params = PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let fhe_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
let pke_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.pke_params;
let ksk_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.ksk_params;
let fhe_params = params.compute_parameters;
let metadata = [b'i', b'n', b't', b'e', b'g', b'e', b'r'];
@@ -1563,9 +1578,16 @@ mod zk_pok_tests {
/// is modified
#[test]
fn test_attack_list_info() {
let pke_params = PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let ksk_params = PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let fhe_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
let pke_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.pke_params;
let ksk_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.ksk_params;
let fhe_params = params.compute_parameters;
let metadata = [b'i', b'n', b't', b'e', b'g', b'e', b'r'];
@@ -1683,9 +1705,16 @@ mod zk_pok_tests {
#[test]
fn test_attack_proven_list_metadata() {
let pke_params = PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let ksk_params = PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let fhe_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
let pke_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.pke_params;
let ksk_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.ksk_params;
let fhe_params = params.compute_parameters;
let metadata = [b'i', b'n', b't', b'e', b'g', b'e', b'r'];
@@ -1795,9 +1824,16 @@ mod zk_pok_tests {
#[test]
fn test_several_proven_lists() {
let pke_params = PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let ksk_params = PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let fhe_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
let pke_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.pke_params;
let ksk_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.ksk_params;
let fhe_params = params.compute_parameters;
let metadata = [b'i', b'n', b't', b'e', b'g', b'e', b'r'];
@@ -1858,9 +1894,16 @@ mod zk_pok_tests {
fn test_malicious_boolean_proven_lists() {
use super::DataKind;
let pke_params = PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let ksk_params = PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let fhe_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let params = TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
let pke_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.pke_params;
let ksk_params = params
.dedicated_compact_public_key_parameters
.unwrap()
.ksk_params;
let fhe_params = params.compute_parameters;
let metadata = [b'i', b'n', b't', b'e', b'g', b'e', b'r'];

View File

@@ -224,6 +224,8 @@ mod tests {
use crate::shortint::parameters::test_params::{
TEST_COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_META_PARAM_CPU_2_2_KS32_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128,
TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128,
TEST_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128,
TEST_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
@@ -278,6 +280,22 @@ mod tests {
TEST_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128.into(),
TEST_COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
),
(
TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128
.compute_parameters
.into(),
TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128
.compression_parameters
.unwrap(),
),
(
TEST_META_PARAM_CPU_2_2_KS32_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128
.compute_parameters
.into(),
TEST_META_PARAM_CPU_2_2_KS32_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128
.compression_parameters
.unwrap(),
),
] {
let (cks, sks) = gen_keys::<ShortintParameterSet>(params, IntegerKeyKind::Radix);

View File

@@ -420,18 +420,14 @@ impl CompressedSquashedNoiseCiphertextListBuilder {
mod test {
use super::*;
use crate::integer::noise_squashing::NoiseSquashingKey;
use crate::shortint::parameters::test_params::{
TEST_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_NOISE_SQUASHING_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
};
use crate::shortint::parameters::test_params::TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
use rand::Rng;
#[test]
fn test_compressed_noise_squashed_ciphertext_list() {
let param = TEST_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let noise_squashing_parameters =
TEST_PARAM_NOISE_SQUASHING_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let meta_param = TEST_META_PARAM_PROD_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
let param = meta_param.compute_parameters;
let noise_squashing_parameters = meta_param.noise_squashing_parameters.unwrap().parameters;
// The goal is to test that encrypting a value stored in a type
// for which the bit count does not match the target block count of the encrypted
@@ -442,7 +438,11 @@ mod test {
let noise_squashing_key = NoiseSquashingKey::new(&cks, &noise_squashing_private_key);
let noise_squashing_compression_private_key = NoiseSquashingCompressionPrivateKey::new(
TEST_PARAM_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
meta_param
.noise_squashing_parameters
.unwrap()
.compression_parameters
.unwrap(),
);
let compression_key = noise_squashing_private_key
.new_noise_squashing_compression_key(&noise_squashing_compression_private_key);

View File

@@ -5,12 +5,7 @@ use crate::integer::{
gen_keys, BooleanBlock, CompactPrivateKey, CompactPublicKey, IntegerKeyKind, RadixCiphertext,
SignedRadixCiphertext,
};
use crate::shortint::parameters::test_params::{
TEST_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2,
};
use crate::shortint::parameters::test_params::TEST_META_PARAM_CPU_2_2_KS32_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
use crate::shortint::ShortintParameterSet;
use itertools::Itertools;
use rand::Rng;
@@ -20,12 +15,20 @@ const NUM_BLOCKS: usize = 32;
#[test]
fn test_ciphertext_re_randomization_after_compression() {
let params = TEST_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128.into();
let comp_params = TEST_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let cpk_params = TEST_PARAM_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128_ZKV2;
let ks_params = TEST_PARAM_KEYSWITCH_PKE_TO_BIG_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let meta_param = TEST_META_PARAM_CPU_2_2_KS32_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
let params = meta_param.compute_parameters;
let comp_params = meta_param.compression_parameters.unwrap();
let cpk_params = meta_param
.dedicated_compact_public_key_parameters
.unwrap()
.pke_params;
let ks_params = meta_param
.dedicated_compact_public_key_parameters
.unwrap()
.re_randomization_parameters
.unwrap();
let (cks, sks) = gen_keys::<ShortintParameterSet>(params, IntegerKeyKind::Radix);
let (cks, sks) = gen_keys::<ShortintParameterSet>(params.into(), IntegerKeyKind::Radix);
let private_compression_key = cks.new_compression_private_key(comp_params);

Some files were not shown because too many files have changed in this diff Show More