mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-11 07:38:08 -05:00
Compare commits
167 Commits
ntt-experi
...
mz/refacto
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e6adab801 | ||
|
|
6df31476e9 | ||
|
|
40205d46e1 | ||
|
|
a1cea9496a | ||
|
|
abd4274b09 | ||
|
|
55775b8e02 | ||
|
|
523d561de6 | ||
|
|
61a50d0bcc | ||
|
|
ee57f5658b | ||
|
|
9362965f50 | ||
|
|
00fb60451d | ||
|
|
18b9fd4464 | ||
|
|
eace0bfb85 | ||
|
|
af1be5ebca | ||
|
|
916bd8a09f | ||
|
|
20cb0642ce | ||
|
|
151f9f6d82 | ||
|
|
8db8cb49e4 | ||
|
|
b4583976a2 | ||
|
|
b450375da1 | ||
|
|
f02f1fb297 | ||
|
|
17642fa703 | ||
|
|
23fa9b24bd | ||
|
|
0453b9bd60 | ||
|
|
9b2cf67911 | ||
|
|
36a7656048 | ||
|
|
61c8eadd58 | ||
|
|
fdd4d9d1cc | ||
|
|
62700ab853 | ||
|
|
27445645e7 | ||
|
|
ea0cd26c0b | ||
|
|
ff48582679 | ||
|
|
a77c87ff12 | ||
|
|
6d143f1edc | ||
|
|
216e6b443a | ||
|
|
1400ae946c | ||
|
|
c332902a05 | ||
|
|
cf7a7f132d | ||
|
|
6e0a3b9ad7 | ||
|
|
1f825dde08 | ||
|
|
f9222de47c | ||
|
|
5732e8dd7a | ||
|
|
9db35c5474 | ||
|
|
b69f73e8e6 | ||
|
|
90bdf75147 | ||
|
|
233ea17adf | ||
|
|
df6ee79841 | ||
|
|
6497fb9a15 | ||
|
|
d8894e3b69 | ||
|
|
42636bab13 | ||
|
|
ec27d3dc6f | ||
|
|
5272c95de4 | ||
|
|
27d7ace3ef | ||
|
|
d80ab231a8 | ||
|
|
fe3fa531f9 | ||
|
|
5c1573c266 | ||
|
|
7772e8112d | ||
|
|
5e92cb1475 | ||
|
|
f51e19b071 | ||
|
|
aeb00ae584 | ||
|
|
ce5e9c1bdb | ||
|
|
4d4e124e94 | ||
|
|
ca6d37e06f | ||
|
|
e3143315f3 | ||
|
|
f8636fe814 | ||
|
|
7e72400321 | ||
|
|
728b409256 | ||
|
|
d91404e567 | ||
|
|
e11c3d7b7c | ||
|
|
6f8eeb043c | ||
|
|
00d55182b4 | ||
|
|
6f6ce106c3 | ||
|
|
68fcbb5280 | ||
|
|
3f46389cc8 | ||
|
|
9e8dd01cb9 | ||
|
|
0085ceb97b | ||
|
|
be9a4d2d9c | ||
|
|
87421e8307 | ||
|
|
0c3919628f | ||
|
|
f1c21888a7 | ||
|
|
2624beb7fa | ||
|
|
e44c38a102 | ||
|
|
4535230874 | ||
|
|
a7b2d9b228 | ||
|
|
ab923a3ebc | ||
|
|
a0e85fb355 | ||
|
|
ecee305340 | ||
|
|
f08ea8cf85 | ||
|
|
096e320b97 | ||
|
|
95aac64c1c | ||
|
|
76aaa56691 | ||
|
|
a40489bdd2 | ||
|
|
4bf617eb10 | ||
|
|
070073d229 | ||
|
|
6c1ca8e32b | ||
|
|
6523610ca4 | ||
|
|
41c20e22f5 | ||
|
|
4a00d25cb1 | ||
|
|
8c9ee64612 | ||
|
|
bfdfbfac0f | ||
|
|
dbe7bdcd5c | ||
|
|
6d77ff18ad | ||
|
|
7d4d0e0b16 | ||
|
|
b27762232c | ||
|
|
f597d0f06f | ||
|
|
ee188448f3 | ||
|
|
ee49f048c7 | ||
|
|
a9b09ecc45 | ||
|
|
efc243edc9 | ||
|
|
bc34411d3f | ||
|
|
c7923ff3ed | ||
|
|
7534b68e5c | ||
|
|
655f7e6214 | ||
|
|
b8556ddbd4 | ||
|
|
cab7439064 | ||
|
|
f8a8780651 | ||
|
|
bb3c8e7d5d | ||
|
|
69536960c3 | ||
|
|
52a7c52a49 | ||
|
|
751c407ba5 | ||
|
|
492d348138 | ||
|
|
e7df7eb5ef | ||
|
|
380ee52986 | ||
|
|
439a28f68b | ||
|
|
2eb1e37ca7 | ||
|
|
eb1b136c45 | ||
|
|
1376bcba7c | ||
|
|
b5b4e54b9b | ||
|
|
23c2bd790a | ||
|
|
251ee9aa0e | ||
|
|
fad066a996 | ||
|
|
6ef1f22b33 | ||
|
|
8cc8dba1ab | ||
|
|
082328c91a | ||
|
|
fdb6faa0a8 | ||
|
|
856440386f | ||
|
|
2e8189514c | ||
|
|
29b2454cce | ||
|
|
9ed2589c7a | ||
|
|
36b71529e6 | ||
|
|
b738946d72 | ||
|
|
62f1425257 | ||
|
|
44e491b93f | ||
|
|
a470b26672 | ||
|
|
015409424c | ||
|
|
37be751188 | ||
|
|
2580a834af | ||
|
|
a029bd878e | ||
|
|
400e7930b6 | ||
|
|
40d07c6bc3 | ||
|
|
9dd2d39f1c | ||
|
|
4045a3bc2f | ||
|
|
b4ffeccd46 | ||
|
|
7fe3ad3b6e | ||
|
|
7fdd4f9532 | ||
|
|
81eef39ddb | ||
|
|
b6459e3cda | ||
|
|
f2ef78c348 | ||
|
|
aef8f31621 | ||
|
|
df78d178da | ||
|
|
9297a886a4 | ||
|
|
28b4f91a32 | ||
|
|
04fb46e41b | ||
|
|
53da809f37 | ||
|
|
723910c669 | ||
|
|
8ecf8879fb | ||
|
|
2427f744f8 |
8
.github/workflows/aws_tfhe_fast_tests.yml
vendored
8
.github/workflows/aws_tfhe_fast_tests.yml
vendored
@@ -51,7 +51,7 @@ jobs:
|
||||
echo "Fork git sha: ${{ inputs.fork_git_sha }}"
|
||||
|
||||
- name: Checkout tfhe-rs
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: ${{ inputs.fork_repo }}
|
||||
ref: ${{ inputs.fork_git_sha }}
|
||||
@@ -80,7 +80,7 @@ jobs:
|
||||
|
||||
- name: Run user docs tests
|
||||
run: |
|
||||
make test_user_doc
|
||||
CARGO_PROFILE=release_lto_off make test_user_doc
|
||||
|
||||
- name: Run js on wasm API tests
|
||||
run: |
|
||||
@@ -110,6 +110,10 @@ jobs:
|
||||
run: |
|
||||
make test_high_level_api
|
||||
|
||||
- name: Run safe deserialization tests
|
||||
run: |
|
||||
make test_safe_deserialization
|
||||
|
||||
- name: Slack Notification
|
||||
if: ${{ always() }}
|
||||
continue-on-error: true
|
||||
|
||||
22
.github/workflows/aws_tfhe_integer_tests.yml
vendored
22
.github/workflows/aws_tfhe_integer_tests.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: AWS Integer Tests on CPU
|
||||
name: AWS Unsigned Integer Tests on CPU
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -23,13 +23,13 @@ on:
|
||||
description: "Action runner name"
|
||||
type: string
|
||||
request_id:
|
||||
description: 'Slab request ID'
|
||||
description: "Slab request ID"
|
||||
type: string
|
||||
fork_repo:
|
||||
description: 'Name of forked repo as user/repo'
|
||||
description: "Name of forked repo as user/repo"
|
||||
type: string
|
||||
fork_git_sha:
|
||||
description: 'Git SHA to checkout from fork'
|
||||
description: "Git SHA to checkout from fork"
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
echo "Fork git sha: ${{ inputs.fork_git_sha }}"
|
||||
|
||||
- name: Checkout tfhe-rs
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: ${{ inputs.fork_repo }}
|
||||
ref: ${{ inputs.fork_git_sha }}
|
||||
@@ -65,13 +65,21 @@ jobs:
|
||||
toolchain: stable
|
||||
default: true
|
||||
|
||||
- name: Gen Keys if required
|
||||
run: |
|
||||
make GEN_KEY_CACHE_MULTI_BIT_ONLY=TRUE gen_key_cache
|
||||
|
||||
- name: Run unsigned integer multi-bit tests
|
||||
run: |
|
||||
AVX512_SUPPORT=ON make test_unsigned_integer_multi_bit_ci
|
||||
|
||||
- name: Gen Keys if required
|
||||
run: |
|
||||
make gen_key_cache
|
||||
|
||||
- name: Run integer tests
|
||||
- name: Run unsigned integer tests
|
||||
run: |
|
||||
BIG_TESTS_INSTANCE=TRUE make test_integer_ci
|
||||
AVX512_SUPPORT=ON BIG_TESTS_INSTANCE=TRUE make test_unsigned_integer_ci
|
||||
|
||||
- name: Slack Notification
|
||||
if: ${{ always() }}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: AWS Multi Bit Tests on CPU
|
||||
name: AWS Signed Integer Tests on CPU
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -23,13 +23,13 @@ on:
|
||||
description: "Action runner name"
|
||||
type: string
|
||||
request_id:
|
||||
description: 'Slab request ID'
|
||||
description: "Slab request ID"
|
||||
type: string
|
||||
fork_repo:
|
||||
description: 'Name of forked repo as user/repo'
|
||||
description: "Name of forked repo as user/repo"
|
||||
type: string
|
||||
fork_git_sha:
|
||||
description: 'Git SHA to checkout from fork'
|
||||
description: "Git SHA to checkout from fork"
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
echo "Fork git sha: ${{ inputs.fork_git_sha }}"
|
||||
|
||||
- name: Checkout tfhe-rs
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: ${{ inputs.fork_repo }}
|
||||
ref: ${{ inputs.fork_git_sha }}
|
||||
@@ -73,9 +73,17 @@ jobs:
|
||||
run: |
|
||||
make test_shortint_multi_bit_ci
|
||||
|
||||
- name: Run integer multi-bit tests
|
||||
- name: Run signed integer multi-bit tests
|
||||
run: |
|
||||
make test_integer_multi_bit_ci
|
||||
AVX512_SUPPORT=ON make test_signed_integer_multi_bit_ci
|
||||
|
||||
- name: Gen Keys if required
|
||||
run: |
|
||||
make gen_key_cache
|
||||
|
||||
- name: Run signed integer tests
|
||||
run: |
|
||||
AVX512_SUPPORT=ON BIG_TESTS_INSTANCE=TRUE make test_signed_integer_ci
|
||||
|
||||
- name: Slack Notification
|
||||
if: ${{ always() }}
|
||||
10
.github/workflows/aws_tfhe_tests.yml
vendored
10
.github/workflows/aws_tfhe_tests.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
echo "Fork git sha: ${{ inputs.fork_git_sha }}"
|
||||
|
||||
- name: Checkout tfhe-rs
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: ${{ inputs.fork_repo }}
|
||||
ref: ${{ inputs.fork_git_sha }}
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
|
||||
- name: Run user docs tests
|
||||
run: |
|
||||
make test_user_doc
|
||||
CARGO_PROFILE=release_lto_off make test_user_doc
|
||||
|
||||
- name: Gen Keys if required
|
||||
run: |
|
||||
@@ -100,6 +100,12 @@ jobs:
|
||||
- name: Run example tests
|
||||
run: |
|
||||
make test_examples
|
||||
make dark_market
|
||||
|
||||
- name: Run apps tests
|
||||
run: |
|
||||
make test_trivium
|
||||
make test_kreyvium
|
||||
|
||||
- name: Slack Notification
|
||||
if: ${{ always() }}
|
||||
|
||||
2
.github/workflows/aws_tfhe_wasm_tests.yml
vendored
2
.github/workflows/aws_tfhe_wasm_tests.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
echo "Fork git sha: ${{ inputs.fork_git_sha }}"
|
||||
|
||||
- name: Checkout tfhe-rs
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: ${{ inputs.fork_repo }}
|
||||
ref: ${{ inputs.fork_git_sha }}
|
||||
|
||||
12
.github/workflows/boolean_benchmark.yml
vendored
12
.github/workflows/boolean_benchmark.yml
vendored
@@ -19,6 +19,14 @@ on:
|
||||
request_id:
|
||||
description: "Slab request ID"
|
||||
type: string
|
||||
# This input is not used in this workflow but still mandatory since a calling workflow could
|
||||
# use it. If a triggering command include a user_inputs field, then the triggered workflow
|
||||
# must include this very input, otherwise the workflow won't be called.
|
||||
# See start_full_benchmarks.yml as example.
|
||||
user_inputs:
|
||||
description: "Type of benchmarks to run"
|
||||
type: string
|
||||
default: "weekly_benchmarks"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -43,7 +51,7 @@ jobs:
|
||||
echo "BENCH_DATE=$(date --iso-8601=seconds)" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -94,7 +102,7 @@ jobs:
|
||||
path: ${{ env.RESULTS_FILENAME }}
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
|
||||
12
.github/workflows/cargo_build.yml
vendored
12
.github/workflows/cargo_build.yml
vendored
@@ -21,7 +21,17 @@ jobs:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
|
||||
- name: Install and run newline linter checks
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: |
|
||||
wget https://github.com/fernandrone/linelint/releases/download/0.0.6/linelint-linux-amd64
|
||||
echo "16b70fb7b471d6f95cbdc0b4e5dc2b0ac9e84ba9ecdc488f7bdf13df823aca4b linelint-linux-amd64" > checksum
|
||||
sha256sum -c checksum || exit 1
|
||||
chmod +x linelint-linux-amd64
|
||||
mv linelint-linux-amd64 /usr/local/bin/linelint
|
||||
make check_newline
|
||||
|
||||
- name: Run pcc checks
|
||||
run: |
|
||||
|
||||
9
.github/workflows/code_coverage.yml
vendored
9
.github/workflows/code_coverage.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
echo "Fork git sha: ${{ inputs.fork_git_sha }}"
|
||||
|
||||
- name: Checkout tfhe-rs
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: ${{ inputs.fork_repo }}
|
||||
ref: ${{ inputs.fork_git_sha }}
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
|
||||
- name: Check for file changes
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@6ee9cdc5816333acda68e01cf12eedc619e28316
|
||||
uses: tj-actions/changed-files@25ef3926d147cd02fc7e931c1ef50772bbb0d25d
|
||||
with:
|
||||
files_yaml: |
|
||||
tfhe:
|
||||
@@ -76,15 +76,16 @@ jobs:
|
||||
- concrete-csprng/src/**
|
||||
|
||||
- name: Generate Keys
|
||||
if: steps.changed-files.outputs.tfhe_any_changed == 'true'
|
||||
run: |
|
||||
make GEN_KEY_CACHE_COVERAGE_ONLY=TRUE gen_key_cache
|
||||
|
||||
- name: Run boolean coverage
|
||||
- name: Run coverage for boolean
|
||||
if: steps.changed-files.outputs.tfhe_any_changed == 'true'
|
||||
run: |
|
||||
make test_boolean_cov
|
||||
|
||||
- name: Run shortint coverage
|
||||
- name: Run coverage for shortint
|
||||
if: steps.changed-files.outputs.tfhe_any_changed == 'true'
|
||||
run: |
|
||||
make test_shortint_cov
|
||||
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout tfhe-rs
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: ${{ inputs.fork_repo }}
|
||||
ref: ${{ inputs.fork_git_sha }}
|
||||
|
||||
4
.github/workflows/integer_benchmark.yml
vendored
4
.github/workflows/integer_benchmark.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
echo "BENCH_DATE=$(date --iso-8601=seconds)" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -96,7 +96,7 @@ jobs:
|
||||
path: ${{ env.RESULTS_FILENAME }}
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
|
||||
35
.github/workflows/integer_full_benchmark.yml
vendored
35
.github/workflows/integer_full_benchmark.yml
vendored
@@ -19,6 +19,10 @@ on:
|
||||
request_id:
|
||||
description: "Slab request ID"
|
||||
type: string
|
||||
user_inputs:
|
||||
description: "Type of benchmarks to run"
|
||||
type: string
|
||||
default: "weekly_benchmarks"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -26,8 +30,33 @@ env:
|
||||
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
jobs:
|
||||
prepare-matrix:
|
||||
name: Prepare operations matrix
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
op_flavor: ${{ steps.set_op_flavor.outputs.op_flavor }}
|
||||
steps:
|
||||
- name: Weekly benchmarks
|
||||
if: ${{ github.event.inputs.user_inputs == 'weekly_benchmarks' }}
|
||||
run: |
|
||||
echo "OP_FLAVOR=[\"default\", \"default_comp\", \"default_scalar\", \"default_scalar_comp\"]" >> ${GITHUB_ENV}
|
||||
|
||||
- name: Quarterly benchmarks
|
||||
if: ${{ github.event.inputs.user_inputs == 'quarterly_benchmarks' }}
|
||||
run: |
|
||||
echo "OP_FLAVOR=[\"default\", \"default_comp\", \"default_scalar\", \"default_scalar_comp\", \
|
||||
\"smart\", \"smart_comp\", \"smart_scalar\", \"smart_parallelized\", \"smart_parallelized_comp\", \"smart_scalar_parallelized\", \"smart_scalar_parallelized_comp\", \
|
||||
\"unchecked\", \"unchecked_comp\", \"unchecked_scalar\", \"unchecked_scalar_comp\", \
|
||||
\"misc\"]" >> ${GITHUB_ENV}
|
||||
|
||||
- name: Set operation flavor output
|
||||
id: set_op_flavor
|
||||
run: |
|
||||
echo "op_flavor=${{ toJSON(env.OP_FLAVOR) }}" >> ${GITHUB_OUTPUT}
|
||||
|
||||
integer-benchmarks:
|
||||
name: Execute integer benchmarks for all operations flavor
|
||||
needs: prepare-matrix
|
||||
runs-on: ${{ github.event.inputs.runner_name }}
|
||||
if: ${{ !cancelled() }}
|
||||
continue-on-error: true
|
||||
@@ -35,7 +64,7 @@ jobs:
|
||||
max-parallel: 1
|
||||
matrix:
|
||||
command: [ integer, integer_multi_bit]
|
||||
op_flavor: [ default, default_comp, default_scalar, default_scalar_comp, smart, smart_comp, smart_scalar, smart_parallelized, smart_parallelized_comp, smart_scalar_parallelized, unchecked, unchecked_comp, unchecked_scalar, unchecked_scalar_comp, misc ]
|
||||
op_flavor: ${{ fromJson(needs.prepare-matrix.outputs.op_flavor) }}
|
||||
steps:
|
||||
- name: Instance configuration used
|
||||
run: |
|
||||
@@ -45,7 +74,7 @@ jobs:
|
||||
echo "Request ID: ${{ inputs.request_id }}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -67,7 +96,7 @@ jobs:
|
||||
override: true
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
echo "BENCH_DATE=$(date --iso-8601=seconds)" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -96,7 +96,7 @@ jobs:
|
||||
path: ${{ env.RESULTS_FILENAME }}
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
|
||||
12
.github/workflows/m1_tests.yml
vendored
12
.github/workflows/m1_tests.yml
vendored
@@ -15,7 +15,6 @@ env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUSTFLAGS: "-C target-cpu=native"
|
||||
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
CARGO_PROFILE: release_lto_off
|
||||
FAST_TESTS: "TRUE"
|
||||
|
||||
concurrency:
|
||||
@@ -28,7 +27,7 @@ jobs:
|
||||
runs-on: ["self-hosted", "m1mac"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
|
||||
- name: Install latest stable
|
||||
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
|
||||
@@ -86,7 +85,7 @@ jobs:
|
||||
|
||||
- name: Run user docs tests
|
||||
run: |
|
||||
make test_user_doc
|
||||
CARGO_PROFILE=release_lto_off make test_user_doc
|
||||
|
||||
# JS tests are more easily launched in docker, we won't test that on M1 as docker is pretty
|
||||
# slow on Apple machines due to the virtualization layer.
|
||||
@@ -111,10 +110,9 @@ jobs:
|
||||
run: |
|
||||
make test_shortint_multi_bit_ci
|
||||
|
||||
# # These multi bit integer tests are too slow on M1 with low core count and low RAM
|
||||
# - name: Run integer multi bit tests
|
||||
# run: |
|
||||
# make test_integer_multi_bit_ci
|
||||
- name: Run integer multi bit tests
|
||||
run: |
|
||||
make test_integer_multi_bit_ci
|
||||
|
||||
remove_label:
|
||||
name: Remove m1_test label
|
||||
|
||||
6
.github/workflows/make_release.yml
vendored
6
.github/workflows/make_release.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
|
||||
- name: Publish web package
|
||||
if: ${{ inputs.push_web_package }}
|
||||
uses: JS-DevTools/npm-publish@fe72237be0920f7a0cafd6a966c9b929c9466e9b
|
||||
uses: JS-DevTools/npm-publish@4b07b26a2f6e0a51846e1870223e545bae91c552
|
||||
with:
|
||||
token: ${{ secrets.NPM_TOKEN }}
|
||||
package: tfhe/pkg/package.json
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
|
||||
- name: Publish Node package
|
||||
if: ${{ inputs.push_node_package }}
|
||||
uses: JS-DevTools/npm-publish@fe72237be0920f7a0cafd6a966c9b929c9466e9b
|
||||
uses: JS-DevTools/npm-publish@4b07b26a2f6e0a51846e1870223e545bae91c552
|
||||
with:
|
||||
token: ${{ secrets.NPM_TOKEN }}
|
||||
package: tfhe/pkg/package.json
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
6
.github/workflows/parameters_check.yml
vendored
6
.github/workflows/parameters_check.yml
vendored
@@ -17,10 +17,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout tfhe-rs
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
|
||||
- name: Checkout lattice-estimator
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: malb/lattice-estimator
|
||||
path: lattice_estimator
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
|
||||
- name: Collect parameters
|
||||
run: |
|
||||
make write_params_to_file
|
||||
CARGO_PROFILE=devo make write_params_to_file
|
||||
|
||||
- name: Perform security check
|
||||
run: |
|
||||
|
||||
12
.github/workflows/pbs_benchmark.yml
vendored
12
.github/workflows/pbs_benchmark.yml
vendored
@@ -19,6 +19,14 @@ on:
|
||||
request_id:
|
||||
description: "Slab request ID"
|
||||
type: string
|
||||
# This input is not used in this workflow but still mandatory since a calling workflow could
|
||||
# use it. If a triggering command include a user_inputs field, then the triggered workflow
|
||||
# must include this very input, otherwise the workflow won't be called.
|
||||
# See start_full_benchmarks.yml as example.
|
||||
user_inputs:
|
||||
description: "Type of benchmarks to run"
|
||||
type: string
|
||||
default: "weekly_benchmarks"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -43,7 +51,7 @@ jobs:
|
||||
echo "BENCH_DATE=$(date --iso-8601=seconds)" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -84,7 +92,7 @@ jobs:
|
||||
path: ${{ env.RESULTS_FILENAME }}
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
|
||||
4
.github/workflows/shortint_benchmark.yml
vendored
4
.github/workflows/shortint_benchmark.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
echo "BENCH_DATE=$(date --iso-8601=seconds)" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -94,7 +94,7 @@ jobs:
|
||||
path: ${{ env.RESULTS_FILENAME }}
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
|
||||
12
.github/workflows/shortint_full_benchmark.yml
vendored
12
.github/workflows/shortint_full_benchmark.yml
vendored
@@ -19,6 +19,14 @@ on:
|
||||
request_id:
|
||||
description: "Slab request ID"
|
||||
type: string
|
||||
# This input is not used in this workflow but still mandatory since a calling workflow could
|
||||
# use it. If a triggering command include a user_inputs field, then the triggered workflow
|
||||
# must include this very input, otherwise the workflow won't be called.
|
||||
# See start_full_benchmarks.yml as example.
|
||||
user_inputs:
|
||||
description: "Type of benchmarks to run"
|
||||
type: string
|
||||
default: "weekly_benchmarks"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -43,7 +51,7 @@ jobs:
|
||||
echo "Request ID: ${{ inputs.request_id }}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -65,7 +73,7 @@ jobs:
|
||||
override: true
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
|
||||
129
.github/workflows/signed_integer_benchmark.yml
vendored
Normal file
129
.github/workflows/signed_integer_benchmark.yml
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
# Run signed integer benchmarks on an AWS instance and return parsed results to Slab CI bot.
|
||||
name: Signed Integer benchmarks
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
instance_id:
|
||||
description: "Instance ID"
|
||||
type: string
|
||||
instance_image_id:
|
||||
description: "Instance AMI ID"
|
||||
type: string
|
||||
instance_type:
|
||||
description: "Instance product type"
|
||||
type: string
|
||||
runner_name:
|
||||
description: "Action runner name"
|
||||
type: string
|
||||
request_id:
|
||||
description: "Slab request ID"
|
||||
type: string
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RESULTS_FILENAME: parsed_benchmark_results_${{ github.sha }}.json
|
||||
PARSE_INTEGER_BENCH_CSV_FILE: tfhe_rs_integer_benches_${{ github.sha }}.csv
|
||||
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
jobs:
|
||||
run-integer-benchmarks:
|
||||
name: Execute signed integer benchmarks in EC2
|
||||
runs-on: ${{ github.event.inputs.runner_name }}
|
||||
if: ${{ !cancelled() }}
|
||||
steps:
|
||||
- name: Instance configuration used
|
||||
run: |
|
||||
echo "IDs: ${{ inputs.instance_id }}"
|
||||
echo "AMI: ${{ inputs.instance_image_id }}"
|
||||
echo "Type: ${{ inputs.instance_type }}"
|
||||
echo "Request ID: ${{ inputs.request_id }}"
|
||||
|
||||
- name: Get benchmark date
|
||||
run: |
|
||||
echo "BENCH_DATE=$(date --iso-8601=seconds)" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up home
|
||||
# "Install rust" step require root user to have a HOME directory which is not set.
|
||||
run: |
|
||||
echo "HOME=/home/ubuntu" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Install rust
|
||||
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
|
||||
with:
|
||||
toolchain: nightly
|
||||
override: true
|
||||
|
||||
- name: Run benchmarks with AVX512
|
||||
run: |
|
||||
make AVX512_SUPPORT=ON FAST_BENCH=TRUE bench_signed_integer
|
||||
|
||||
- name: Parse benchmarks to csv
|
||||
run: |
|
||||
make PARSE_INTEGER_BENCH_CSV_FILE=${{ env.PARSE_INTEGER_BENCH_CSV_FILE }} \
|
||||
parse_integer_benches
|
||||
|
||||
- name: Upload csv results artifact
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
|
||||
with:
|
||||
name: ${{ github.sha }}_csv_integer
|
||||
path: ${{ env.PARSE_INTEGER_BENCH_CSV_FILE }}
|
||||
|
||||
- name: Parse results
|
||||
run: |
|
||||
COMMIT_DATE="$(git --no-pager show -s --format=%cd --date=iso8601-strict ${{ github.sha }})"
|
||||
COMMIT_HASH="$(git describe --tags --dirty)"
|
||||
python3 ./ci/benchmark_parser.py target/criterion ${{ env.RESULTS_FILENAME }} \
|
||||
--database tfhe_rs \
|
||||
--hardware ${{ inputs.instance_type }} \
|
||||
--project-version "${COMMIT_HASH}" \
|
||||
--branch ${{ github.ref_name }} \
|
||||
--commit-date "${COMMIT_DATE}" \
|
||||
--bench-date "${{ env.BENCH_DATE }}" \
|
||||
--walk-subdirs \
|
||||
--name-suffix avx512 \
|
||||
--throughput
|
||||
|
||||
- name: Upload parsed results artifact
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
|
||||
with:
|
||||
name: ${{ github.sha }}_integer
|
||||
path: ${{ env.RESULTS_FILENAME }}
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
token: ${{ secrets.CONCRETE_ACTIONS_TOKEN }}
|
||||
|
||||
- name: Send data to Slab
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Computing HMac on results file"
|
||||
SIGNATURE="$(slab/scripts/hmac_calculator.sh ${{ env.RESULTS_FILENAME }} '${{ secrets.JOB_SECRET }}')"
|
||||
echo "Sending results to Slab..."
|
||||
curl -v -k \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Slab-Repository: ${{ github.repository }}" \
|
||||
-H "X-Slab-Command: store_data_v2" \
|
||||
-H "X-Hub-Signature-256: sha256=${SIGNATURE}" \
|
||||
-d @${{ env.RESULTS_FILENAME }} \
|
||||
${{ secrets.SLAB_URL }}
|
||||
|
||||
- name: Slack Notification
|
||||
if: ${{ failure() }}
|
||||
continue-on-error: true
|
||||
uses: rtCamp/action-slack-notify@b24d75fe0e728a4bf9fc42ee217caa686d141ee8
|
||||
env:
|
||||
SLACK_COLOR: ${{ job.status }}
|
||||
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
|
||||
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
|
||||
SLACK_MESSAGE: "Signed integer benchmarks failed. (${{ env.ACTION_RUN_URL }})"
|
||||
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||
133
.github/workflows/signed_integer_full_benchmark.yml
vendored
Normal file
133
.github/workflows/signed_integer_full_benchmark.yml
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
# Run all signed integer benchmarks on an AWS instance and return parsed results to Slab CI bot.
|
||||
name: Signed Integer full benchmarks
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
instance_id:
|
||||
description: "Instance ID"
|
||||
type: string
|
||||
instance_image_id:
|
||||
description: "Instance AMI ID"
|
||||
type: string
|
||||
instance_type:
|
||||
description: "Instance product type"
|
||||
type: string
|
||||
runner_name:
|
||||
description: "Action runner name"
|
||||
type: string
|
||||
request_id:
|
||||
description: "Slab request ID"
|
||||
type: string
|
||||
user_inputs:
|
||||
description: "Type of benchmarks to run"
|
||||
type: string
|
||||
default: "weekly_benchmarks"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RESULTS_FILENAME: parsed_benchmark_results_${{ github.sha }}.json
|
||||
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
jobs:
|
||||
integer-benchmarks:
|
||||
name: Execute signed integer benchmarks for all operations flavor
|
||||
runs-on: ${{ github.event.inputs.runner_name }}
|
||||
if: ${{ !cancelled() }}
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
max-parallel: 1
|
||||
matrix:
|
||||
command: [ integer, integer_multi_bit ]
|
||||
op_flavor: [ default, default_comp, default_scalar, default_scalar_comp,
|
||||
unchecked, unchecked_comp, unchecked_scalar, unchecked_scalar_comp ]
|
||||
steps:
|
||||
- name: Instance configuration used
|
||||
run: |
|
||||
echo "IDs: ${{ inputs.instance_id }}"
|
||||
echo "AMI: ${{ inputs.instance_image_id }}"
|
||||
echo "Type: ${{ inputs.instance_type }}"
|
||||
echo "Request ID: ${{ inputs.request_id }}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get benchmark details
|
||||
run: |
|
||||
echo "BENCH_DATE=$(date --iso-8601=seconds)" >> "${GITHUB_ENV}"
|
||||
echo "COMMIT_DATE=$(git --no-pager show -s --format=%cd --date=iso8601-strict ${{ github.sha }})" >> "${GITHUB_ENV}"
|
||||
echo "COMMIT_HASH=$(git describe --tags --dirty)" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Set up home
|
||||
# "Install rust" step require root user to have a HOME directory which is not set.
|
||||
run: |
|
||||
echo "HOME=/home/ubuntu" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Install rust
|
||||
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
|
||||
with:
|
||||
toolchain: nightly
|
||||
override: true
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
token: ${{ secrets.CONCRETE_ACTIONS_TOKEN }}
|
||||
|
||||
- name: Run benchmarks with AVX512
|
||||
run: |
|
||||
make AVX512_SUPPORT=ON BENCH_OP_FLAVOR=${{ matrix.op_flavor }} bench_signed_${{ matrix.command }}
|
||||
|
||||
- name: Parse results
|
||||
run: |
|
||||
python3 ./ci/benchmark_parser.py target/criterion ${{ env.RESULTS_FILENAME }} \
|
||||
--database tfhe_rs \
|
||||
--hardware ${{ inputs.instance_type }} \
|
||||
--project-version "${{ env.COMMIT_HASH }}" \
|
||||
--branch ${{ github.ref_name }} \
|
||||
--commit-date "${{ env.COMMIT_DATE }}" \
|
||||
--bench-date "${{ env.BENCH_DATE }}" \
|
||||
--walk-subdirs \
|
||||
--name-suffix avx512 \
|
||||
--throughput
|
||||
|
||||
- name: Upload parsed results artifact
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
|
||||
with:
|
||||
name: ${{ github.sha }}_${{ matrix.command }}_${{ matrix.op_flavor }}
|
||||
path: ${{ env.RESULTS_FILENAME }}
|
||||
|
||||
- name: Send data to Slab
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Computing HMac on results file"
|
||||
SIGNATURE="$(slab/scripts/hmac_calculator.sh ${{ env.RESULTS_FILENAME }} '${{ secrets.JOB_SECRET }}')"
|
||||
echo "Sending results to Slab..."
|
||||
curl -v -k \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Slab-Repository: ${{ github.repository }}" \
|
||||
-H "X-Slab-Command: store_data_v2" \
|
||||
-H "X-Hub-Signature-256: sha256=${SIGNATURE}" \
|
||||
-d @${{ env.RESULTS_FILENAME }} \
|
||||
${{ secrets.SLAB_URL }}
|
||||
|
||||
slack-notification:
|
||||
name: Slack Notification
|
||||
runs-on: ${{ github.event.inputs.runner_name }}
|
||||
if: ${{ failure() }}
|
||||
needs: integer-benchmarks
|
||||
steps:
|
||||
- name: Notify
|
||||
continue-on-error: true
|
||||
uses: rtCamp/action-slack-notify@b24d75fe0e728a4bf9fc42ee217caa686d141ee8
|
||||
env:
|
||||
SLACK_COLOR: ${{ job.status }}
|
||||
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
|
||||
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
|
||||
SLACK_MESSAGE: "Signed integer full benchmarks failed. (${{ env.ACTION_RUN_URL }})"
|
||||
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||
129
.github/workflows/signed_integer_multi_bit_benchmark.yml
vendored
Normal file
129
.github/workflows/signed_integer_multi_bit_benchmark.yml
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
# Run signed integer benchmarks with multi-bit cryptographic parameters on an AWS instance and return parsed results to Slab CI bot.
|
||||
name: Signed Integer Multi-bit benchmarks
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
instance_id:
|
||||
description: "Instance ID"
|
||||
type: string
|
||||
instance_image_id:
|
||||
description: "Instance AMI ID"
|
||||
type: string
|
||||
instance_type:
|
||||
description: "Instance product type"
|
||||
type: string
|
||||
runner_name:
|
||||
description: "Action runner name"
|
||||
type: string
|
||||
request_id:
|
||||
description: "Slab request ID"
|
||||
type: string
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RESULTS_FILENAME: parsed_benchmark_results_${{ github.sha }}.json
|
||||
PARSE_INTEGER_BENCH_CSV_FILE: tfhe_rs_integer_benches_${{ github.sha }}.csv
|
||||
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
jobs:
|
||||
run-integer-benchmarks:
|
||||
name: Execute signed integer multi-bit benchmarks in EC2
|
||||
runs-on: ${{ github.event.inputs.runner_name }}
|
||||
if: ${{ !cancelled() }}
|
||||
steps:
|
||||
- name: Instance configuration used
|
||||
run: |
|
||||
echo "IDs: ${{ inputs.instance_id }}"
|
||||
echo "AMI: ${{ inputs.instance_image_id }}"
|
||||
echo "Type: ${{ inputs.instance_type }}"
|
||||
echo "Request ID: ${{ inputs.request_id }}"
|
||||
|
||||
- name: Get benchmark date
|
||||
run: |
|
||||
echo "BENCH_DATE=$(date --iso-8601=seconds)" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up home
|
||||
# "Install rust" step require root user to have a HOME directory which is not set.
|
||||
run: |
|
||||
echo "HOME=/home/ubuntu" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Install rust
|
||||
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
|
||||
with:
|
||||
toolchain: nightly
|
||||
override: true
|
||||
|
||||
- name: Run multi-bit benchmarks with AVX512
|
||||
run: |
|
||||
make AVX512_SUPPORT=ON FAST_BENCH=TRUE bench_signed_integer_multi_bit
|
||||
|
||||
- name: Parse benchmarks to csv
|
||||
run: |
|
||||
make PARSE_INTEGER_BENCH_CSV_FILE=${{ env.PARSE_INTEGER_BENCH_CSV_FILE }} \
|
||||
parse_integer_benches
|
||||
|
||||
- name: Upload csv results artifact
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
|
||||
with:
|
||||
name: ${{ github.sha }}_csv_integer
|
||||
path: ${{ env.PARSE_INTEGER_BENCH_CSV_FILE }}
|
||||
|
||||
- name: Parse results
|
||||
run: |
|
||||
COMMIT_DATE="$(git --no-pager show -s --format=%cd --date=iso8601-strict ${{ github.sha }})"
|
||||
COMMIT_HASH="$(git describe --tags --dirty)"
|
||||
python3 ./ci/benchmark_parser.py target/criterion ${{ env.RESULTS_FILENAME }} \
|
||||
--database tfhe_rs \
|
||||
--hardware ${{ inputs.instance_type }} \
|
||||
--project-version "${COMMIT_HASH}" \
|
||||
--branch ${{ github.ref_name }} \
|
||||
--commit-date "${COMMIT_DATE}" \
|
||||
--bench-date "${{ env.BENCH_DATE }}" \
|
||||
--walk-subdirs \
|
||||
--name-suffix avx512 \
|
||||
--throughput
|
||||
|
||||
- name: Upload parsed results artifact
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
|
||||
with:
|
||||
name: ${{ github.sha }}_integer
|
||||
path: ${{ env.RESULTS_FILENAME }}
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
token: ${{ secrets.CONCRETE_ACTIONS_TOKEN }}
|
||||
|
||||
- name: Send data to Slab
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Computing HMac on results file"
|
||||
SIGNATURE="$(slab/scripts/hmac_calculator.sh ${{ env.RESULTS_FILENAME }} '${{ secrets.JOB_SECRET }}')"
|
||||
echo "Sending results to Slab..."
|
||||
curl -v -k \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Slab-Repository: ${{ github.repository }}" \
|
||||
-H "X-Slab-Command: store_data_v2" \
|
||||
-H "X-Hub-Signature-256: sha256=${SIGNATURE}" \
|
||||
-d @${{ env.RESULTS_FILENAME }} \
|
||||
${{ secrets.SLAB_URL }}
|
||||
|
||||
- name: Slack Notification
|
||||
if: ${{ failure() }}
|
||||
continue-on-error: true
|
||||
uses: rtCamp/action-slack-notify@b24d75fe0e728a4bf9fc42ee217caa686d141ee8
|
||||
env:
|
||||
SLACK_COLOR: ${{ job.status }}
|
||||
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
|
||||
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
|
||||
SLACK_MESSAGE: "Signed integer benchmarks failed. (${{ env.ACTION_RUN_URL }})"
|
||||
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||
35
.github/workflows/start_benchmarks.yml
vendored
35
.github/workflows/start_benchmarks.yml
vendored
@@ -20,10 +20,18 @@ on:
|
||||
description: "Run integer benches"
|
||||
type: boolean
|
||||
default: true
|
||||
signed_integer_bench:
|
||||
description: "Run signed integer benches"
|
||||
type: boolean
|
||||
default: true
|
||||
integer_multi_bit_bench:
|
||||
description: "Run integer multi bit benches"
|
||||
type: boolean
|
||||
default: true
|
||||
signed_integer_multi_bit_bench:
|
||||
description: "Run signed integer multi bit benches"
|
||||
type: boolean
|
||||
default: true
|
||||
pbs_bench:
|
||||
description: "Run PBS benches"
|
||||
type: boolean
|
||||
@@ -38,17 +46,20 @@ jobs:
|
||||
if: ${{ (github.event_name == 'push' && github.repository == 'zama-ai/tfhe-rs') || github.event_name == 'workflow_dispatch' }}
|
||||
strategy:
|
||||
matrix:
|
||||
command: [boolean_bench, shortint_bench, integer_bench, integer_multi_bit_bench, pbs_bench, wasm_client_bench]
|
||||
command: [ boolean_bench, shortint_bench,
|
||||
integer_bench, integer_multi_bit_bench,
|
||||
signed_integer_bench, signed_integer_multi_bit_bench,
|
||||
pbs_bench, wasm_client_bench ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout tfhe-rs
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check for file changes
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@6ee9cdc5816333acda68e01cf12eedc619e28316
|
||||
uses: tj-actions/changed-files@25ef3926d147cd02fc7e931c1ef50772bbb0d25d
|
||||
with:
|
||||
files_yaml: |
|
||||
common_benches:
|
||||
@@ -69,13 +80,23 @@ jobs:
|
||||
integer_bench:
|
||||
- tfhe/src/shortint/**
|
||||
- tfhe/src/integer/**
|
||||
- tfhe/benches/integer/**
|
||||
- tfhe/benches/integer/bench.rs
|
||||
- .github/workflows/integer_benchmark.yml
|
||||
integer_multi_bit_bench:
|
||||
- tfhe/src/shortint/**
|
||||
- tfhe/src/integer/**
|
||||
- tfhe/benches/integer/**
|
||||
- .github/workflows/integer_benchmark.yml
|
||||
- tfhe/benches/integer/bench.rs
|
||||
- .github/workflows/integer_multi_bit_benchmark.yml
|
||||
signed_integer_bench:
|
||||
- tfhe/src/shortint/**
|
||||
- tfhe/src/integer/**
|
||||
- tfhe/benches/integer/signed_bench.rs
|
||||
- .github/workflows/signed_integer_benchmark.yml
|
||||
signed_integer_multi_bit_bench:
|
||||
- tfhe/src/shortint/**
|
||||
- tfhe/src/integer/**
|
||||
- tfhe/benches/integer/signed_bench.rs
|
||||
- .github/workflows/signed_integer_multi_bit_benchmark.yml
|
||||
pbs_bench:
|
||||
- tfhe/src/core_crypto/**
|
||||
- tfhe/benches/core_crypto/**
|
||||
@@ -85,7 +106,7 @@ jobs:
|
||||
- .github/workflows/wasm_client_benchmark.yml
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
|
||||
33
.github/workflows/start_full_benchmarks.yml
vendored
33
.github/workflows/start_full_benchmarks.yml
vendored
@@ -3,34 +3,57 @@ name: Start full suite benchmarks
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Job will be triggered each Saturday at 1a.m.
|
||||
# Weekly benchmarks will be triggered each Saturday at 1a.m.
|
||||
- cron: '0 1 * * 6'
|
||||
# Quarterly benchmarks will be triggered right before end of quarter, the 25th of the current month at 4a.m.
|
||||
# These benchmarks are far longer to execute hence the reason to run them only four time a year.
|
||||
- cron: '0 4 25 MAR,JUN,SEP,DEC *'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
benchmark_type:
|
||||
description: 'Benchmark type'
|
||||
required: true
|
||||
default: 'weekly'
|
||||
type: choice
|
||||
options:
|
||||
- weekly
|
||||
- quarterly
|
||||
|
||||
jobs:
|
||||
start-benchmarks:
|
||||
if: ${{ (github.event_name == 'schedule' && github.repository == 'zama-ai/tfhe-rs') || github.event_name == 'workflow_dispatch' }}
|
||||
strategy:
|
||||
matrix:
|
||||
command: [ boolean_bench, shortint_full_bench, integer_full_bench, pbs_bench, wasm_client_bench ]
|
||||
command: [ boolean_bench, shortint_full_bench, integer_full_bench,
|
||||
signed_integer_full_bench, pbs_bench, wasm_client_bench ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout tfhe-rs
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
token: ${{ secrets.CONCRETE_ACTIONS_TOKEN }}
|
||||
|
||||
- name: Set benchmarks type as weekly
|
||||
if: (github.event_name == 'workflow_dispatch' && inputs.benchmark_type == 'weekly') || github.event.schedule == '0 1 * * 6'
|
||||
run: |
|
||||
echo "BENCH_TYPE=weekly_benchmarks" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Set benchmarks type as quarterly
|
||||
if: (github.event_name == 'workflow_dispatch' && inputs.benchmark_type == 'quarterly') || github.event.schedule == '0 4 25 MAR,JUN,SEP,DEC *'
|
||||
run: |
|
||||
echo "BENCH_TYPE=quarterly_benchmarks" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Start AWS job in Slab
|
||||
shell: bash
|
||||
run: |
|
||||
echo -n '{"command": "${{ matrix.command }}", "git_ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}' > command.json
|
||||
echo -n '{"command": "${{ matrix.command }}", "git_ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "user_inputs": "${{ env.BENCH_TYPE }}"}' > command.json
|
||||
SIGNATURE="$(slab/scripts/hmac_calculator.sh command.json '${{ secrets.JOB_SECRET }}')"
|
||||
curl -v -k \
|
||||
--fail-with-body \
|
||||
|
||||
2
.github/workflows/sync_on_push.yml
vendored
2
.github/workflows/sync_on_push.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Save repo
|
||||
|
||||
12
.github/workflows/wasm_client_benchmark.yml
vendored
12
.github/workflows/wasm_client_benchmark.yml
vendored
@@ -19,6 +19,14 @@ on:
|
||||
request_id:
|
||||
description: "Slab request ID"
|
||||
type: string
|
||||
# This input is not used in this workflow but still mandatory since a calling workflow could
|
||||
# use it. If a triggering command include a user_inputs field, then the triggered workflow
|
||||
# must include this very input, otherwise the workflow won't be called.
|
||||
# See start_full_benchmarks.yml as example.
|
||||
user_inputs:
|
||||
description: "Type of benchmarks to run"
|
||||
type: string
|
||||
default: "weekly_benchmarks"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -43,7 +51,7 @@ jobs:
|
||||
echo "BENCH_DATE=$(date --iso-8601=seconds)" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Checkout tfhe-rs repo with tags
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -95,7 +103,7 @@ jobs:
|
||||
path: ${{ env.RESULTS_FILENAME }}
|
||||
|
||||
- name: Checkout Slab repo
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
with:
|
||||
repository: zama-ai/slab
|
||||
path: slab
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,9 +3,9 @@ target/
|
||||
.vscode/
|
||||
|
||||
# Path we use for internal-keycache during tests
|
||||
./keys/
|
||||
keys/
|
||||
# In case of symlinked keys
|
||||
./keys
|
||||
keys
|
||||
|
||||
**/Cargo.lock
|
||||
**/*.bin
|
||||
|
||||
14
.linelint.yml
Normal file
14
.linelint.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
ignore:
|
||||
- .git
|
||||
- target
|
||||
- tfhe/benchmarks_parameters
|
||||
- tfhe/web_wasm_parallel_tests/node_modules
|
||||
- tfhe/web_wasm_parallel_tests/dist
|
||||
- keys
|
||||
- coverage
|
||||
|
||||
rules:
|
||||
# checks if file ends in a newline character
|
||||
end-of-file:
|
||||
enable: true
|
||||
single-new-line: true
|
||||
218
Makefile
218
Makefile
@@ -6,7 +6,7 @@ TARGET_ARCH_FEATURE:=$(shell ./scripts/get_arch_feature.sh)
|
||||
RS_BUILD_TOOLCHAIN:=stable
|
||||
CARGO_RS_BUILD_TOOLCHAIN:=+$(RS_BUILD_TOOLCHAIN)
|
||||
CARGO_PROFILE?=release
|
||||
MIN_RUST_VERSION:=$(shell grep rust-version tfhe/Cargo.toml | cut -d '=' -f 2 | xargs)
|
||||
MIN_RUST_VERSION:=$(shell grep '^rust-version[[:space:]]*=' tfhe/Cargo.toml | cut -d '=' -f 2 | xargs)
|
||||
AVX512_SUPPORT?=OFF
|
||||
WASM_RUSTFLAGS:=
|
||||
BIG_TESTS_INSTANCE?=FALSE
|
||||
@@ -16,7 +16,17 @@ PARSE_INTEGER_BENCH_CSV_FILE?=tfhe_rs_integer_benches.csv
|
||||
FAST_TESTS?=FALSE
|
||||
FAST_BENCH?=FALSE
|
||||
BENCH_OP_FLAVOR?=DEFAULT
|
||||
COVERAGE_EXCLUDED_FILES = tfhe/benches/*,apps/trivium/src/*,tfhe/examples/*,tasks/src/*
|
||||
NODE_VERSION=20
|
||||
# sed: -n, do not print input stream, -e means a script/expression
|
||||
# 1,/version/ indicates from the first line, to the line matching version at the start of the line
|
||||
# p indicates to print, so we keep only the start of the Cargo.toml until we hit the first version
|
||||
# entry which should be the version of tfhe
|
||||
TFHE_CURRENT_VERSION:=\
|
||||
$(shell sed -n -e '1,/^version/p' tfhe/Cargo.toml | \
|
||||
grep '^version[[:space:]]*=' | cut -d '=' -f 2 | xargs)
|
||||
# Cargo has a hard time distinguishing between our package from the workspace and a package that
|
||||
# could be a dependency, so we build an unambiguous spec here
|
||||
TFHE_SPEC:=tfhe@$(TFHE_CURRENT_VERSION)
|
||||
# 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
|
||||
@@ -43,6 +53,22 @@ endif
|
||||
REGEX_STRING?=''
|
||||
REGEX_PATTERN?=''
|
||||
|
||||
# Exclude these files from coverage reports
|
||||
define COVERAGE_EXCLUDED_FILES
|
||||
--exclude-files apps/trivium/src/trivium/* \
|
||||
--exclude-files apps/trivium/src/kreyvium/* \
|
||||
--exclude-files apps/trivium/src/static_deque/* \
|
||||
--exclude-files apps/trivium/src/trans_ciphering/* \
|
||||
--exclude-files tasks/src/* \
|
||||
--exclude-files tfhe/benches/boolean/* \
|
||||
--exclude-files tfhe/benches/core_crypto/* \
|
||||
--exclude-files tfhe/benches/shortint/* \
|
||||
--exclude-files tfhe/benches/integer/* \
|
||||
--exclude-files tfhe/benches/* \
|
||||
--exclude-files tfhe/examples/regex_engine/* \
|
||||
--exclude-files tfhe/examples/utilities/*
|
||||
endef
|
||||
|
||||
.PHONY: rs_check_toolchain # Echo the rust toolchain used for checks
|
||||
rs_check_toolchain:
|
||||
@echo $(RS_CHECK_TOOLCHAIN)
|
||||
@@ -84,7 +110,7 @@ install_wasm_pack: install_rs_build_toolchain
|
||||
install_node:
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | $(SHELL)
|
||||
source ~/.bashrc
|
||||
$(SHELL) -i -c 'nvm install node' || \
|
||||
$(SHELL) -i -c 'nvm install $(NODE_VERSION)' || \
|
||||
( echo "Unable to install node, unknown error." && exit 1 )
|
||||
|
||||
.PHONY: install_dieharder # Install dieharder for apt distributions or macOS
|
||||
@@ -102,58 +128,71 @@ install_tarpaulin: install_rs_build_toolchain
|
||||
cargo $(CARGO_RS_BUILD_TOOLCHAIN) install cargo-tarpaulin --locked || \
|
||||
( echo "Unable to install cargo tarpaulin, unknown error." && exit 1 )
|
||||
|
||||
.PHONY: check_linelint_installed # Check if linelint newline linter is installed
|
||||
check_linelint_installed:
|
||||
@printf "\n" | linelint - > /dev/null 2>&1 || \
|
||||
( echo "Unable to locate linelint. Try installing it: https://github.com/fernandrone/linelint/releases" && exit 1 )
|
||||
|
||||
.PHONY: fmt # Format rust code
|
||||
fmt: install_rs_check_toolchain
|
||||
cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" fmt
|
||||
|
||||
.PHONT: check_fmt # Check rust code format
|
||||
.PHONY: check_fmt # Check rust code format
|
||||
check_fmt: install_rs_check_toolchain
|
||||
cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" fmt --check
|
||||
|
||||
.PHONY: fix_newline # Fix newline at end of file issues to be UNIX compliant
|
||||
fix_newline: check_linelint_installed
|
||||
linelint -a .
|
||||
|
||||
.PHONY: check_newline # Check for newline at end of file to be UNIX compliant
|
||||
check_newline: check_linelint_installed
|
||||
linelint .
|
||||
|
||||
.PHONY: clippy_core # Run clippy lints on core_crypto with and without experimental features
|
||||
clippy_core: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy \
|
||||
--features=$(TARGET_ARCH_FEATURE) \
|
||||
-p tfhe -- --no-deps -D warnings
|
||||
-p $(TFHE_SPEC) -- --no-deps -D warnings
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental \
|
||||
-p tfhe -- --no-deps -D warnings
|
||||
-p $(TFHE_SPEC) -- --no-deps -D warnings
|
||||
|
||||
.PHONY: clippy_boolean # Run clippy lints enabling the boolean features
|
||||
clippy_boolean: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean \
|
||||
-p tfhe -- --no-deps -D warnings
|
||||
-p $(TFHE_SPEC) -- --no-deps -D warnings
|
||||
|
||||
.PHONY: clippy_shortint # Run clippy lints enabling the shortint features
|
||||
clippy_shortint: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy \
|
||||
--features=$(TARGET_ARCH_FEATURE),shortint \
|
||||
-p tfhe -- --no-deps -D warnings
|
||||
-p $(TFHE_SPEC) -- --no-deps -D warnings
|
||||
|
||||
.PHONY: clippy_integer # Run clippy lints enabling the integer features
|
||||
clippy_integer: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy \
|
||||
--features=$(TARGET_ARCH_FEATURE),integer \
|
||||
-p tfhe -- --no-deps -D warnings
|
||||
-p $(TFHE_SPEC) -- --no-deps -D warnings
|
||||
|
||||
.PHONY: clippy # Run clippy lints enabling the boolean, shortint, integer
|
||||
clippy: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy --all-targets \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer \
|
||||
-p tfhe -- --no-deps -D warnings
|
||||
-p $(TFHE_SPEC) -- --no-deps -D warnings
|
||||
|
||||
.PHONY: clippy_c_api # Run clippy lints enabling the boolean, shortint and the C API
|
||||
clippy_c_api: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api \
|
||||
-p tfhe -- --no-deps -D warnings
|
||||
-p $(TFHE_SPEC) -- --no-deps -D warnings
|
||||
|
||||
.PHONY: clippy_js_wasm_api # Run clippy lints enabling the boolean, shortint, integer and the js wasm API
|
||||
clippy_js_wasm_api: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy \
|
||||
--features=boolean-client-js-wasm-api,shortint-client-js-wasm-api,integer-client-js-wasm-api \
|
||||
-p tfhe -- --no-deps -D warnings
|
||||
-p $(TFHE_SPEC) -- --no-deps -D warnings
|
||||
|
||||
.PHONY: clippy_tasks # Run clippy lints on helper tasks crate.
|
||||
clippy_tasks:
|
||||
@@ -164,13 +203,13 @@ clippy_tasks:
|
||||
clippy_trivium: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy -p tfhe-trivium \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer \
|
||||
-p tfhe -- --no-deps -D warnings
|
||||
-p $(TFHE_SPEC) -- --no-deps -D warnings
|
||||
|
||||
.PHONY: clippy_all_targets # Run clippy lints on all targets (benches, examples, etc.)
|
||||
clippy_all_targets:
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy --all-targets \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache \
|
||||
-p tfhe -- --no-deps -D warnings
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache,safe-deserialization \
|
||||
-p $(TFHE_SPEC) -- --no-deps -D warnings
|
||||
|
||||
.PHONY: clippy_concrete_csprng # Run clippy lints on concrete-csprng
|
||||
clippy_concrete_csprng:
|
||||
@@ -190,58 +229,58 @@ clippy_concrete_csprng
|
||||
gen_key_cache: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) run --profile $(CARGO_PROFILE) \
|
||||
--example generates_test_keys \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,internal-keycache -p tfhe -- \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,internal-keycache -- \
|
||||
$(MULTI_BIT_ONLY) $(COVERAGE_ONLY)
|
||||
|
||||
.PHONY: build_core # Build core_crypto without experimental features
|
||||
build_core: install_rs_build_toolchain install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE) -p tfhe
|
||||
--features=$(TARGET_ARCH_FEATURE) -p $(TFHE_SPEC)
|
||||
@if [[ "$(AVX512_SUPPORT)" == "ON" ]]; then \
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),$(AVX512_FEATURE) -p tfhe; \
|
||||
--features=$(TARGET_ARCH_FEATURE),$(AVX512_FEATURE) -p $(TFHE_SPEC); \
|
||||
fi
|
||||
|
||||
.PHONY: build_core_experimental # Build core_crypto with experimental features
|
||||
build_core_experimental: install_rs_build_toolchain install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental -p tfhe
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental -p $(TFHE_SPEC)
|
||||
@if [[ "$(AVX512_SUPPORT)" == "ON" ]]; then \
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental,$(AVX512_FEATURE) -p tfhe; \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental,$(AVX512_FEATURE) -p $(TFHE_SPEC); \
|
||||
fi
|
||||
|
||||
.PHONY: build_boolean # Build with boolean enabled
|
||||
build_boolean: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean -p tfhe --all-targets
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean -p $(TFHE_SPEC) --all-targets
|
||||
|
||||
.PHONY: build_shortint # Build with shortint enabled
|
||||
build_shortint: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),shortint -p tfhe --all-targets
|
||||
--features=$(TARGET_ARCH_FEATURE),shortint -p $(TFHE_SPEC) --all-targets
|
||||
|
||||
.PHONY: build_integer # Build with integer enabled
|
||||
build_integer: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),integer -p tfhe --all-targets
|
||||
--features=$(TARGET_ARCH_FEATURE),integer -p $(TFHE_SPEC) --all-targets
|
||||
|
||||
.PHONY: build_tfhe_full # Build with boolean, shortint and integer enabled
|
||||
build_tfhe_full: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer -p tfhe --all-targets
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer -p $(TFHE_SPEC) --all-targets
|
||||
|
||||
.PHONY: build_c_api # Build the C API for boolean, shortint and integer
|
||||
build_c_api: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api,high-level-c-api, \
|
||||
-p tfhe
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api,high-level-c-api,safe-deserialization \
|
||||
-p $(TFHE_SPEC)
|
||||
|
||||
.PHONY: build_c_api_experimental_deterministic_fft # Build the C API for boolean, shortint and integer with experimental deterministic FFT
|
||||
build_c_api_experimental_deterministic_fft: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api,high-level-c-api,experimental-force_fft_algo_dif4 \
|
||||
-p tfhe
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api,high-level-c-api,safe-deserialization,experimental-force_fft_algo_dif4 \
|
||||
-p $(TFHE_SPEC)
|
||||
|
||||
.PHONY: build_web_js_api # Build the js API targeting the web browser
|
||||
build_web_js_api: install_rs_build_toolchain install_wasm_pack
|
||||
@@ -274,30 +313,30 @@ build_concrete_csprng: install_rs_build_toolchain
|
||||
.PHONY: test_core_crypto # Run the tests of the core_crypto module including experimental ones
|
||||
test_core_crypto: install_rs_build_toolchain install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental -p tfhe -- core_crypto::
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental -p $(TFHE_SPEC) -- core_crypto::
|
||||
@if [[ "$(AVX512_SUPPORT)" == "ON" ]]; then \
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental,$(AVX512_FEATURE) -p tfhe -- core_crypto::; \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental,$(AVX512_FEATURE) -p $(TFHE_SPEC) -- core_crypto::; \
|
||||
fi
|
||||
|
||||
.PHONY: test_boolean # Run the tests of the boolean module
|
||||
test_boolean: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean -p tfhe -- boolean::
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean -p $(TFHE_SPEC) -- boolean::
|
||||
|
||||
.PHONY: test_boolean_cov # Run the tests of the boolean module with code coverage
|
||||
test_boolean_cov: install_rs_check_toolchain install_tarpaulin
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) tarpaulin --profile $(CARGO_PROFILE) \
|
||||
--out Xml --output-dir coverage/boolean --line --engine Llvm --timeout 500 \
|
||||
--exclude-files $(COVERAGE_EXCLUDED_FILES) \
|
||||
--out xml --output-dir coverage/boolean --line --engine llvm --timeout 500 \
|
||||
$(COVERAGE_EXCLUDED_FILES) \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,internal-keycache,__coverage \
|
||||
-p tfhe -- boolean::
|
||||
-p $(TFHE_SPEC) -- boolean::
|
||||
|
||||
.PHONY: test_c_api_rs # Run the rust tests for the C API
|
||||
test_c_api_rs: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api,high-level-c-api \
|
||||
-p tfhe \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api,high-level-c-api,safe-deserialization \
|
||||
-p $(TFHE_SPEC) \
|
||||
c_api
|
||||
|
||||
.PHONY: test_c_api_c # Run the C tests for the C API
|
||||
@@ -324,45 +363,82 @@ test_shortint_multi_bit_ci: install_rs_build_toolchain install_cargo_nextest
|
||||
.PHONY: test_shortint # Run all the tests for shortint
|
||||
test_shortint: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),shortint,internal-keycache -p tfhe -- shortint::
|
||||
--features=$(TARGET_ARCH_FEATURE),shortint,internal-keycache -p $(TFHE_SPEC) -- shortint::
|
||||
|
||||
.PHONY: test_shortint_cov # Run the tests of the shortint module with code coverage
|
||||
test_shortint_cov: install_rs_check_toolchain install_tarpaulin
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) tarpaulin --profile $(CARGO_PROFILE) \
|
||||
--out Xml --output-dir coverage/shortint --line --engine Llvm --timeout 500 \
|
||||
--exclude-files $(COVERAGE_EXCLUDED_FILES) \
|
||||
--out xml --output-dir coverage/shortint --line --engine llvm --timeout 500 \
|
||||
$(COVERAGE_EXCLUDED_FILES) \
|
||||
--features=$(TARGET_ARCH_FEATURE),shortint,internal-keycache,__coverage \
|
||||
-p tfhe -- shortint::
|
||||
-p $(TFHE_SPEC) -- shortint::
|
||||
|
||||
.PHONY: test_integer_ci # Run the tests for integer ci
|
||||
test_integer_ci: install_rs_build_toolchain install_cargo_nextest
|
||||
test_integer_ci: install_rs_check_toolchain install_cargo_nextest
|
||||
BIG_TESTS_INSTANCE="$(BIG_TESTS_INSTANCE)" \
|
||||
FAST_TESTS="$(FAST_TESTS)" \
|
||||
./scripts/integer-tests.sh --rust-toolchain $(CARGO_RS_BUILD_TOOLCHAIN) \
|
||||
--cargo-profile "$(CARGO_PROFILE)"
|
||||
./scripts/integer-tests.sh --rust-toolchain $(CARGO_RS_CHECK_TOOLCHAIN) \
|
||||
--cargo-profile "$(CARGO_PROFILE)" --avx512-support "$(AVX512_SUPPORT)"
|
||||
|
||||
.PHONY: test_unsigned_integer_ci # Run the tests for unsigned integer ci
|
||||
test_unsigned_integer_ci: install_rs_check_toolchain install_cargo_nextest
|
||||
BIG_TESTS_INSTANCE="$(BIG_TESTS_INSTANCE)" \
|
||||
FAST_TESTS="$(FAST_TESTS)" \
|
||||
./scripts/integer-tests.sh --rust-toolchain $(CARGO_RS_CHECK_TOOLCHAIN) \
|
||||
--cargo-profile "$(CARGO_PROFILE)" --avx512-support "$(AVX512_SUPPORT)" \
|
||||
--unsigned-only
|
||||
|
||||
.PHONY: test_signed_integer_ci # Run the tests for signed integer ci
|
||||
test_signed_integer_ci: install_rs_check_toolchain install_cargo_nextest
|
||||
BIG_TESTS_INSTANCE="$(BIG_TESTS_INSTANCE)" \
|
||||
FAST_TESTS="$(FAST_TESTS)" \
|
||||
./scripts/integer-tests.sh --rust-toolchain $(CARGO_RS_CHECK_TOOLCHAIN) \
|
||||
--cargo-profile "$(CARGO_PROFILE)" --avx512-support "$(AVX512_SUPPORT)" \
|
||||
--signed-only
|
||||
|
||||
.PHONY: test_integer_multi_bit_ci # Run the tests for integer ci running only multibit tests
|
||||
test_integer_multi_bit_ci: install_rs_build_toolchain install_cargo_nextest
|
||||
test_integer_multi_bit_ci: install_rs_check_toolchain install_cargo_nextest
|
||||
BIG_TESTS_INSTANCE="$(BIG_TESTS_INSTANCE)" \
|
||||
FAST_TESTS="$(FAST_TESTS)" \
|
||||
./scripts/integer-tests.sh --rust-toolchain $(CARGO_RS_BUILD_TOOLCHAIN) \
|
||||
--cargo-profile "$(CARGO_PROFILE)" --multi-bit
|
||||
./scripts/integer-tests.sh --rust-toolchain $(CARGO_RS_CHECK_TOOLCHAIN) \
|
||||
--cargo-profile "$(CARGO_PROFILE)" --multi-bit --avx512-support "$(AVX512_SUPPORT)"
|
||||
|
||||
.PHONY: test_unsigned_integer_multi_bit_ci # Run the tests for nsigned integer ci running only multibit tests
|
||||
test_unsigned_integer_multi_bit_ci: install_rs_check_toolchain install_cargo_nextest
|
||||
BIG_TESTS_INSTANCE="$(BIG_TESTS_INSTANCE)" \
|
||||
FAST_TESTS="$(FAST_TESTS)" \
|
||||
./scripts/integer-tests.sh --rust-toolchain $(CARGO_RS_CHECK_TOOLCHAIN) \
|
||||
--cargo-profile "$(CARGO_PROFILE)" --multi-bit --avx512-support "$(AVX512_SUPPORT)" \
|
||||
--unsigned-only
|
||||
|
||||
.PHONY: test_signed_integer_multi_bit_ci # Run the tests for nsigned integer ci running only multibit tests
|
||||
test_signed_integer_multi_bit_ci: install_rs_check_toolchain install_cargo_nextest
|
||||
BIG_TESTS_INSTANCE="$(BIG_TESTS_INSTANCE)" \
|
||||
FAST_TESTS="$(FAST_TESTS)" \
|
||||
./scripts/integer-tests.sh --rust-toolchain $(CARGO_RS_CHECK_TOOLCHAIN) \
|
||||
--cargo-profile "$(CARGO_PROFILE)" --multi-bit --avx512-support "$(AVX512_SUPPORT)" \
|
||||
--signed-only
|
||||
|
||||
.PHONY: test_safe_deserialization # Run the tests for safe deserialization
|
||||
test_safe_deserialization: install_rs_build_toolchain install_cargo_nextest
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache,safe-deserialization -p $(TFHE_SPEC) -- safe_deserialization::
|
||||
|
||||
.PHONY: test_integer # Run all the tests for integer
|
||||
test_integer: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),integer,internal-keycache -p tfhe -- integer::
|
||||
--features=$(TARGET_ARCH_FEATURE),integer,internal-keycache -p $(TFHE_SPEC) -- integer::
|
||||
|
||||
.PHONY: test_high_level_api # Run all the tests for high_level_api
|
||||
test_high_level_api: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache -p tfhe \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache -p $(TFHE_SPEC) \
|
||||
-- high_level_api::
|
||||
|
||||
.PHONY: test_user_doc # Run tests from the .md documentation
|
||||
test_user_doc: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) --doc \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache -p tfhe \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache -p $(TFHE_SPEC) \
|
||||
-- test_user_docs::
|
||||
|
||||
.PHONY: test_regex_engine # Run tests for regex_engine example
|
||||
@@ -425,18 +501,18 @@ format_doc_latex:
|
||||
.PHONY: check_compile_tests # Build tests in debug without running them
|
||||
check_compile_tests:
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --no-run \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental,boolean,shortint,integer,internal-keycache \
|
||||
-p tfhe
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental,boolean,shortint,integer,internal-keycache,safe-deserialization \
|
||||
-p $(TFHE_SPEC)
|
||||
|
||||
@if [[ "$(OS)" == "Linux" || "$(OS)" == "Darwin" ]]; then \
|
||||
"$(MAKE)" build_c_api; \
|
||||
"$(MAKE)" build_c_api && \
|
||||
./scripts/c_api_tests.sh --build-only; \
|
||||
fi
|
||||
|
||||
.PHONY: build_nodejs_test_docker # Build a docker image with tools to run nodejs tests for wasm API
|
||||
build_nodejs_test_docker:
|
||||
DOCKER_BUILDKIT=1 docker build --build-arg RUST_TOOLCHAIN="$(RS_BUILD_TOOLCHAIN)" \
|
||||
-f docker/Dockerfile.wasm_tests -t tfhe-wasm-tests .
|
||||
-f docker/Dockerfile.wasm_tests --build-arg NODE_VERSION=$(NODE_VERSION) -t tfhe-wasm-tests .
|
||||
|
||||
.PHONY: test_nodejs_wasm_api_in_docker # Run tests for the nodejs on wasm API in a docker container
|
||||
test_nodejs_wasm_api_in_docker: build_nodejs_test_docker
|
||||
@@ -460,7 +536,8 @@ test_web_js_api_parallel: build_web_js_api_parallel
|
||||
.PHONY: ci_test_web_js_api_parallel # Run tests for the web wasm api
|
||||
ci_test_web_js_api_parallel: build_web_js_api_parallel
|
||||
source ~/.nvm/nvm.sh && \
|
||||
nvm use node && \
|
||||
nvm install $(NODE_VERSION) && \
|
||||
nvm use $(NODE_VERSION) && \
|
||||
$(MAKE) -C tfhe/web_wasm_parallel_tests test-ci
|
||||
|
||||
.PHONY: no_tfhe_typo # Check we did not invert the h and f in tfhe
|
||||
@@ -479,27 +556,42 @@ dieharder_csprng: install_dieharder build_concrete_csprng
|
||||
# Benchmarks
|
||||
#
|
||||
|
||||
.PHONY: bench_integer # Run benchmarks for integer
|
||||
.PHONY: bench_integer # Run benchmarks for unsigned integer
|
||||
bench_integer: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_BENCH_OP_FLAVOR=$(BENCH_OP_FLAVOR) __TFHE_RS_FAST_BENCH=$(FAST_BENCH) \
|
||||
cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
|
||||
--bench integer-bench \
|
||||
--features=$(TARGET_ARCH_FEATURE),integer,internal-keycache,$(AVX512_FEATURE) -p tfhe --
|
||||
--features=$(TARGET_ARCH_FEATURE),integer,internal-keycache,$(AVX512_FEATURE) -p $(TFHE_SPEC) --
|
||||
|
||||
.PHONY: bench_integer_multi_bit # Run benchmarks for integer using multi-bit parameters
|
||||
.PHONY: bench_integer_multi_bit # Run benchmarks for unsigned integer using multi-bit parameters
|
||||
bench_integer_multi_bit: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_BENCH_TYPE=MULTI_BIT \
|
||||
__TFHE_RS_BENCH_OP_FLAVOR=$(BENCH_OP_FLAVOR) __TFHE_RS_FAST_BENCH=$(FAST_BENCH) \
|
||||
cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
|
||||
--bench integer-bench \
|
||||
--features=$(TARGET_ARCH_FEATURE),integer,internal-keycache,$(AVX512_FEATURE) -p tfhe --
|
||||
--features=$(TARGET_ARCH_FEATURE),integer,internal-keycache,$(AVX512_FEATURE) -p $(TFHE_SPEC) --
|
||||
|
||||
.PHONY: bench_signed_integer # Run benchmarks for signed integer
|
||||
bench_signed_integer: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_BENCH_OP_FLAVOR=$(BENCH_OP_FLAVOR) __TFHE_RS_FAST_BENCH=$(FAST_BENCH) \
|
||||
cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
|
||||
--bench integer-signed-bench \
|
||||
--features=$(TARGET_ARCH_FEATURE),integer,internal-keycache,$(AVX512_FEATURE) -p $(TFHE_SPEC) --
|
||||
|
||||
.PHONY: bench_signed_integer_multi_bit # Run benchmarks for signed integer using multi-bit parameters
|
||||
bench_signed_integer_multi_bit: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_BENCH_TYPE=MULTI_BIT \
|
||||
__TFHE_RS_BENCH_OP_FLAVOR=$(BENCH_OP_FLAVOR) __TFHE_RS_FAST_BENCH=$(FAST_BENCH) \
|
||||
cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
|
||||
--bench integer-signed-bench \
|
||||
--features=$(TARGET_ARCH_FEATURE),integer,internal-keycache,$(AVX512_FEATURE) -p $(TFHE_SPEC) --
|
||||
|
||||
.PHONY: bench_shortint # Run benchmarks for shortint
|
||||
bench_shortint: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_BENCH_OP_FLAVOR=$(BENCH_OP_FLAVOR) \
|
||||
cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
|
||||
--bench shortint-bench \
|
||||
--features=$(TARGET_ARCH_FEATURE),shortint,internal-keycache,$(AVX512_FEATURE) -p tfhe
|
||||
--features=$(TARGET_ARCH_FEATURE),shortint,internal-keycache,$(AVX512_FEATURE) -p $(TFHE_SPEC)
|
||||
|
||||
.PHONY: bench_shortint_multi_bit # Run benchmarks for shortint using multi-bit parameters
|
||||
bench_shortint_multi_bit: install_rs_check_toolchain
|
||||
@@ -507,20 +599,20 @@ bench_shortint_multi_bit: install_rs_check_toolchain
|
||||
__TFHE_RS_BENCH_OP_FLAVOR=$(BENCH_OP_FLAVOR) \
|
||||
cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
|
||||
--bench shortint-bench \
|
||||
--features=$(TARGET_ARCH_FEATURE),shortint,internal-keycache,$(AVX512_FEATURE) -p tfhe --
|
||||
--features=$(TARGET_ARCH_FEATURE),shortint,internal-keycache,$(AVX512_FEATURE) -p $(TFHE_SPEC) --
|
||||
|
||||
|
||||
.PHONY: bench_boolean # Run benchmarks for boolean
|
||||
bench_boolean: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
|
||||
--bench boolean-bench \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,internal-keycache,$(AVX512_FEATURE) -p tfhe
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,internal-keycache,$(AVX512_FEATURE) -p $(TFHE_SPEC)
|
||||
|
||||
.PHONY: bench_pbs # Run benchmarks for PBS
|
||||
bench_pbs: install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
|
||||
--bench pbs-bench \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,internal-keycache,$(AVX512_FEATURE) -p tfhe
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,internal-keycache,$(AVX512_FEATURE) -p $(TFHE_SPEC)
|
||||
|
||||
.PHONY: bench_web_js_api_parallel # Run benchmarks for the web wasm api
|
||||
bench_web_js_api_parallel: build_web_js_api_parallel
|
||||
@@ -604,7 +696,7 @@ pcc: no_tfhe_typo no_dbg_log check_fmt lint_doc clippy_all check_compile_tests
|
||||
fpcc: no_tfhe_typo no_dbg_log check_fmt lint_doc clippy_fast check_compile_tests
|
||||
|
||||
.PHONY: conformance # Automatically fix problems that can be fixed
|
||||
conformance: fmt
|
||||
conformance: fix_newline fmt
|
||||
|
||||
.PHONY: help # Generate list of targets with descriptions
|
||||
help:
|
||||
|
||||
@@ -70,9 +70,7 @@ use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint32, FheUint8};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Basic configuration to use homomorphic integers
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
|
||||
// Key generation
|
||||
let (client_key, server_keys) = generate_keys(config);
|
||||
|
||||
@@ -17,7 +17,7 @@ path = "../../tfhe"
|
||||
features = [ "boolean", "shortint", "integer", "aarch64-unix" ]
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = { version = "0.4", features = [ "html_reports" ]}
|
||||
criterion = { version = "0.5.1", features = [ "html_reports" ]}
|
||||
|
||||
[[bench]]
|
||||
name = "trivium"
|
||||
|
||||
@@ -120,7 +120,7 @@ fn main() {
|
||||
|
||||
# FHE byte Trivium implementation
|
||||
|
||||
The same objects have also been implemented to stream bytes insead of booleans. They can be constructed and used in the same way via the functions `TriviumStreamByte::<u8>::new` and
|
||||
The same objects have also been implemented to stream bytes instead of booleans. They can be constructed and used in the same way via the functions `TriviumStreamByte::<u8>::new` and
|
||||
`TriviumStreamByte::<FheUint8>::new` with the same arguments as before. The `FheUint8` version is significantly slower than the `FheBool` version, because not running
|
||||
with the same cryptographic parameters. Its interest lie in its trans-ciphering capabilities: `TriviumStreamByte<FheUint8>` implements the trait `TransCiphering`,
|
||||
meaning it implements the functions `trans_encrypt_64`. This function takes as input a `FheUint64` and outputs a `FheUint64`, the output being
|
||||
|
||||
@@ -6,7 +6,7 @@ use tfhe_trivium::KreyviumStream;
|
||||
use criterion::Criterion;
|
||||
|
||||
pub fn kreyvium_bool_gen(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_bool().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB000000000000".to_string();
|
||||
@@ -41,7 +41,7 @@ pub fn kreyvium_bool_gen(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
pub fn kreyvium_bool_warmup(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_bool().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB000000000000".to_string();
|
||||
|
||||
@@ -6,9 +6,8 @@ use tfhe_trivium::{KreyviumStreamByte, TransCiphering};
|
||||
use criterion::Criterion;
|
||||
|
||||
pub fn kreyvium_byte_gen(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.enable_function_evaluation_integers()
|
||||
let config = ConfigBuilder::default()
|
||||
.enable_function_evaluation()
|
||||
.build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
@@ -36,9 +35,8 @@ pub fn kreyvium_byte_gen(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
pub fn kreyvium_byte_trans(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.enable_function_evaluation_integers()
|
||||
let config = ConfigBuilder::default()
|
||||
.enable_function_evaluation()
|
||||
.build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
@@ -67,9 +65,8 @@ pub fn kreyvium_byte_trans(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
pub fn kreyvium_byte_warmup(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.enable_function_evaluation_integers()
|
||||
let config = ConfigBuilder::default()
|
||||
.enable_function_evaluation()
|
||||
.build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
|
||||
@@ -8,9 +8,7 @@ use tfhe_trivium::{KreyviumStreamShortint, TransCiphering};
|
||||
use criterion::Criterion;
|
||||
|
||||
pub fn kreyvium_shortint_warmup(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().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();
|
||||
@@ -60,9 +58,7 @@ pub fn kreyvium_shortint_warmup(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
pub fn kreyvium_shortint_gen(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().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();
|
||||
@@ -107,9 +103,7 @@ pub fn kreyvium_shortint_gen(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
pub fn kreyvium_shortint_trans(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().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();
|
||||
|
||||
@@ -6,7 +6,7 @@ use tfhe_trivium::TriviumStream;
|
||||
use criterion::Criterion;
|
||||
|
||||
pub fn trivium_bool_gen(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_bool().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB".to_string();
|
||||
@@ -41,7 +41,7 @@ pub fn trivium_bool_gen(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
pub fn trivium_bool_warmup(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_bool().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB".to_string();
|
||||
|
||||
@@ -6,9 +6,7 @@ use tfhe_trivium::{TransCiphering, TriviumStreamByte};
|
||||
use criterion::Criterion;
|
||||
|
||||
pub fn trivium_byte_gen(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB".to_string();
|
||||
@@ -35,9 +33,7 @@ pub fn trivium_byte_gen(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
pub fn trivium_byte_trans(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB".to_string();
|
||||
@@ -65,9 +61,7 @@ pub fn trivium_byte_trans(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
pub fn trivium_byte_warmup(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB".to_string();
|
||||
|
||||
@@ -8,9 +8,7 @@ use tfhe_trivium::{TransCiphering, TriviumStreamShortint};
|
||||
use criterion::Criterion;
|
||||
|
||||
pub fn trivium_shortint_warmup(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().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();
|
||||
@@ -60,9 +58,7 @@ pub fn trivium_shortint_warmup(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
pub fn trivium_shortint_gen(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().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();
|
||||
@@ -107,9 +103,7 @@ pub fn trivium_shortint_gen(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
pub fn trivium_shortint_trans(c: &mut Criterion) {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().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();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! This module implements the Kreyvium stream cipher, using booleans or FheBool
|
||||
//! for the representaion of the inner bits.
|
||||
//! for the representation of the inner bits.
|
||||
|
||||
use crate::static_deque::StaticDeque;
|
||||
|
||||
@@ -35,7 +35,7 @@ pub struct KreyviumStream<T> {
|
||||
}
|
||||
|
||||
impl KreyviumStream<bool> {
|
||||
/// Contructor for `KreyviumStream<bool>`: arguments are the secret key and the input vector.
|
||||
/// Constructor for `KreyviumStream<bool>`: arguments are the secret key and the input vector.
|
||||
/// Outputs a KreyviumStream object already initialized (1152 steps have been run before
|
||||
/// returning)
|
||||
pub fn new(mut key: [bool; 128], mut iv: [bool; 128]) -> KreyviumStream<bool> {
|
||||
@@ -118,7 +118,7 @@ where
|
||||
T: KreyviumBoolInput<T> + std::marker::Send + std::marker::Sync,
|
||||
for<'a> &'a T: KreyviumBoolInput<T>,
|
||||
{
|
||||
/// Internal generic contructor: arguments are already prepared registers, and an optional FHE
|
||||
/// Internal generic constructor: arguments are already prepared registers, and an optional FHE
|
||||
/// server key
|
||||
fn new_from_registers(
|
||||
a_register: [T; 93],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! This module implements the Kreyvium stream cipher, using u8 or FheUint8
|
||||
//! for the representaion of the inner bits.
|
||||
//! for the representation of the inner bits.
|
||||
|
||||
use crate::static_deque::{StaticByteDeque, StaticByteDequeInput};
|
||||
|
||||
@@ -31,7 +31,7 @@ impl KreyviumByteInput<FheUint8> for &FheUint8 {}
|
||||
/// representation of bits (u8 or FheUint8). To be able to compute FHE operations, it also owns
|
||||
/// an Option for a ServerKey.
|
||||
/// Since the original Kreyvium registers' sizes are not a multiple of 8, these registers (which
|
||||
/// store byte-like objects) have a size that is the eigth of the closest multiple of 8 above the
|
||||
/// store byte-like objects) have a size that is the eighth of the closest multiple of 8 above the
|
||||
/// originals' sizes.
|
||||
pub struct KreyviumStreamByte<T> {
|
||||
a_byte: StaticByteDeque<12, T>,
|
||||
@@ -43,7 +43,7 @@ pub struct KreyviumStreamByte<T> {
|
||||
}
|
||||
|
||||
impl KreyviumStreamByte<u8> {
|
||||
/// Contructor for `KreyviumStreamByte<u8>`: arguments are the secret key and the input vector.
|
||||
/// Constructor for `KreyviumStreamByte<u8>`: arguments are the secret key and the input vector.
|
||||
/// Outputs a KreyviumStream object already initialized (1152 steps have been run before
|
||||
/// returning)
|
||||
pub fn new(key_bytes: [u8; 16], iv_bytes: [u8; 16]) -> KreyviumStreamByte<u8> {
|
||||
@@ -146,7 +146,7 @@ where
|
||||
T: KreyviumByteInput<T> + Send,
|
||||
for<'a> &'a T: KreyviumByteInput<T>,
|
||||
{
|
||||
/// Internal generic contructor: arguments are already prepared registers, and an optional FHE
|
||||
/// Internal generic constructor: arguments are already prepared registers, and an optional FHE
|
||||
/// server key
|
||||
fn new_from_registers(
|
||||
a_register: [T; 12],
|
||||
|
||||
@@ -19,7 +19,7 @@ pub struct KreyviumStreamShortint {
|
||||
}
|
||||
|
||||
impl KreyviumStreamShortint {
|
||||
/// Contructor for KreyviumStreamShortint: arguments are the secret key and the input vector,
|
||||
/// Constructor for KreyviumStreamShortint: arguments are the secret key and the input vector,
|
||||
/// and a ServerKey reference. Outputs a KreyviumStream object already initialized (1152
|
||||
/// steps have been run before returning)
|
||||
pub fn new(
|
||||
|
||||
@@ -170,7 +170,7 @@ fn kreyvium_test_4() {
|
||||
|
||||
#[test]
|
||||
fn kreyvium_test_fhe_long() {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_bool().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB000000000000".to_string();
|
||||
@@ -217,9 +217,7 @@ use tfhe::shortint::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn kreyvium_test_shortint_long() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().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();
|
||||
@@ -302,9 +300,8 @@ fn kreyvium_test_clear_byte() {
|
||||
|
||||
#[test]
|
||||
fn kreyvium_test_byte_long() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.enable_function_evaluation_integers()
|
||||
let config = ConfigBuilder::default()
|
||||
.enable_function_evaluation()
|
||||
.build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
@@ -342,9 +339,8 @@ fn kreyvium_test_byte_long() {
|
||||
|
||||
#[test]
|
||||
fn kreyvium_test_fhe_byte_transciphering_long() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.enable_function_evaluation_integers()
|
||||
let config = ConfigBuilder::default()
|
||||
.enable_function_evaluation()
|
||||
.build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! This module implements the StaticByteDeque struct: a deque of bytes. The idea
|
||||
//! is that this is a wrapper around StaticDeque, but StaticByteDeque has an additional
|
||||
//! functionnality: it can construct the "intermediate" bytes, made of parts of other bytes.
|
||||
//! functionality: it can construct the "intermediate" bytes, made of parts of other bytes.
|
||||
//! This is pretending to store bits, and allows accessing bits in chunks of 8 consecutive.
|
||||
|
||||
use crate::static_deque::StaticDeque;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
use core::ops::{Index, IndexMut};
|
||||
|
||||
/// StaticDeque: a struct implementing a deque whose size is known at compile time.
|
||||
/// It has 2 members: the static array conatining the data (never empty), and a cursor
|
||||
/// It has 2 members: the static array containing the data (never empty), and a cursor
|
||||
/// equal to the index of the oldest element (and the next one to be overwritten).
|
||||
#[derive(Clone)]
|
||||
pub struct StaticDeque<const N: usize, T> {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use crate::{KreyviumStreamByte, KreyviumStreamShortint, TriviumStreamByte, TriviumStreamShortint};
|
||||
use tfhe::shortint::Ciphertext;
|
||||
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{set_server_key, unset_server_key, FheUint64, FheUint8, ServerKey};
|
||||
|
||||
use rayon::prelude::*;
|
||||
|
||||
@@ -232,7 +232,7 @@ fn trivium_test_clear_byte() {
|
||||
|
||||
#[test]
|
||||
fn trivium_test_fhe_long() {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_bool().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB".to_string();
|
||||
@@ -277,9 +277,7 @@ fn trivium_test_fhe_long() {
|
||||
|
||||
#[test]
|
||||
fn trivium_test_fhe_byte_long() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB".to_string();
|
||||
@@ -316,9 +314,7 @@ fn trivium_test_fhe_byte_long() {
|
||||
|
||||
#[test]
|
||||
fn trivium_test_fhe_byte_transciphering_long() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
let key_string = "0053A6F94C9FF24598EB".to_string();
|
||||
@@ -357,9 +353,7 @@ use tfhe::shortint::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn trivium_test_shortint_long() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().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();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! This module implements the Trivium stream cipher, using booleans or FheBool
|
||||
//! for the representaion of the inner bits.
|
||||
//! for the representation of the inner bits.
|
||||
|
||||
use crate::static_deque::StaticDeque;
|
||||
|
||||
@@ -33,7 +33,7 @@ pub struct TriviumStream<T> {
|
||||
}
|
||||
|
||||
impl TriviumStream<bool> {
|
||||
/// Contructor for `TriviumStream<bool>`: arguments are the secret key and the input vector.
|
||||
/// Constructor for `TriviumStream<bool>`: arguments are the secret key and the input vector.
|
||||
/// Outputs a TriviumStream object already initialized (1152 steps have been run before
|
||||
/// returning)
|
||||
pub fn new(key: [bool; 80], iv: [bool; 80]) -> TriviumStream<bool> {
|
||||
@@ -94,7 +94,7 @@ where
|
||||
T: TriviumBoolInput<T> + std::marker::Send + std::marker::Sync,
|
||||
for<'a> &'a T: TriviumBoolInput<T>,
|
||||
{
|
||||
/// Internal generic contructor: arguments are already prepared registers, and an optional FHE
|
||||
/// Internal generic constructor: arguments are already prepared registers, and an optional FHE
|
||||
/// server key
|
||||
fn new_from_registers(
|
||||
a_register: [T; 93],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! This module implements the Trivium stream cipher, using u8 or FheUint8
|
||||
//! for the representaion of the inner bits.
|
||||
//! for the representation of the inner bits.
|
||||
|
||||
use crate::static_deque::{StaticByteDeque, StaticByteDequeInput};
|
||||
|
||||
@@ -31,7 +31,7 @@ impl TriviumByteInput<FheUint8> for &FheUint8 {}
|
||||
/// representation of bits (u8 or FheUint8). To be able to compute FHE operations, it also owns
|
||||
/// an Option for a ServerKey.
|
||||
/// Since the original Trivium registers' sizes are not a multiple of 8, these registers (which
|
||||
/// store byte-like objects) have a size that is the eigth of the closest multiple of 8 above the
|
||||
/// store byte-like objects) have a size that is the eighth of the closest multiple of 8 above the
|
||||
/// originals' sizes.
|
||||
pub struct TriviumStreamByte<T> {
|
||||
a_byte: StaticByteDeque<12, T>,
|
||||
@@ -41,7 +41,7 @@ pub struct TriviumStreamByte<T> {
|
||||
}
|
||||
|
||||
impl TriviumStreamByte<u8> {
|
||||
/// Contructor for `TriviumStreamByte<u8>`: arguments are the secret key and the input vector.
|
||||
/// Constructor for `TriviumStreamByte<u8>`: arguments are the secret key and the input vector.
|
||||
/// Outputs a TriviumStream object already initialized (1152 steps have been run before
|
||||
/// returning)
|
||||
pub fn new(key: [u8; 10], iv: [u8; 10]) -> TriviumStreamByte<u8> {
|
||||
@@ -111,7 +111,7 @@ where
|
||||
T: TriviumByteInput<T> + Send,
|
||||
for<'a> &'a T: TriviumByteInput<T>,
|
||||
{
|
||||
/// Internal generic contructor: arguments are already prepared registers, and an optional FHE
|
||||
/// Internal generic constructor: arguments are already prepared registers, and an optional FHE
|
||||
/// server key
|
||||
fn new_from_registers(
|
||||
a_register: [T; 12],
|
||||
|
||||
@@ -17,9 +17,9 @@ pub struct TriviumStreamShortint {
|
||||
}
|
||||
|
||||
impl TriviumStreamShortint {
|
||||
/// Contructor for TriviumStreamShortint: arguments are the secret key and the input vector, and
|
||||
/// a ServerKey reference. Outputs a TriviumStream object already initialized (1152 steps
|
||||
/// have been run before returning)
|
||||
/// Constructor for TriviumStreamShortint: arguments are the secret key and the input vector,
|
||||
/// and a ServerKey reference. Outputs a TriviumStream object already initialized (1152
|
||||
/// steps have been run before returning)
|
||||
pub fn new(
|
||||
key: [Ciphertext; 80],
|
||||
iv: [u64; 80],
|
||||
|
||||
@@ -36,23 +36,24 @@ def check_security(filename):
|
||||
try:
|
||||
# The lattice estimator is not able to manage such large dimension.
|
||||
# If we have the security for smaller `n` then we have security for larger ones.
|
||||
if param.n >= 32768:
|
||||
if param.n > 16384:
|
||||
param = param.updated(n = 16384)
|
||||
|
||||
usvp_level = LWE.primal_usvp(param, red_cost_model = model)
|
||||
dual_level = LWE.dual_hybrid(param, red_cost_model = model)
|
||||
|
||||
estimator_level = log(min(usvp_level["rop"], dual_level["rop"]),2 )
|
||||
security_level = f"security level = {estimator_level} bits"
|
||||
if estimator_level < 127:
|
||||
print("FAIL")
|
||||
reason = f"attained security level = {estimator_level} bits target is 128 bits"
|
||||
print("FAIL\t({security_level})")
|
||||
reason = f"attained {security_level} target is 128 bits"
|
||||
to_update.append((param, reason))
|
||||
continue
|
||||
except Exception as err:
|
||||
print("FAIL")
|
||||
to_update.append((param, f"{repr(err)}"))
|
||||
else:
|
||||
print("OK")
|
||||
print(f"OK\t({security_level})")
|
||||
|
||||
return to_update
|
||||
|
||||
@@ -72,4 +73,4 @@ if __name__ == "__main__":
|
||||
print(f"[{param.tag}] reason: {reason} (param)")
|
||||
sys.exit(int(1)) # Explicit conversion is needed to make this call work
|
||||
else:
|
||||
print("All parameters passed the security check")
|
||||
print("All parameters passed the security check")
|
||||
|
||||
@@ -20,7 +20,10 @@ def main(args):
|
||||
bench_function_id = bench_data["function_id"]
|
||||
|
||||
split = bench_function_id.split("::")
|
||||
(_, function_name, parameter_set, bits) = split
|
||||
if split.len() == 5: # Signed integers
|
||||
(_, _, function_name, parameter_set, bits) = split
|
||||
else: # Unsigned integers
|
||||
(_, function_name, parameter_set, bits) = split
|
||||
|
||||
if "_scalar_" in bits:
|
||||
(bits, scalar) = bits.split("_bits_scalar_")
|
||||
|
||||
21
ci/slab.toml
21
ci/slab.toml
@@ -21,12 +21,12 @@ check_run_name = "CPU AWS Tests"
|
||||
[command.cpu_integer_test]
|
||||
workflow = "aws_tfhe_integer_tests.yml"
|
||||
profile = "cpu-big"
|
||||
check_run_name = "CPU Integer AWS Tests"
|
||||
check_run_name = "CPU Unsigned Integer AWS Tests"
|
||||
|
||||
[command.cpu_multi_bit_test]
|
||||
workflow = "aws_tfhe_multi_bit_tests.yml"
|
||||
workflow = "aws_tfhe_signed_integer_tests.yml"
|
||||
profile = "cpu-big"
|
||||
check_run_name = "CPU AWS Multi Bit Tests"
|
||||
check_run_name = "CPU Signed Integer AWS Tests"
|
||||
|
||||
[command.cpu_wasm_test]
|
||||
workflow = "aws_tfhe_wasm_tests.yml"
|
||||
@@ -43,6 +43,11 @@ workflow = "integer_full_benchmark.yml"
|
||||
profile = "bench"
|
||||
check_run_name = "Integer CPU AWS Benchmarks Full Suite"
|
||||
|
||||
[command.signed_integer_full_bench]
|
||||
workflow = "signed_integer_full_benchmark.yml"
|
||||
profile = "bench"
|
||||
check_run_name = "Signed Integer CPU AWS Benchmarks Full Suite"
|
||||
|
||||
[command.integer_bench]
|
||||
workflow = "integer_benchmark.yml"
|
||||
profile = "bench"
|
||||
@@ -53,6 +58,16 @@ workflow = "integer_multi_bit_benchmark.yml"
|
||||
profile = "bench"
|
||||
check_run_name = "Integer multi bit CPU AWS Benchmarks"
|
||||
|
||||
[command.signed_integer_bench]
|
||||
workflow = "signed_integer_benchmark.yml"
|
||||
profile = "bench"
|
||||
check_run_name = "Signed integer CPU AWS Benchmarks"
|
||||
|
||||
[command.signed_integer_multi_bit_bench]
|
||||
workflow = "signed_integer_multi_bit_benchmark.yml"
|
||||
profile = "bench"
|
||||
check_run_name = "Signed integer multi bit CPU AWS Benchmarks"
|
||||
|
||||
[command.shortint_full_bench]
|
||||
workflow = "shortint_full_benchmark.yml"
|
||||
profile = "bench"
|
||||
|
||||
@@ -9,6 +9,7 @@ documentation = "https://docs.zama.ai/tfhe-rs"
|
||||
repository = "https://github.com/zama-ai/tfhe-rs"
|
||||
readme = "README.md"
|
||||
keywords = ["fully", "homomorphic", "encryption", "fhe", "cryptography"]
|
||||
rust-version = "1.72"
|
||||
|
||||
[dependencies]
|
||||
aes = "0.8.2"
|
||||
@@ -19,8 +20,8 @@ libc = "0.2.133"
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8.3"
|
||||
criterion = "0.3"
|
||||
clap = "=4.2.7"
|
||||
criterion = "0.5.1"
|
||||
clap = "=4.4.4"
|
||||
|
||||
[features]
|
||||
parallel = ["rayon"]
|
||||
|
||||
@@ -17,7 +17,7 @@ pub struct BytesPerChild(pub usize);
|
||||
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
|
||||
pub struct ByteCount(pub u128);
|
||||
|
||||
/// An error occuring during a generator fork.
|
||||
/// An error occurring during a generator fork.
|
||||
#[derive(Debug)]
|
||||
pub enum ForkError {
|
||||
ForkTooLarge,
|
||||
@@ -145,7 +145,7 @@ pub mod generator_generic_test {
|
||||
|
||||
/// Checks that the PRNG roughly generates uniform numbers.
|
||||
///
|
||||
/// To do that, we perform an histogram of the occurences of each byte value, over a fixed
|
||||
/// To do that, we perform an histogram of the occurrences of each byte value, over a fixed
|
||||
/// number of samples and check that the empirical probabilities of the bins are close to
|
||||
/// the theoretical probabilities.
|
||||
pub fn test_roughly_uniform<G: RandomGenerator>() {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! When initializing a generator, one needs to provide a [`Seed`], which is then used as key to the
|
||||
//! AES blockcipher. As a consequence, the quality of the outputs of the generator is directly
|
||||
//! conditioned by the quality of this seed. This module proposes different mechanisms to deliver
|
||||
//! seeds that can accomodate varying scenarios.
|
||||
//! seeds that can accommodate varying scenarios.
|
||||
|
||||
/// A seed value, used to initialize a generator.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
@@ -15,7 +15,7 @@ pub trait Seeder {
|
||||
fn seed(&mut self) -> Seed;
|
||||
|
||||
/// Check whether the seeder can be used on the current machine. This function may check if some
|
||||
/// required CPU features are available or if some OS features are availble for example.
|
||||
/// required CPU features are available or if some OS features are available for example.
|
||||
fn is_available() -> bool
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
@@ -11,6 +11,7 @@ RUN sed -i 's|^deb http://archive.ubuntu.com/ubuntu/|deb http://mirror.ubuntu.ik
|
||||
ENV CARGO_TARGET_DIR=/root/tfhe-rs-target
|
||||
|
||||
ARG RUST_TOOLCHAIN="stable"
|
||||
ARG NODE_VERSION
|
||||
|
||||
WORKDIR /tfhe-wasm-tests
|
||||
|
||||
@@ -34,6 +35,6 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > install-rustup.s
|
||||
chmod +x install-node.sh && \
|
||||
./install-node.sh && \
|
||||
. "$HOME/.nvm/nvm.sh" && \
|
||||
bash -i -c 'nvm install node && nvm use node'
|
||||
bash -i -c 'nvm install ${NODE_VERSION} && nvm use ${NODE_VERSION}'
|
||||
|
||||
WORKDIR /tfhe-wasm-tests/tfhe-rs/
|
||||
|
||||
@@ -8,14 +8,23 @@ 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 "--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 "--cargo-profile The cargo profile used to build tests"
|
||||
echo "--avx512-support Set to ON to enable avx512"
|
||||
echo
|
||||
}
|
||||
|
||||
RUST_TOOLCHAIN="+stable"
|
||||
multi_bit=""
|
||||
not_multi_bit="_multi_bit"
|
||||
# Run signed test by default
|
||||
signed=""
|
||||
not_signed=""
|
||||
cargo_profile="release"
|
||||
# TODO: revert to release once the bug is properly fixed/identified
|
||||
cargo_profile_doctests="release_lto_off"
|
||||
avx512_feature=""
|
||||
|
||||
while [ -n "$1" ]
|
||||
do
|
||||
@@ -35,11 +44,28 @@ do
|
||||
not_multi_bit=""
|
||||
;;
|
||||
|
||||
"--unsigned-only" )
|
||||
signed=""
|
||||
not_signed="_signed"
|
||||
;;
|
||||
|
||||
"--signed-only" )
|
||||
signed="_signed"
|
||||
not_signed=""
|
||||
;;
|
||||
|
||||
"--cargo-profile" )
|
||||
shift
|
||||
cargo_profile="$1"
|
||||
;;
|
||||
|
||||
"--avx512-support" )
|
||||
shift
|
||||
if [[ "$1" == "ON" ]]; then
|
||||
avx512_feature=nightly-avx512
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown param : $1"
|
||||
exit 1
|
||||
@@ -62,104 +88,86 @@ if [[ $(uname) == "Darwin" ]]; then
|
||||
nproc_bin="sysctl -n hw.logicalcpu"
|
||||
fi
|
||||
|
||||
n_threads="$(${nproc_bin})"
|
||||
# TODO autodetect/have a finer CPU count depending on memory
|
||||
num_cpu_threads="$(${nproc_bin})"
|
||||
|
||||
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
|
||||
n_threads=1
|
||||
small_instance_n_threads=1
|
||||
fi
|
||||
else
|
||||
# Keys are 4.7 gigs at max, test machine has 32 gigs of RAM
|
||||
n_threads=6
|
||||
small_instance_n_threads=6
|
||||
fi
|
||||
|
||||
if [[ "${BIG_TESTS_INSTANCE}" != TRUE ]]; then
|
||||
if [[ "${FAST_TESTS}" != TRUE ]]; then
|
||||
# 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 is too slow
|
||||
# so is test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs
|
||||
filter_expression="""\
|
||||
test(/^integer::.*${multi_bit}/) \
|
||||
${not_multi_bit:+"and not test(~${not_multi_bit})"} \
|
||||
and not test(/.*_block_pbs(_base)?_param_message_[34]_carry_[34]_ks_pbs$/) \
|
||||
and not test(~mul_crt_param_message_4_carry_4_ks_pbs) \
|
||||
and not test(/.*test_wopbs_bivariate_crt_wopbs_param_message_[34]_carry_[34]_ks_pbs$/) \
|
||||
and not test(/.*test_integer_smart_mul_param_message_4_carry_4_ks_pbs$/) \
|
||||
and not test(/.*test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs$/)"""
|
||||
else
|
||||
# test only fast default operations with only two set of parameters
|
||||
filter_expression="""\
|
||||
test(/^integer::.*${multi_bit}/) \
|
||||
${not_multi_bit:+"and not test(~${not_multi_bit})"} \
|
||||
and test(/.*_default_.*?_param${multi_bit}_message_[2-3]_carry_[2-3]${multi_bit:+"_group_2"}_ks_pbs/) \
|
||||
and not test(/.*_param_message_[14]_carry_[14]_ks_pbs$/) \
|
||||
and not test(/.*default_add_sequence_multi_thread_param_message_3_carry_3_ks_pbs$/)"""
|
||||
fi
|
||||
|
||||
cargo "${RUST_TOOLCHAIN}" nextest run \
|
||||
--tests \
|
||||
--cargo-profile "${cargo_profile}" \
|
||||
--package tfhe \
|
||||
--profile ci \
|
||||
--features="${ARCH_FEATURE}",integer,internal-keycache \
|
||||
--test-threads "${n_threads}" \
|
||||
-E "$filter_expression"
|
||||
|
||||
if [[ "${multi_bit}" == "" ]]; then
|
||||
cargo "${RUST_TOOLCHAIN}" test \
|
||||
--profile "${cargo_profile}" \
|
||||
--package tfhe \
|
||||
--features="${ARCH_FEATURE}",integer,internal-keycache \
|
||||
--doc \
|
||||
-- integer::
|
||||
fi
|
||||
if [[ "${BIG_TESTS_INSTANCE}" == TRUE ]]; then
|
||||
test_threads="$((num_cpu_threads * 1 / 2))"
|
||||
doctest_threads="${num_cpu_threads}"
|
||||
else
|
||||
if [[ "${FAST_TESTS}" != TRUE ]]; then
|
||||
# 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 is too slow
|
||||
# so is test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs
|
||||
filter_expression="""\
|
||||
test_threads="${small_instance_n_threads}"
|
||||
doctest_threads="${num_cpu_threads}"
|
||||
fi
|
||||
|
||||
# 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 is too slow
|
||||
# so is test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs
|
||||
# we skip smart_div, smart_rem which are already covered by the smar_div_rem test
|
||||
# we similarly skip default_div, default_rem which are covered by default_div_rem
|
||||
full_test_filter_expression="""\
|
||||
test(/^integer::.*${multi_bit}/) \
|
||||
${signed:+"and test(/^integer::.*${signed}/)"} \
|
||||
${not_multi_bit:+"and not test(~${not_multi_bit})"} \
|
||||
${not_signed:+"and not test(~${not_signed})"} \
|
||||
and not test(/.*integer_smart_div_param/) \
|
||||
and not test(/.*integer_smart_rem_param/) \
|
||||
and not test(/.*integer_default_div_param/) \
|
||||
and not test(/.*integer_default_rem_param/) \
|
||||
and not test(/.*_block_pbs(_base)?_param_message_[34]_carry_[34]_ks_pbs$/) \
|
||||
and not test(~mul_crt_param_message_4_carry_4_ks_pbs) \
|
||||
and not test(/.*test_wopbs_bivariate_crt_wopbs_param_message_[34]_carry_[34]_ks_pbs$/) \
|
||||
and not test(/.*test_integer_smart_mul_param_message_4_carry_4_ks_pbs$/) \
|
||||
and not test(/.*test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs$/)"""
|
||||
else
|
||||
# test only fast default operations with only two set of parameters
|
||||
filter_expression="""\
|
||||
|
||||
# test only fast default operations with only two set of parameters
|
||||
# we skip default_div, default_rem which are covered by default_div_rem
|
||||
fast_test_filter_expression="""\
|
||||
test(/^integer::.*${multi_bit}/) \
|
||||
${signed:+"and test(/^integer::.*${signed}/)"} \
|
||||
${not_multi_bit:+"and not test(~${not_multi_bit})"} \
|
||||
${not_signed:+"and not test(~${not_signed})"} \
|
||||
and test(/.*_default_.*?_param${multi_bit}_message_[2-3]_carry_[2-3]${multi_bit:+"_group_2"}_ks_pbs/) \
|
||||
and not test(/.*integer_default_div_param/) \
|
||||
and not test(/.*integer_default_rem_param/) \
|
||||
and not test(/.*_param_message_[14]_carry_[14]_ks_pbs$/) \
|
||||
and not test(/.*default_add_sequence_multi_thread_param_message_3_carry_3_ks_pbs$/)"""
|
||||
fi
|
||||
|
||||
num_cpu_threads="$(${nproc_bin})"
|
||||
num_threads=$((num_cpu_threads * 1 / 2))
|
||||
cargo "${RUST_TOOLCHAIN}" nextest run \
|
||||
--tests \
|
||||
--cargo-profile "${cargo_profile}" \
|
||||
if [[ "${FAST_TESTS}" == "TRUE" ]]; then
|
||||
echo "Running 'fast' test set'"
|
||||
filter_expression="${fast_test_filter_expression}"
|
||||
else
|
||||
echo "Running 'slow' test set"
|
||||
filter_expression="${full_test_filter_expression}"
|
||||
fi
|
||||
|
||||
cargo "${RUST_TOOLCHAIN}" nextest run \
|
||||
--tests \
|
||||
--cargo-profile "${cargo_profile}" \
|
||||
--package tfhe \
|
||||
--profile ci \
|
||||
--features="${ARCH_FEATURE}",integer,internal-keycache,"${avx512_feature}" \
|
||||
--test-threads "${test_threads}" \
|
||||
-E "$filter_expression"
|
||||
|
||||
if [[ "${multi_bit}" == "" ]]; then
|
||||
cargo "${RUST_TOOLCHAIN}" test \
|
||||
--profile "${cargo_profile_doctests}" \
|
||||
--package tfhe \
|
||||
--profile ci \
|
||||
--features="${ARCH_FEATURE}",integer,internal-keycache \
|
||||
--test-threads $num_threads \
|
||||
-E "$filter_expression"
|
||||
|
||||
if [[ "${multi_bit}" == "" ]]; then
|
||||
cargo "${RUST_TOOLCHAIN}" test \
|
||||
--profile "${cargo_profile}" \
|
||||
--package tfhe \
|
||||
--features="${ARCH_FEATURE}",integer,internal-keycache \
|
||||
--doc \
|
||||
-- --test-threads="$(${nproc_bin})" integer::
|
||||
fi
|
||||
--features="${ARCH_FEATURE}",integer,internal-keycache,"${avx512_feature}" \
|
||||
--doc \
|
||||
-- --test-threads="${doctest_threads}" integer::
|
||||
fi
|
||||
|
||||
echo "Test ran in $SECONDS seconds"
|
||||
|
||||
@@ -94,6 +94,7 @@ or test(/^shortint::.*_param${multi_bit}_message_2_carry_3${multi_bit:+"_group_[
|
||||
or test(/^shortint::.*_param${multi_bit}_message_3_carry_1${multi_bit:+"_group_[0-9]"}(_compact_pk)?_ks_pbs/) \
|
||||
or test(/^shortint::.*_param${multi_bit}_message_3_carry_2${multi_bit:+"_group_[0-9]"}(_compact_pk)?_ks_pbs/) \
|
||||
or test(/^shortint::.*_param${multi_bit}_message_3_carry_3${multi_bit:+"_group_[0-9]"}(_compact_pk)?_ks_pbs/) \
|
||||
or test(/^shortint::.*_ci_run_filter/) \
|
||||
)\
|
||||
and not test(~smart_add_and_mul)""" # This test is too slow
|
||||
else
|
||||
@@ -159,6 +160,7 @@ or test(/^shortint::.*_param${multi_bit}_message_3_carry_1${multi_bit:+"_group_[
|
||||
or test(/^shortint::.*_param${multi_bit}_message_3_carry_2${multi_bit:+"_group_[0-9]"}(_compact_pk)?_ks_pbs/) \
|
||||
or test(/^shortint::.*_param${multi_bit}_message_3_carry_3${multi_bit:+"_group_[0-9]"}(_compact_pk)?_ks_pbs/) \
|
||||
or test(/^shortint::.*_param${multi_bit}_message_4_carry_4${multi_bit:+"_group_[0-9]"}(_compact_pk)?_ks_pbs/) \
|
||||
or test(/^shortint::.*_ci_run_filter/) \
|
||||
)\
|
||||
and not test(~smart_add_and_mul)""" # This test is too slow
|
||||
else
|
||||
|
||||
@@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
clap = "3.1"
|
||||
clap = "=4.4.4"
|
||||
lazy_static = "1.4"
|
||||
log = "0.4"
|
||||
simplelog = "0.12"
|
||||
|
||||
2
tfhe/.gitignore
vendored
2
tfhe/.gitignore
vendored
@@ -1 +1 @@
|
||||
build/
|
||||
build/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tfhe"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
edition = "2021"
|
||||
readme = "../README.md"
|
||||
keywords = ["fully", "homomorphic", "encryption", "fhe", "cryptography"]
|
||||
@@ -26,16 +26,16 @@ rand = "0.8.5"
|
||||
rand_distr = "0.4.3"
|
||||
paste = "1.0.7"
|
||||
lazy_static = { version = "1.4.0" }
|
||||
criterion = "0.4.0"
|
||||
criterion = "0.5.1"
|
||||
doc-comment = "0.3.3"
|
||||
serde_json = "1.0.94"
|
||||
# clap has to be pinned as its minimum supported rust version
|
||||
# changes often between minor releases, which breaks our CI
|
||||
clap = { version = "=4.2.7", features = ["derive"] }
|
||||
clap = { version = "=4.4.4", features = ["derive"] }
|
||||
# Used in user documentation
|
||||
bincode = "1.3.3"
|
||||
fs2 = { version = "0.4.3" }
|
||||
itertools = "0.10.5"
|
||||
itertools = "0.11.0"
|
||||
# For erf and normality test
|
||||
libm = "0.2.6"
|
||||
# Begin regex-engine deps
|
||||
@@ -46,10 +46,10 @@ log = "0.4.19"
|
||||
# End regex-engine deps
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = { version = "0.24.3", optional = true }
|
||||
cbindgen = { version = "0.26.0", optional = true }
|
||||
|
||||
[dependencies]
|
||||
concrete-csprng = { version = "0.4.0", path= "../concrete-csprng", features = [
|
||||
concrete-csprng = { version = "0.4.0", path = "../concrete-csprng", features = [
|
||||
"generator_fallback",
|
||||
"parallel",
|
||||
] }
|
||||
@@ -64,7 +64,7 @@ dyn-stack = { version = "0.9" }
|
||||
paste = { version = "1.0.7", optional = true }
|
||||
fs2 = { version = "0.4.3", optional = true }
|
||||
# While we wait for repeat_n in rust standard library
|
||||
itertools = "0.10.5"
|
||||
itertools = "0.11.0"
|
||||
|
||||
# wasm deps
|
||||
wasm-bindgen = { version = "0.2.86", features = [
|
||||
@@ -73,7 +73,7 @@ wasm-bindgen = { version = "0.2.86", features = [
|
||||
wasm-bindgen-rayon = { version = "1.0", optional = true }
|
||||
js-sys = { version = "0.3", optional = true }
|
||||
console_error_panic_hook = { version = "0.1.7", optional = true }
|
||||
serde-wasm-bindgen = { version = "0.4", optional = true }
|
||||
serde-wasm-bindgen = { version = "0.6.0", optional = true }
|
||||
getrandom = { version = "0.2.8", optional = true }
|
||||
bytemuck = "1.13.1"
|
||||
|
||||
@@ -82,32 +82,36 @@ bytemuck = "1.13.1"
|
||||
boolean = ["dep:paste"]
|
||||
shortint = ["dep:paste"]
|
||||
integer = ["shortint", "dep:paste"]
|
||||
internal-keycache = ["lazy_static", "dep:fs2", "bincode", "dep:paste"]
|
||||
internal-keycache = ["dep:lazy_static", "dep:fs2", "dep:bincode", "dep:paste"]
|
||||
safe-deserialization = ["dep:bincode"]
|
||||
|
||||
# Experimental section
|
||||
experimental = []
|
||||
experimental-force_fft_algo_dif4 = []
|
||||
# End experimental section
|
||||
|
||||
__c_api = ["cbindgen", "bincode", "dep:paste"]
|
||||
__c_api = ["dep:cbindgen", "dep:bincode", "dep:paste"]
|
||||
# For the semver trick to skip the build.rs
|
||||
__force_skip_cbindgen = []
|
||||
boolean-c-api = ["boolean", "__c_api"]
|
||||
shortint-c-api = ["shortint", "__c_api"]
|
||||
high-level-c-api = ["boolean-c-api", "shortint-c-api", "integer", "__c_api"]
|
||||
|
||||
__wasm_api = [
|
||||
"wasm-bindgen",
|
||||
"js-sys",
|
||||
"console_error_panic_hook",
|
||||
"serde-wasm-bindgen",
|
||||
"getrandom",
|
||||
"dep:wasm-bindgen",
|
||||
"dep:js-sys",
|
||||
"dep:console_error_panic_hook",
|
||||
"dep:serde-wasm-bindgen",
|
||||
"dep:getrandom",
|
||||
"getrandom/js",
|
||||
"bincode",
|
||||
"dep:bincode",
|
||||
"safe-deserialization",
|
||||
]
|
||||
boolean-client-js-wasm-api = ["boolean", "__wasm_api"]
|
||||
shortint-client-js-wasm-api = ["shortint", "__wasm_api"]
|
||||
integer-client-js-wasm-api = ["integer", "__wasm_api"]
|
||||
high-level-client-js-wasm-api = ["boolean", "shortint", "integer", "__wasm_api"]
|
||||
parallel-wasm-api = ["wasm-bindgen-rayon"]
|
||||
parallel-wasm-api = ["dep:wasm-bindgen-rayon"]
|
||||
|
||||
nightly-avx512 = ["concrete-fft/nightly", "pulp/nightly"]
|
||||
|
||||
@@ -182,6 +186,12 @@ path = "benches/integer/bench.rs"
|
||||
harness = false
|
||||
required-features = ["integer", "internal-keycache"]
|
||||
|
||||
[[bench]]
|
||||
name = "integer-signed-bench"
|
||||
path = "benches/integer/signed_bench.rs"
|
||||
harness = false
|
||||
required-features = ["integer", "internal-keycache"]
|
||||
|
||||
[[bench]]
|
||||
name = "keygen"
|
||||
path = "benches/keygen/bench.rs"
|
||||
@@ -204,7 +214,7 @@ required-features = ["shortint", "internal-keycache"]
|
||||
[[example]]
|
||||
name = "generates_test_keys"
|
||||
path = "examples/utilities/generates_test_keys.rs"
|
||||
required-features = ["shortint", "internal-keycache"]
|
||||
required-features = ["boolean", "shortint", "internal-keycache"]
|
||||
|
||||
[[example]]
|
||||
name = "boolean_key_sizes"
|
||||
|
||||
@@ -43,7 +43,7 @@ pub fn write_to_json_boolean<T: Into<CryptoParametersRecord<u32>>>(
|
||||
|
||||
// Put all `bench_function` in one place
|
||||
// so the keygen is only run once per parameters saving time.
|
||||
fn benchs(c: &mut Criterion, params: BooleanParameters, parameter_name: &str) {
|
||||
fn benches(c: &mut Criterion, params: BooleanParameters, parameter_name: &str) {
|
||||
let mut bench_group = c.benchmark_group("gates_benches");
|
||||
|
||||
let cks = ClientKey::new(¶ms);
|
||||
@@ -83,15 +83,15 @@ fn benchs(c: &mut Criterion, params: BooleanParameters, parameter_name: &str) {
|
||||
}
|
||||
|
||||
fn bench_default_parameters(c: &mut Criterion) {
|
||||
benchs(c, DEFAULT_PARAMETERS, "DEFAULT_PARAMETERS");
|
||||
benches(c, DEFAULT_PARAMETERS, "DEFAULT_PARAMETERS");
|
||||
}
|
||||
|
||||
fn bench_default_parameters_ks_pbs(c: &mut Criterion) {
|
||||
benchs(c, DEFAULT_PARAMETERS_KS_PBS, "DEFAULT_PARAMETERS_KS_PBS");
|
||||
benches(c, DEFAULT_PARAMETERS_KS_PBS, "DEFAULT_PARAMETERS_KS_PBS");
|
||||
}
|
||||
|
||||
fn bench_low_prob_parameters(c: &mut Criterion) {
|
||||
benchs(
|
||||
benches(
|
||||
c,
|
||||
PARAMETERS_ERROR_PROB_2_POW_MINUS_165,
|
||||
"PARAMETERS_ERROR_PROB_2_POW_MINUS_165",
|
||||
@@ -99,7 +99,7 @@ fn bench_low_prob_parameters(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
fn bench_low_prob_parameters_ks_pbs(c: &mut Criterion) {
|
||||
benchs(
|
||||
benches(
|
||||
c,
|
||||
PARAMETERS_ERROR_PROB_2_POW_MINUS_165_KS_PBS,
|
||||
"PARAMETERS_ERROR_PROB_2_POW_MINUS_165_KS_PBS",
|
||||
@@ -107,5 +107,5 @@ fn bench_low_prob_parameters_ks_pbs(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
fn bench_tfhe_lib_parameters(c: &mut Criterion) {
|
||||
benchs(c, TFHE_LIB_PARAMETERS, " TFHE_LIB_PARAMETERS");
|
||||
benches(c, TFHE_LIB_PARAMETERS, " TFHE_LIB_PARAMETERS");
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ fn multi_bit_pbs<Scalar: UnsignedTorus + CastInto<usize> + CastFrom<usize> + Syn
|
||||
);
|
||||
|
||||
let id = format!("Multi Bit PBS {}", Scalar::BITS);
|
||||
#[allow(clippy::unit_arg)]
|
||||
|
||||
{
|
||||
c.bench_function(&id, |b| {
|
||||
b.iter(|| {
|
||||
|
||||
@@ -12,7 +12,7 @@ use rand::prelude::*;
|
||||
use rand::Rng;
|
||||
use std::vec::IntoIter;
|
||||
use tfhe::integer::keycache::KEY_CACHE;
|
||||
use tfhe::integer::{RadixCiphertext, ServerKey};
|
||||
use tfhe::integer::{IntegerKeyKind, RadixCiphertext, ServerKey};
|
||||
use tfhe::keycache::NamedParam;
|
||||
|
||||
use tfhe::integer::U256;
|
||||
@@ -118,7 +118,7 @@ fn bench_server_key_binary_function_dirty_inputs<F>(
|
||||
|
||||
let bench_id = format!("{bench_name}::{param_name}::{bit_size}_bits");
|
||||
bench_group.bench_function(&bench_id, |b| {
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param);
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param, IntegerKeyKind::Radix);
|
||||
|
||||
let encrypt_two_values = || {
|
||||
let clear_0 = gen_random_u256(&mut rng);
|
||||
@@ -186,7 +186,7 @@ fn bench_server_key_binary_function_clean_inputs<F>(
|
||||
|
||||
let bench_id = format!("{bench_name}::{param_name}::{bit_size}_bits");
|
||||
bench_group.bench_function(&bench_id, |b| {
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param);
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param, IntegerKeyKind::Radix);
|
||||
|
||||
let encrypt_two_values = || {
|
||||
let clear_0 = gen_random_u256(&mut rng);
|
||||
@@ -243,7 +243,7 @@ fn bench_server_key_unary_function_dirty_inputs<F>(
|
||||
|
||||
let bench_id = format!("{bench_name}::{param_name}::{bit_size}_bits");
|
||||
bench_group.bench_function(&bench_id, |b| {
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param);
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param, IntegerKeyKind::Radix);
|
||||
|
||||
let encrypt_one_value = || {
|
||||
let clear_0 = gen_random_u256(&mut rng);
|
||||
@@ -308,7 +308,7 @@ fn bench_server_key_unary_function_clean_inputs<F>(
|
||||
|
||||
let bench_id = format!("{bench_name}::{param_name}::{bit_size}_bits");
|
||||
bench_group.bench_function(&bench_id, |b| {
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param);
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param, IntegerKeyKind::Radix);
|
||||
|
||||
let encrypt_one_value = || {
|
||||
let clear_0 = gen_random_u256(&mut rng);
|
||||
@@ -362,7 +362,7 @@ fn bench_server_key_binary_scalar_function_dirty_inputs<F, G>(
|
||||
|
||||
let bench_id = format!("{bench_name}::{param_name}::{bit_size}_bits");
|
||||
bench_group.bench_function(&bench_id, |b| {
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param);
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param, IntegerKeyKind::Radix);
|
||||
|
||||
let encrypt_one_value = || {
|
||||
let clear_0 = gen_random_u256(&mut rng);
|
||||
@@ -435,7 +435,7 @@ fn bench_server_key_binary_scalar_function_clean_inputs<F, G>(
|
||||
|
||||
let bench_id = format!("{bench_name}::{param_name}::{bit_size}_bits_scalar_{bit_size}");
|
||||
bench_group.bench_function(&bench_id, |b| {
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param);
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param, IntegerKeyKind::Radix);
|
||||
|
||||
let encrypt_one_value = || {
|
||||
let clear_0 = gen_random_u256(&mut rng);
|
||||
@@ -515,7 +515,7 @@ fn if_then_else_parallelized(c: &mut Criterion) {
|
||||
|
||||
let bench_id = format!("{bench_name}::{param_name}::{bit_size}_bits");
|
||||
bench_group.bench_function(&bench_id, |b| {
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param);
|
||||
let (cks, sks) = KEY_CACHE.get_from_params(param, IntegerKeyKind::Radix);
|
||||
|
||||
let encrypt_tree_values = || {
|
||||
let clear_0 = gen_random_u256(&mut rng);
|
||||
@@ -524,7 +524,7 @@ fn if_then_else_parallelized(c: &mut Criterion) {
|
||||
let clear_1 = gen_random_u256(&mut rng);
|
||||
let ct_1 = cks.encrypt_radix(clear_1, num_block);
|
||||
|
||||
let cond = sks.create_trivial_radix(rng.gen_bool(0.5) as u64, num_block);
|
||||
let cond = sks.create_trivial_boolean_block(rng.gen_bool(0.5));
|
||||
|
||||
(cond, ct_0, ct_1)
|
||||
};
|
||||
@@ -650,15 +650,23 @@ define_server_key_bench_fn!(method_name: smart_bitxor, display_name: bitxor);
|
||||
define_server_key_bench_fn!(method_name: smart_add_parallelized, display_name: add);
|
||||
define_server_key_bench_fn!(method_name: smart_sub_parallelized, display_name: sub);
|
||||
define_server_key_bench_fn!(method_name: smart_mul_parallelized, display_name: mul);
|
||||
define_server_key_bench_fn!(method_name: smart_div_parallelized, display_name: div);
|
||||
define_server_key_bench_fn!(method_name: smart_div_rem_parallelized, display_name: div_mod);
|
||||
define_server_key_bench_fn!(method_name: smart_rem_parallelized, display_name: rem);
|
||||
define_server_key_bench_fn!(method_name: smart_bitand_parallelized, display_name: bitand);
|
||||
define_server_key_bench_fn!(method_name: smart_bitxor_parallelized, display_name: bitxor);
|
||||
define_server_key_bench_fn!(method_name: smart_bitor_parallelized, display_name: bitor);
|
||||
define_server_key_bench_fn!(method_name: smart_rotate_right_parallelized, display_name: rotate_right);
|
||||
define_server_key_bench_fn!(method_name: smart_rotate_left_parallelized, display_name: rotate_left);
|
||||
define_server_key_bench_fn!(method_name: smart_right_shift_parallelized, display_name: right_shift);
|
||||
define_server_key_bench_fn!(method_name: smart_left_shift_parallelized, display_name: left_shift);
|
||||
|
||||
define_server_key_bench_default_fn!(method_name: add_parallelized, display_name: add);
|
||||
define_server_key_bench_default_fn!(method_name: sub_parallelized, display_name: sub);
|
||||
define_server_key_bench_default_fn!(method_name: mul_parallelized, display_name: mul);
|
||||
define_server_key_bench_default_fn!(method_name: div_parallelized, display_name: div);
|
||||
define_server_key_bench_default_fn!(method_name: rem_parallelized, display_name: modulo);
|
||||
define_server_key_bench_default_fn!(method_name: div_rem_parallelized, display_name: div_mod);
|
||||
define_server_key_bench_default_fn!(method_name: bitand_parallelized, display_name: bitand);
|
||||
define_server_key_bench_default_fn!(method_name: bitxor_parallelized, display_name: bitxor);
|
||||
define_server_key_bench_default_fn!(method_name: bitor_parallelized, display_name: bitor);
|
||||
@@ -671,7 +679,11 @@ define_server_key_bench_default_fn!(method_name: unchecked_bitand, display_name:
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_bitor, display_name: bitor);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_bitxor, display_name: bitxor);
|
||||
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_add_parallelized, display_name: add);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_mul_parallelized, display_name: mul);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_div_parallelized, display_name: div);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_rem_parallelized, display_name: modulo);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_div_rem_parallelized, display_name: div_mod);
|
||||
define_server_key_bench_default_fn!(
|
||||
method_name: unchecked_bitand_parallelized,
|
||||
display_name: bitand
|
||||
@@ -684,6 +696,38 @@ define_server_key_bench_default_fn!(
|
||||
method_name: unchecked_bitxor_parallelized,
|
||||
display_name: bitxor
|
||||
);
|
||||
define_server_key_bench_default_fn!(
|
||||
method_name: unchecked_rotate_right_parallelized,
|
||||
display_name: rotate_right
|
||||
);
|
||||
define_server_key_bench_default_fn!(
|
||||
method_name: unchecked_rotate_left_parallelized,
|
||||
display_name: rotate_left
|
||||
);
|
||||
define_server_key_bench_default_fn!(
|
||||
method_name: unchecked_right_shift_parallelized,
|
||||
display_name: right_shift
|
||||
);
|
||||
define_server_key_bench_default_fn!(
|
||||
method_name: unchecked_left_shift_parallelized,
|
||||
display_name: left_shift
|
||||
);
|
||||
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_bitand_parallelized,
|
||||
display_name: bitand,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_bitor_parallelized,
|
||||
display_name: bitor,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_bitxor_parallelized,
|
||||
display_name: bitxor,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_add,
|
||||
@@ -716,6 +760,46 @@ define_server_key_bench_scalar_fn!(
|
||||
display_name: mul,
|
||||
rng_func: mul_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_div_parallelized,
|
||||
display_name: div,
|
||||
rng_func: div_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_rem_parallelized,
|
||||
display_name: modulo,
|
||||
rng_func: div_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_div_rem_parallelized,
|
||||
display_name: div_mod,
|
||||
rng_func: div_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_bitand_parallelized,
|
||||
display_name: bitand,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_bitor_parallelized,
|
||||
display_name: bitor,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_bitxor_parallelized,
|
||||
display_name: bitxor,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_rotate_left_parallelized,
|
||||
display_name: rotate_left,
|
||||
rng_func: shift_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_rotate_right_parallelized,
|
||||
display_name: rotate_right,
|
||||
rng_func: shift_scalar
|
||||
);
|
||||
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: scalar_add_parallelized,
|
||||
@@ -742,6 +826,11 @@ define_server_key_bench_scalar_default_fn!(
|
||||
display_name: modulo,
|
||||
rng_func: div_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: scalar_div_rem_parallelized,
|
||||
display_name: div_mod,
|
||||
rng_func: div_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: scalar_left_shift_parallelized,
|
||||
display_name: left_shift,
|
||||
@@ -762,6 +851,22 @@ define_server_key_bench_scalar_default_fn!(
|
||||
display_name: rotate_right,
|
||||
rng_func: shift_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: scalar_bitand_parallelized,
|
||||
display_name: bitand,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: scalar_bitor_parallelized,
|
||||
display_name: bitor,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: scalar_bitxor_parallelized,
|
||||
display_name: bitxor,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: scalar_eq_parallelized,
|
||||
display_name: equal,
|
||||
@@ -803,6 +908,47 @@ define_server_key_bench_scalar_default_fn!(
|
||||
rng_func: default_scalar
|
||||
);
|
||||
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_eq_parallelized,
|
||||
display_name: equal,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_ne_parallelized,
|
||||
display_name: not_equal,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_le_parallelized,
|
||||
display_name: less_or_equal,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_lt_parallelized,
|
||||
display_name: less_than,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_ge_parallelized,
|
||||
display_name: greater_or_equal,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_gt_parallelized,
|
||||
display_name: greater_than,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_max_parallelized,
|
||||
display_name: max,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_fn!(
|
||||
method_name: smart_scalar_min_parallelized,
|
||||
display_name: min,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_add,
|
||||
display_name: add,
|
||||
@@ -818,10 +964,50 @@ define_server_key_bench_scalar_default_fn!(
|
||||
display_name: mul,
|
||||
rng_func: mul_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_div_parallelized,
|
||||
display_name: div,
|
||||
rng_func: div_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_rem_parallelized,
|
||||
display_name: modulo,
|
||||
rng_func: div_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_div_rem_parallelized,
|
||||
display_name: div_mod,
|
||||
rng_func: div_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_rotate_right_parallelized,
|
||||
display_name: rotate_right,
|
||||
rng_func: shift_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_rotate_left_parallelized,
|
||||
display_name: rotate_left,
|
||||
rng_func: shift_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_right_shift_parallelized,
|
||||
display_name: right_shift,
|
||||
rng_func: shift_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_left_shift_parallelized,
|
||||
display_name: left_shift,
|
||||
rng_func: shift_scalar
|
||||
);
|
||||
|
||||
define_server_key_bench_unary_fn!(method_name: smart_neg, display_name: negation);
|
||||
define_server_key_bench_unary_fn!(method_name: smart_neg_parallelized, display_name: negation);
|
||||
define_server_key_bench_unary_fn!(method_name: smart_abs_parallelized, display_name: abs);
|
||||
|
||||
define_server_key_bench_unary_default_fn!(method_name: neg_parallelized, display_name: negation);
|
||||
define_server_key_bench_unary_default_fn!(method_name: abs_parallelized, display_name: abs);
|
||||
|
||||
define_server_key_bench_unary_default_fn!(method_name: unchecked_abs_parallelized, display_name: abs);
|
||||
|
||||
define_server_key_bench_unary_fn!(method_name: full_propagate, display_name: carry_propagation);
|
||||
define_server_key_bench_unary_fn!(
|
||||
@@ -832,6 +1018,7 @@ define_server_key_bench_unary_fn!(
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_max, display_name: max);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_min, display_name: min);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_eq, display_name: equal);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_ne, display_name: not_equal);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_lt, display_name: less_than);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_le, display_name: less_or_equal);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_gt, display_name: greater_than);
|
||||
@@ -840,6 +1027,7 @@ define_server_key_bench_default_fn!(method_name: unchecked_ge, display_name: gre
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_max_parallelized, display_name: max);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_min_parallelized, display_name: min);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_eq_parallelized, display_name: equal);
|
||||
define_server_key_bench_default_fn!(method_name: unchecked_ne_parallelized, display_name: not_equal);
|
||||
define_server_key_bench_default_fn!(
|
||||
method_name: unchecked_lt_parallelized,
|
||||
display_name: less_than
|
||||
@@ -857,9 +1045,35 @@ define_server_key_bench_default_fn!(
|
||||
display_name: greater_or_equal
|
||||
);
|
||||
|
||||
define_server_key_bench_scalar_default_fn!(method_name: unchecked_scalar_max_parallelized, display_name: max,rng_func: default_scalar);
|
||||
define_server_key_bench_scalar_default_fn!(method_name: unchecked_scalar_min_parallelized, display_name: min,rng_func: default_scalar);
|
||||
define_server_key_bench_scalar_default_fn!(method_name: unchecked_scalar_eq_parallelized, display_name: equal,rng_func: default_scalar);
|
||||
define_server_key_bench_scalar_default_fn!(method_name: unchecked_scalar_ne_parallelized, display_name: not_equal,rng_func: default_scalar);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_lt_parallelized,
|
||||
display_name: less_than,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_le_parallelized,
|
||||
display_name: less_or_equal,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_gt_parallelized,
|
||||
display_name: greater_than,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
define_server_key_bench_scalar_default_fn!(
|
||||
method_name: unchecked_scalar_ge_parallelized,
|
||||
display_name: greater_or_equal,
|
||||
rng_func: default_scalar
|
||||
);
|
||||
|
||||
define_server_key_bench_fn!(method_name: smart_max, display_name: max);
|
||||
define_server_key_bench_fn!(method_name: smart_min, display_name: min);
|
||||
define_server_key_bench_fn!(method_name: smart_eq, display_name: equal);
|
||||
define_server_key_bench_fn!(method_name: smart_ne, display_name: not_equal);
|
||||
define_server_key_bench_fn!(method_name: smart_lt, display_name: less_than);
|
||||
define_server_key_bench_fn!(method_name: smart_le, display_name: less_or_equal);
|
||||
define_server_key_bench_fn!(method_name: smart_gt, display_name: greater_than);
|
||||
@@ -868,6 +1082,7 @@ define_server_key_bench_fn!(method_name: smart_ge, display_name: greater_or_equa
|
||||
define_server_key_bench_fn!(method_name: smart_max_parallelized, display_name: max);
|
||||
define_server_key_bench_fn!(method_name: smart_min_parallelized, display_name: min);
|
||||
define_server_key_bench_fn!(method_name: smart_eq_parallelized, display_name: equal);
|
||||
define_server_key_bench_fn!(method_name: smart_ne_parallelized, display_name: not_equal);
|
||||
define_server_key_bench_fn!(method_name: smart_lt_parallelized, display_name: less_than);
|
||||
define_server_key_bench_fn!(
|
||||
method_name: smart_le_parallelized,
|
||||
@@ -923,6 +1138,7 @@ criterion_group!(
|
||||
smart_max,
|
||||
smart_min,
|
||||
smart_eq,
|
||||
smart_ne,
|
||||
smart_lt,
|
||||
smart_le,
|
||||
smart_gt,
|
||||
@@ -931,12 +1147,21 @@ criterion_group!(
|
||||
|
||||
criterion_group!(
|
||||
smart_parallelized_ops,
|
||||
smart_neg_parallelized,
|
||||
smart_abs_parallelized,
|
||||
smart_add_parallelized,
|
||||
smart_sub_parallelized,
|
||||
smart_mul_parallelized,
|
||||
// smart_div_parallelized,
|
||||
// smart_rem_parallelized,
|
||||
smart_div_rem_parallelized, // For ciphertext div == rem == div_rem
|
||||
smart_bitand_parallelized,
|
||||
smart_bitor_parallelized,
|
||||
smart_bitxor_parallelized,
|
||||
smart_rotate_right_parallelized,
|
||||
smart_rotate_left_parallelized,
|
||||
smart_right_shift_parallelized,
|
||||
smart_left_shift_parallelized,
|
||||
);
|
||||
|
||||
criterion_group!(
|
||||
@@ -944,6 +1169,7 @@ criterion_group!(
|
||||
smart_max_parallelized,
|
||||
smart_min_parallelized,
|
||||
smart_eq_parallelized,
|
||||
smart_ne_parallelized,
|
||||
smart_lt_parallelized,
|
||||
smart_le_parallelized,
|
||||
smart_gt_parallelized,
|
||||
@@ -952,12 +1178,14 @@ criterion_group!(
|
||||
|
||||
criterion_group!(
|
||||
default_parallelized_ops,
|
||||
neg_parallelized,
|
||||
abs_parallelized,
|
||||
add_parallelized,
|
||||
sub_parallelized,
|
||||
mul_parallelized,
|
||||
div_parallelized,
|
||||
rem_parallelized,
|
||||
neg_parallelized,
|
||||
// div_parallelized,
|
||||
// rem_parallelized,
|
||||
div_rem_parallelized,
|
||||
bitand_parallelized,
|
||||
bitnot_parallelized,
|
||||
bitor_parallelized,
|
||||
@@ -993,6 +1221,26 @@ criterion_group!(
|
||||
smart_scalar_add_parallelized,
|
||||
smart_scalar_sub_parallelized,
|
||||
smart_scalar_mul_parallelized,
|
||||
smart_scalar_div_parallelized,
|
||||
smart_scalar_rem_parallelized, // For scalar rem == div_rem
|
||||
// smart_scalar_div_rem_parallelized,
|
||||
smart_scalar_bitand_parallelized,
|
||||
smart_scalar_bitor_parallelized,
|
||||
smart_scalar_bitxor_parallelized,
|
||||
smart_scalar_rotate_right_parallelized,
|
||||
smart_scalar_rotate_left_parallelized,
|
||||
);
|
||||
|
||||
criterion_group!(
|
||||
smart_scalar_parallelized_ops_comp,
|
||||
smart_scalar_max_parallelized,
|
||||
smart_scalar_min_parallelized,
|
||||
smart_scalar_eq_parallelized,
|
||||
smart_scalar_ne_parallelized,
|
||||
smart_scalar_lt_parallelized,
|
||||
smart_scalar_le_parallelized,
|
||||
smart_scalar_gt_parallelized,
|
||||
smart_scalar_ge_parallelized,
|
||||
);
|
||||
|
||||
criterion_group!(
|
||||
@@ -1002,10 +1250,14 @@ criterion_group!(
|
||||
scalar_mul_parallelized,
|
||||
scalar_div_parallelized,
|
||||
scalar_rem_parallelized,
|
||||
// scalar_div_rem_parallelized,
|
||||
scalar_left_shift_parallelized,
|
||||
scalar_right_shift_parallelized,
|
||||
scalar_rotate_left_parallelized,
|
||||
scalar_rotate_right_parallelized,
|
||||
scalar_bitand_parallelized,
|
||||
scalar_bitor_parallelized,
|
||||
scalar_bitxor_parallelized,
|
||||
);
|
||||
|
||||
criterion_group!(
|
||||
@@ -1030,11 +1282,40 @@ criterion_group!(
|
||||
unchecked_bitxor,
|
||||
);
|
||||
|
||||
criterion_group!(
|
||||
unchecked_parallelized_ops,
|
||||
unchecked_abs_parallelized,
|
||||
unchecked_add_parallelized,
|
||||
unchecked_mul_parallelized,
|
||||
// unchecked_div_parallelized,
|
||||
// unchecked_rem_parallelized,
|
||||
unchecked_div_rem_parallelized,
|
||||
unchecked_bitand_parallelized,
|
||||
unchecked_bitor_parallelized,
|
||||
unchecked_bitxor_parallelized,
|
||||
unchecked_rotate_right_parallelized,
|
||||
unchecked_rotate_left_parallelized,
|
||||
unchecked_right_shift_parallelized,
|
||||
unchecked_left_shift_parallelized,
|
||||
);
|
||||
|
||||
criterion_group!(
|
||||
unchecked_parallelized_ops_comp,
|
||||
unchecked_eq_parallelized,
|
||||
unchecked_ne_parallelized,
|
||||
unchecked_gt_parallelized,
|
||||
unchecked_ge_parallelized,
|
||||
unchecked_lt_parallelized,
|
||||
unchecked_max_parallelized,
|
||||
unchecked_min_parallelized,
|
||||
);
|
||||
|
||||
criterion_group!(
|
||||
unchecked_ops_comp,
|
||||
unchecked_max,
|
||||
unchecked_min,
|
||||
unchecked_eq,
|
||||
unchecked_ne,
|
||||
unchecked_lt,
|
||||
unchecked_le,
|
||||
unchecked_gt,
|
||||
@@ -1046,20 +1327,28 @@ criterion_group!(
|
||||
unchecked_scalar_add,
|
||||
unchecked_scalar_sub,
|
||||
unchecked_scalar_mul_parallelized,
|
||||
unchecked_bitand_parallelized,
|
||||
unchecked_bitor_parallelized,
|
||||
unchecked_bitxor_parallelized,
|
||||
unchecked_scalar_div_parallelized,
|
||||
unchecked_scalar_rem_parallelized,
|
||||
// unchecked_scalar_div_rem_parallelized,
|
||||
unchecked_scalar_bitand_parallelized,
|
||||
unchecked_scalar_bitor_parallelized,
|
||||
unchecked_scalar_bitxor_parallelized,
|
||||
unchecked_scalar_rotate_right_parallelized,
|
||||
unchecked_scalar_rotate_left_parallelized,
|
||||
unchecked_scalar_right_shift_parallelized,
|
||||
unchecked_scalar_left_shift_parallelized,
|
||||
);
|
||||
|
||||
criterion_group!(
|
||||
unchecked_scalar_ops_comp,
|
||||
unchecked_max_parallelized,
|
||||
unchecked_min_parallelized,
|
||||
unchecked_eq_parallelized,
|
||||
unchecked_lt_parallelized,
|
||||
unchecked_le_parallelized,
|
||||
unchecked_gt_parallelized,
|
||||
unchecked_ge_parallelized,
|
||||
unchecked_scalar_max_parallelized,
|
||||
unchecked_scalar_min_parallelized,
|
||||
unchecked_scalar_eq_parallelized,
|
||||
unchecked_scalar_ne_parallelized,
|
||||
unchecked_scalar_lt_parallelized,
|
||||
unchecked_scalar_le_parallelized,
|
||||
unchecked_scalar_gt_parallelized,
|
||||
unchecked_scalar_ge_parallelized,
|
||||
);
|
||||
|
||||
criterion_group!(misc, full_propagate, full_propagate_parallelized);
|
||||
@@ -1078,7 +1367,9 @@ fn main() {
|
||||
"smart_parallelized" => smart_parallelized_ops(),
|
||||
"smart_parallelized_comp" => smart_parallelized_ops_comp(),
|
||||
"smart_scalar_parallelized" => smart_scalar_parallelized_ops(),
|
||||
"smart_scalar_parallelized_comp" => smart_scalar_parallelized_ops_comp(),
|
||||
"unchecked" => unchecked_ops(),
|
||||
"unchecked_parallelized" => unchecked_parallelized_ops(),
|
||||
"unchecked_comp" => unchecked_ops_comp(),
|
||||
"unchecked_scalar" => unchecked_scalar_ops(),
|
||||
"unchecked_scalar_comp" => unchecked_scalar_ops_comp(),
|
||||
|
||||
1111
tfhe/benches/integer/signed_bench.rs
Normal file
1111
tfhe/benches/integer/signed_bench.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
#[cfg(feature = "__c_api")]
|
||||
#[cfg(all(feature = "__c_api", not(feature = "__force_skip_cbindgen")))]
|
||||
fn gen_c_api() {
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
@@ -32,14 +32,15 @@ fn gen_c_api() {
|
||||
}
|
||||
|
||||
extern crate cbindgen;
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
let crate_dir: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into();
|
||||
let package_name = env::var("CARGO_PKG_NAME").unwrap();
|
||||
let output_file = target_dir()
|
||||
.join(format!("{package_name}.h"))
|
||||
.display()
|
||||
.to_string();
|
||||
let output_file = target_dir().join(format!("{package_name}.h"));
|
||||
|
||||
let parse_expand_features_vec = vec![
|
||||
// Note that this list may not be complete, but as macro expansion is used mostly/only for
|
||||
// the C API and the HL API, this is fine, if the C API build fails or generates invalid
|
||||
// headers then you likely need to add other features that will be forwarded to Cargo
|
||||
// expand
|
||||
#[cfg(feature = "__c_api")]
|
||||
"__c_api",
|
||||
#[cfg(feature = "boolean-c-api")]
|
||||
@@ -63,8 +64,8 @@ fn gen_c_api() {
|
||||
};
|
||||
|
||||
cbindgen::Builder::new()
|
||||
.with_crate(crate_dir.clone())
|
||||
.with_config(cbindgen::Config::from_root_or_default(crate_dir))
|
||||
.with_crate(crate_dir.as_path())
|
||||
.with_config(cbindgen::Config::from_file(crate_dir.join("cbindgen.toml")).unwrap())
|
||||
.with_parse_expand(&parse_expand_vec)
|
||||
.with_parse_expand_features(&parse_expand_features_vec)
|
||||
.generate()
|
||||
@@ -73,6 +74,6 @@ fn gen_c_api() {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[cfg(feature = "__c_api")]
|
||||
#[cfg(all(feature = "__c_api", not(feature = "__force_skip_cbindgen")))]
|
||||
gen_c_api()
|
||||
}
|
||||
|
||||
@@ -37,4 +37,3 @@ foreach (testsourcefile ${TEST_CASES})
|
||||
# Enabled asserts even in release mode
|
||||
add_definitions(-UNDEBUG)
|
||||
endforeach (testsourcefile ${TEST_CASES})
|
||||
|
||||
|
||||
@@ -99,8 +99,7 @@ int main(void) {
|
||||
ConfigBuilder *builder;
|
||||
Config *config;
|
||||
|
||||
config_builder_all_disabled(&builder);
|
||||
config_builder_enable_default_integers_small(&builder);
|
||||
config_builder_default(&builder);
|
||||
config_builder_build(builder, &config);
|
||||
|
||||
ClientKey *client_key = NULL;
|
||||
|
||||
@@ -110,13 +110,140 @@ int uint256_public_key(const ClientKey *client_key, const PublicKey *public_key)
|
||||
return ok;
|
||||
}
|
||||
|
||||
int int256_client_key(const ClientKey *client_key) {
|
||||
int ok;
|
||||
FheInt256 *lhs = NULL;
|
||||
FheInt256 *rhs = NULL;
|
||||
FheInt256 *result = NULL;
|
||||
FheInt64 *cast_result = NULL;
|
||||
// This is +1
|
||||
I256 lhs_clear = {1, 0, 0, 0};
|
||||
// This is -1
|
||||
I256 rhs_clear = {UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX};
|
||||
I256 result_clear = {0};
|
||||
|
||||
ok = fhe_int256_try_encrypt_with_client_key_i256(lhs_clear, client_key, &lhs);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int256_try_encrypt_with_client_key_i256(rhs_clear, client_key, &rhs);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int256_add(lhs, rhs, &result);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int256_decrypt(result, client_key, &result_clear);
|
||||
assert(ok == 0);
|
||||
|
||||
// We did 1 + (-1), so we expect 0
|
||||
assert(result_clear.w0 == 0);
|
||||
assert(result_clear.w1 == 0);
|
||||
assert(result_clear.w2 == 0);
|
||||
assert(result_clear.w3 == 0);
|
||||
|
||||
fhe_int256_destroy(result);
|
||||
ok = fhe_int256_sub(lhs, rhs, &result);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int256_decrypt(result, client_key, &result_clear);
|
||||
assert(ok == 0);
|
||||
|
||||
// We did 1 - (-1), so we expect 2
|
||||
assert(result_clear.w0 == 2);
|
||||
assert(result_clear.w1 == 0);
|
||||
assert(result_clear.w2 == 0);
|
||||
assert(result_clear.w3 == 0);
|
||||
|
||||
// try some casting
|
||||
ok = fhe_int256_cast_into_fhe_int64(result, &cast_result);
|
||||
assert(ok == 0);
|
||||
int64_t u64_clear;
|
||||
ok = fhe_int64_decrypt(cast_result, client_key, &u64_clear);
|
||||
assert(ok == 0);
|
||||
assert(u64_clear == 2);
|
||||
|
||||
fhe_int256_destroy(lhs);
|
||||
fhe_int256_destroy(rhs);
|
||||
fhe_int256_destroy(result);
|
||||
fhe_int64_destroy(cast_result);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int int256_encrypt_trivial(const ClientKey *client_key) {
|
||||
int ok;
|
||||
FheInt256 *lhs = NULL;
|
||||
FheInt256 *rhs = NULL;
|
||||
FheInt256 *result = NULL;
|
||||
I256 lhs_clear = {1, 2, 3, 4};
|
||||
I256 rhs_clear = {5, 6, 7, 8};
|
||||
I256 result_clear = {0};
|
||||
|
||||
ok = fhe_int256_try_encrypt_trivial_i256(lhs_clear, &lhs);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int256_try_encrypt_trivial_i256(rhs_clear, &rhs);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int256_add(lhs, rhs, &result);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int256_decrypt(result, client_key, &result_clear);
|
||||
assert(ok == 0);
|
||||
|
||||
assert(result_clear.w0 == 6);
|
||||
assert(result_clear.w1 == 8);
|
||||
assert(result_clear.w2 == 10);
|
||||
assert(result_clear.w3 == 12);
|
||||
|
||||
fhe_int256_destroy(lhs);
|
||||
fhe_int256_destroy(rhs);
|
||||
fhe_int256_destroy(result);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
int int256_public_key(const ClientKey *client_key, const PublicKey *public_key) {
|
||||
int ok;
|
||||
FheInt256 *lhs = NULL;
|
||||
FheInt256 *rhs = NULL;
|
||||
FheInt256 *result = NULL;
|
||||
// This is +1
|
||||
I256 lhs_clear = {1, 0, 0, 0};
|
||||
// This is -1
|
||||
I256 rhs_clear = {UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX};
|
||||
I256 result_clear = {0};
|
||||
|
||||
ok = fhe_int256_try_encrypt_with_public_key_i256(lhs_clear, public_key, &lhs);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int256_try_encrypt_with_public_key_i256(rhs_clear, public_key, &rhs);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int256_sub(lhs, rhs, &result);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int256_decrypt(result, client_key, &result_clear);
|
||||
assert(ok == 0);
|
||||
|
||||
// We did 1 - (-1), so we expect 2
|
||||
assert(result_clear.w0 == 2);
|
||||
assert(result_clear.w1 == 0);
|
||||
assert(result_clear.w2 == 0);
|
||||
assert(result_clear.w3 == 0);
|
||||
|
||||
fhe_int256_destroy(lhs);
|
||||
fhe_int256_destroy(rhs);
|
||||
fhe_int256_destroy(result);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(void) {
|
||||
int ok = 0;
|
||||
ConfigBuilder *builder;
|
||||
Config *config;
|
||||
|
||||
config_builder_all_disabled(&builder);
|
||||
config_builder_enable_default_integers_small(&builder);
|
||||
config_builder_default(&builder);
|
||||
config_builder_build(builder, &config);
|
||||
|
||||
ClientKey *client_key = NULL;
|
||||
@@ -132,6 +259,10 @@ int main(void) {
|
||||
uint256_encrypt_trivial(client_key);
|
||||
uint256_public_key(client_key, public_key);
|
||||
|
||||
int256_client_key(client_key);
|
||||
int256_encrypt_trivial(client_key);
|
||||
int256_public_key(client_key, public_key);
|
||||
|
||||
client_key_destroy(client_key);
|
||||
public_key_destroy(public_key);
|
||||
server_key_destroy(server_key);
|
||||
|
||||
@@ -102,8 +102,7 @@ int main(void) {
|
||||
ConfigBuilder *builder;
|
||||
Config *config;
|
||||
|
||||
config_builder_all_disabled(&builder);
|
||||
config_builder_enable_default_bool(&builder);
|
||||
config_builder_default(&builder);
|
||||
config_builder_build(builder, &config);
|
||||
|
||||
ClientKey *client_key = NULL;
|
||||
|
||||
@@ -78,7 +78,7 @@ int uint256_encrypt_trivial(const ClientKey *client_key) {
|
||||
return ok;
|
||||
}
|
||||
|
||||
int uint256_public_key(const ClientKey *client_key,
|
||||
int uint256_compact_public_key(const ClientKey *client_key,
|
||||
const CompressedCompactPublicKey *compressed_public_key) {
|
||||
int ok;
|
||||
CompactPublicKey *public_key = NULL;
|
||||
@@ -112,7 +112,7 @@ int uint256_public_key(const ClientKey *client_key,
|
||||
lhs = expand_output[0];
|
||||
rhs = expand_output[1];
|
||||
// We can destroy the compact list
|
||||
// The expanded ciphertext are independant from it
|
||||
// The expanded ciphertext are independent from it
|
||||
compact_fhe_uint256_list_destroy(list);
|
||||
|
||||
ok = fhe_uint256_sub(lhs, rhs, &result);
|
||||
@@ -158,14 +158,88 @@ int uint256_public_key(const ClientKey *client_key,
|
||||
return ok;
|
||||
}
|
||||
|
||||
int int32_compact_public_key(const ClientKey *client_key,
|
||||
const CompressedCompactPublicKey *compressed_public_key) {
|
||||
int ok;
|
||||
CompactPublicKey *public_key = NULL;
|
||||
FheInt32 *lhs = NULL;
|
||||
FheInt32 *rhs = NULL;
|
||||
FheInt32 *result = NULL;
|
||||
CompactFheInt32List *list = NULL;
|
||||
|
||||
int32_t result_clear = 0;
|
||||
int32_t clears[2] = {-9482394, 98712234};
|
||||
|
||||
ok = compressed_compact_public_key_decompress(compressed_public_key, &public_key);
|
||||
assert(ok == 0);
|
||||
|
||||
// Compact list example
|
||||
{
|
||||
ok = compact_fhe_int32_list_try_encrypt_with_compact_public_key_i32(&clears[0], 2,
|
||||
public_key, &list);
|
||||
assert(ok == 0);
|
||||
|
||||
size_t len = 0;
|
||||
ok = compact_fhe_int32_list_len(list, &len);
|
||||
assert(ok == 0);
|
||||
assert(len == 2);
|
||||
|
||||
FheInt32 *expand_output[2] = {NULL};
|
||||
ok = compact_fhe_int32_list_expand(list, &expand_output[0], 2);
|
||||
assert(ok == 0);
|
||||
|
||||
// transfer ownership
|
||||
lhs = expand_output[0];
|
||||
rhs = expand_output[1];
|
||||
// We can destroy the compact list
|
||||
// The expanded ciphertext are independent from it
|
||||
compact_fhe_int32_list_destroy(list);
|
||||
|
||||
ok = fhe_int32_sub(lhs, rhs, &result);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int32_decrypt(result, client_key, &result_clear);
|
||||
assert(ok == 0);
|
||||
|
||||
assert(result_clear == clears[0] - clears[1]);
|
||||
|
||||
fhe_int32_destroy(lhs);
|
||||
fhe_int32_destroy(rhs);
|
||||
fhe_int32_destroy(result);
|
||||
}
|
||||
|
||||
{
|
||||
ok = fhe_int32_try_encrypt_with_compact_public_key_i32(clears[0], public_key, &lhs);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int32_try_encrypt_with_compact_public_key_i32(clears[1], public_key, &rhs);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int32_add(lhs, rhs, &result);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = fhe_int32_decrypt(result, client_key, &result_clear);
|
||||
assert(ok == 0);
|
||||
|
||||
assert(result_clear == clears[0] + clears[1]);
|
||||
|
||||
fhe_int32_destroy(lhs);
|
||||
fhe_int32_destroy(rhs);
|
||||
fhe_int32_destroy(result);
|
||||
}
|
||||
|
||||
compact_public_key_destroy(public_key);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int ok = 0;
|
||||
{
|
||||
ConfigBuilder *builder;
|
||||
Config *config;
|
||||
|
||||
config_builder_all_disabled(&builder);
|
||||
config_builder_enable_custom_integers(&builder,
|
||||
config_builder_default(&builder);
|
||||
config_builder_use_custom_parameters(&builder,
|
||||
SHORTINT_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS);
|
||||
config_builder_build(builder, &config);
|
||||
|
||||
@@ -180,7 +254,8 @@ int main(void) {
|
||||
|
||||
uint256_client_key(client_key);
|
||||
uint256_encrypt_trivial(client_key);
|
||||
uint256_public_key(client_key, compressed_public_key);
|
||||
uint256_compact_public_key(client_key, compressed_public_key);
|
||||
int32_compact_public_key(client_key, compressed_public_key);
|
||||
|
||||
client_key_destroy(client_key);
|
||||
compressed_compact_public_key_destroy(compressed_public_key);
|
||||
@@ -191,8 +266,8 @@ int main(void) {
|
||||
ConfigBuilder *builder;
|
||||
Config *config;
|
||||
|
||||
config_builder_all_disabled(&builder);
|
||||
config_builder_enable_custom_integers(&builder,
|
||||
config_builder_default(&builder);
|
||||
config_builder_use_custom_parameters(&builder,
|
||||
SHORTINT_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS);
|
||||
config_builder_build(builder, &config);
|
||||
|
||||
@@ -207,7 +282,8 @@ int main(void) {
|
||||
|
||||
uint256_client_key(client_key);
|
||||
uint256_encrypt_trivial(client_key);
|
||||
uint256_public_key(client_key, compressed_public_key);
|
||||
uint256_compact_public_key(client_key, compressed_public_key);
|
||||
int32_compact_public_key(client_key, compressed_public_key);
|
||||
|
||||
client_key_destroy(client_key);
|
||||
compressed_compact_public_key_destroy(compressed_public_key);
|
||||
|
||||
@@ -64,6 +64,67 @@ int uint8_public_key(const ClientKey *client_key, const PublicKey *public_key) {
|
||||
return ok;
|
||||
}
|
||||
|
||||
int uint8_safe_serialization(const ClientKey *client_key, const ServerKey *server_key) {
|
||||
int ok;
|
||||
CompactFheUint8 *lhs = NULL;
|
||||
CompactFheUint8 *deserialized_lhs = NULL;
|
||||
CompactFheUint8 *result = NULL;
|
||||
Buffer value_buffer = {.pointer = NULL, .length = 0};
|
||||
Buffer cks_buffer = {.pointer = NULL, .length = 0};
|
||||
BufferView deser_view = {.pointer = NULL, .length = 0};
|
||||
ClientKey *deserialized_client_key = NULL;
|
||||
|
||||
const uint64_t max_serialization_size = UINT64_C(1) << UINT64_C(20);
|
||||
|
||||
uint8_t lhs_clear = 123;
|
||||
|
||||
ok = client_key_serialize(client_key, &cks_buffer);
|
||||
assert(ok == 0);
|
||||
|
||||
deser_view.pointer = cks_buffer.pointer;
|
||||
deser_view.length = cks_buffer.length;
|
||||
ok = client_key_deserialize(deser_view, &deserialized_client_key);
|
||||
assert(ok == 0);
|
||||
|
||||
struct CompactPublicKey *public_key;
|
||||
|
||||
ok = compact_public_key_new(deserialized_client_key, &public_key);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = compact_fhe_uint8_try_encrypt_with_compact_public_key_u8(lhs_clear, public_key, &lhs);
|
||||
assert(ok == 0);
|
||||
|
||||
ok = compact_fhe_uint8_safe_serialize(lhs, &value_buffer, max_serialization_size);
|
||||
assert(ok == 0);
|
||||
|
||||
deser_view.pointer = value_buffer.pointer;
|
||||
deser_view.length = value_buffer.length;
|
||||
ok = compact_fhe_uint8_safe_deserialize_conformant(deser_view, max_serialization_size, server_key,
|
||||
&deserialized_lhs);
|
||||
assert(ok == 0);
|
||||
|
||||
FheUint8 *expanded = NULL;
|
||||
|
||||
ok = compact_fhe_uint8_expand(deserialized_lhs, &expanded);
|
||||
assert(ok == 0);
|
||||
|
||||
uint8_t clear;
|
||||
ok = fhe_uint8_decrypt(expanded, deserialized_client_key, &clear);
|
||||
assert(ok == 0);
|
||||
|
||||
assert(clear == lhs_clear);
|
||||
|
||||
if (value_buffer.pointer != NULL) {
|
||||
destroy_buffer(&value_buffer);
|
||||
}
|
||||
compact_fhe_uint8_destroy(lhs);
|
||||
compact_fhe_uint8_destroy(deserialized_lhs);
|
||||
compact_fhe_uint8_destroy(result);
|
||||
fhe_uint8_destroy(expanded);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
int uint8_serialization(const ClientKey *client_key) {
|
||||
int ok;
|
||||
FheUint8 *lhs = NULL;
|
||||
@@ -142,9 +203,7 @@ int main(void) {
|
||||
ConfigBuilder *builder;
|
||||
Config *config;
|
||||
|
||||
ok = config_builder_all_disabled(&builder);
|
||||
assert(ok == 0);
|
||||
ok = config_builder_enable_default_integers(&builder);
|
||||
ok = config_builder_default(&builder);
|
||||
assert(ok == 0);
|
||||
ok = config_builder_build(builder, &config);
|
||||
assert(ok == 0);
|
||||
@@ -159,6 +218,8 @@ int main(void) {
|
||||
assert(ok == 0);
|
||||
ok = uint8_serialization(client_key);
|
||||
assert(ok == 0);
|
||||
ok = uint8_safe_serialization(client_key, server_key);
|
||||
assert(ok == 0);
|
||||
ok = uint8_compressed(client_key);
|
||||
assert(ok == 0);
|
||||
|
||||
@@ -179,9 +240,7 @@ int main(void) {
|
||||
ConfigBuilder *builder;
|
||||
Config *config;
|
||||
|
||||
ok = config_builder_all_disabled(&builder);
|
||||
assert(ok == 0);
|
||||
ok = config_builder_enable_default_integers_small(&builder);
|
||||
ok = config_builder_default_with_small_encryption(&builder);
|
||||
assert(ok == 0);
|
||||
ok = config_builder_build(builder, &config);
|
||||
assert(ok == 0);
|
||||
|
||||
@@ -114,14 +114,15 @@ bitflags = false
|
||||
############## Options for How Your Rust library Should Be Parsed ##############
|
||||
|
||||
[parse]
|
||||
parse_deps = true
|
||||
include = ["tfhe"]
|
||||
parse_deps = false
|
||||
include = []
|
||||
exclude = []
|
||||
clean = false
|
||||
extra_bindings = []
|
||||
|
||||
|
||||
[parse.expand]
|
||||
# Managed by build.rs to programmatically select features when required
|
||||
crates = []
|
||||
all_features = false
|
||||
default_features = true
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
## Getting Started
|
||||
* [Installation](getting_started/installation.md)
|
||||
* [Quick Start](getting_started/quick_start.md)
|
||||
* [Operations](getting_started/operations.md)
|
||||
* [Types & Operations](getting_started/operations.md)
|
||||
* [Benchmarks](getting_started/benchmarks.md)
|
||||
* [Security and Cryptography](getting_started/security_and_cryptography.md)
|
||||
|
||||
@@ -56,4 +56,3 @@
|
||||
|
||||
## API references
|
||||
* [docs.rs](https://docs.rs/tfhe/)
|
||||
|
||||
|
||||
@@ -504,7 +504,7 @@ Pattern | Description
|
||||
`/^abc$/` | Matches with content that equals exactly `abc` (case sensitive)
|
||||
`/^abc$/i` | Matches with content that equals `abc` (case insensitive)
|
||||
`/abc/` | Matches with content that contains somewhere `abc`
|
||||
`/ab?c/` | Matches with content that contains somewhere `abc` or somwhere `ab`
|
||||
`/ab?c/` | Matches with content that contains somewhere `abc` or somewhere `ab`
|
||||
`/^ab*c$/` | For example, matches with: `ac`, `abc`, `abbbbc`
|
||||
`/^[a-c]b\|cd$/` | Matches with: `ab`, `bb`, `cb`, `cd`
|
||||
`/^[a-c]b\|cd$/i` | Matches with: `ab`, `Ab`, `aB`, ..., `cD`, `CD`
|
||||
|
||||
@@ -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 = "0.4.0", features = [ "x86_64-unix" ] }
|
||||
tfhe = { version = "0.5.0", features = [ "x86_64-unix" ] }
|
||||
```
|
||||
|
||||
This enables the `x86_64-unix` feature to have efficient implementations of various algorithms for `x86_64` CPUs on a Unix-like system. The 'unix' suffix indicates that the `UnixSeeder`, which uses `/dev/random` to generate random numbers, is activated as a fallback if no hardware number generator is available (like `rdseed` on `x86_64` or if the [`Randomization Services`](https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc) on Apple platforms are not available). To avoid having the `UnixSeeder` as a potential fallback or to run on non-Unix systems (e.g., Windows), the `x86_64` feature is sufficient.
|
||||
@@ -19,19 +19,19 @@ For Apple Silicon, the `aarch64-unix` or `aarch64` feature should be enabled. `a
|
||||
In short: For `x86_64`-based machines running Unix-like OSes:
|
||||
|
||||
```toml
|
||||
tfhe = { version = "0.4.0", features = ["x86_64-unix"] }
|
||||
tfhe = { version = "0.5.0", features = ["x86_64-unix"] }
|
||||
```
|
||||
|
||||
For Apple Silicon or aarch64-based machines running Unix-like OSes:
|
||||
|
||||
```toml
|
||||
tfhe = { version = "0.4.0", features = ["aarch64-unix"] }
|
||||
tfhe = { version = "0.5.0", features = ["aarch64-unix"] }
|
||||
```
|
||||
|
||||
For `x86_64`-based machines with the [`rdseed instruction`](https://en.wikipedia.org/wiki/RDRAND) running Windows:
|
||||
|
||||
```toml
|
||||
tfhe = { version = "0.4.0", features = ["x86_64"] }
|
||||
tfhe = { version = "0.5.0", features = ["x86_64"] }
|
||||
```
|
||||
|
||||
### Commented code to double a 2-bit message in a leveled fashion and using a PBS with the `core_crypto` module.
|
||||
@@ -249,7 +249,7 @@ pub fn main() {
|
||||
println!("Checking result...");
|
||||
assert_eq!(6, pbs_multiplication_result);
|
||||
println!(
|
||||
"Mulitplication via PBS result is correct! Expected 6, got {pbs_multiplication_result}"
|
||||
"Multiplication via PBS result is correct! Expected 6, got {pbs_multiplication_result}"
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -35,7 +35,7 @@ fn main() {
|
||||
Note that both the `client_key` and `server_key` implement the `Serialize` and `Deserialize` traits. This way you can use any compatible serializer to store/send the data. To store the `server_key` in a binary file, you can use the `bincode` library:
|
||||
|
||||
```rust
|
||||
use std::fs::File;
|
||||
use std::fs::{File, create_dir_all};
|
||||
use std::io::{Write, Read};
|
||||
use tfhe::boolean::prelude::*;
|
||||
|
||||
@@ -49,7 +49,13 @@ fn main() {
|
||||
// We serialize the server key to bytes, and store them in a file:
|
||||
let encoded: Vec<u8> = bincode::serialize(&server_key).unwrap();
|
||||
|
||||
let server_key_file = "/tmp/tutorial_server_key.bin";
|
||||
// Create a tmp dir with the current user name to avoid cluttering the /tmp dir
|
||||
let user = std::env::var("USER").unwrap_or_else(|_| "unknown_user".to_string());
|
||||
let tmp_dir_for_user = &format!("/tmp/{user}");
|
||||
|
||||
create_dir_all(tmp_dir_for_user).unwrap();
|
||||
|
||||
let server_key_file = &format!("{tmp_dir_for_user}/tutorial_server_key.bin");
|
||||
|
||||
// We write the server key to a file:
|
||||
let mut file = File::create(server_key_file)
|
||||
|
||||
@@ -8,7 +8,7 @@ Here is an example using the `bincode` serialization library, which serializes t
|
||||
binary format:
|
||||
|
||||
```rust
|
||||
use std::fs::File;
|
||||
use std::fs::{File, create_dir_all};
|
||||
use std::io::{Write, Read};
|
||||
use tfhe::boolean::prelude::*;
|
||||
|
||||
@@ -20,8 +20,14 @@ fn main() {
|
||||
let encoded_server_key: Vec<u8> = bincode::serialize(&server_key).unwrap();
|
||||
let encoded_client_key: Vec<u8> = bincode::serialize(&client_key).unwrap();
|
||||
|
||||
let server_key_file = "/tmp/ser_example_server_key.bin";
|
||||
let client_key_file = "/tmp/ser_example_client_key.bin";
|
||||
// Create a tmp dir with the current user name to avoid cluttering the /tmp dir
|
||||
let user = std::env::var("USER").unwrap_or_else(|_| "unknown_user".to_string());
|
||||
let tmp_dir_for_user = &format!("/tmp/{user}");
|
||||
|
||||
create_dir_all(tmp_dir_for_user).unwrap();
|
||||
|
||||
let server_key_file = &format!("{tmp_dir_for_user}/ser_example_server_key.bin");
|
||||
let client_key_file = &format!("{tmp_dir_for_user}/ser_example_client_key.bin");
|
||||
|
||||
// We write the keys to files:
|
||||
let mut file = File::create(server_key_file)
|
||||
|
||||
@@ -17,7 +17,7 @@ This crate implements two ways to represent an integer:
|
||||
|
||||
The first possibility to represent a large integer is to use a Radix-based decomposition on the plaintexts. Let $$B \in \mathbb{N}$$ be a basis such that the size of $$B$$ is smaller than (or equal to) 4 bits. Then, an integer $$m \in \mathbb{N}$$ can be written as $$m = m_0 + m_1*B + m_2*B^2 + ...$$, where each $$m_i$$ is strictly smaller than $$B$$. Each $$m_i$$ is then independently encrypted. In the end, an Integer ciphertext is defined as a set of shortint ciphertexts.
|
||||
|
||||
The definition of an integer requires a basis and a number of blocks. This is done at key generation. Below, the keys are dedicated to unsigned integers encrypting messages over 8 bits, using a basis over 2 bits (i.e., $$B=2^2$$) and 4 blocks.
|
||||
The definition of an integer requires a basis and a number of blocks. These parameters are chosen at key generation. Below, the keys are dedicated to integers encrypting messages over 8 bits, using a basis over 2 bits (i.e., $$B=2^2$$) and 4 blocks.
|
||||
|
||||
```rust
|
||||
use tfhe::integer::gen_keys_radix;
|
||||
@@ -93,6 +93,10 @@ Each operation may come in different 'flavors':
|
||||
|
||||
Not all operations have these 4 flavors, as some of them are implemented in a way that the operation is always possible without ever exceeding the plaintext space capacity.
|
||||
|
||||
{% hint style="info" %}
|
||||
If you don't know which flavor to use, you should use the `default` one.
|
||||
{% endhint %}
|
||||
|
||||
## How to use each operation type
|
||||
|
||||
Let's try to do a circuit evaluation using the different flavors of already introduced operations. For a very small circuit, the `unchecked` flavor may be enough to do the computation correctly. Otherwise, `checked` and `smart` are the best options.
|
||||
@@ -162,12 +166,15 @@ fn main() {
|
||||
assert!(result.is_ok());
|
||||
|
||||
let result = server_key.checked_sub_assign(&mut ct_1, &ct_2);
|
||||
assert!(result.is_ok());
|
||||
|
||||
let result = server_key.checked_add_assign(&mut ct_1, &ct_3);
|
||||
assert!(result.is_err());
|
||||
|
||||
// We use the client key to decrypt the output of the circuit:
|
||||
// Only the scalar multiplication could be done
|
||||
let output: u64 = client_key.decrypt(&ct_1);
|
||||
assert_eq!(output, (msg1 * scalar) % modulus as u64);
|
||||
assert_eq!(output, ((msg1 * scalar) - msg2) % modulus as u64);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -208,6 +215,14 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
{% hint style="warning" %}
|
||||
You must avoid cloning the inputs when calling `smart` operations to preserve performance. For instance, you SHOULD NOT have these kind of patterns in the code:
|
||||
```Rust
|
||||
sks.smart_add(&mut a.clone(), &mut b.clone());
|
||||
```
|
||||
{% endhint %}
|
||||
|
||||
|
||||
The main advantage of the default flavor is to ensure predictable timings, as long as only this kind of operation is used. Only the parallelized version of the operations is provided.
|
||||
|
||||
{% hint style="warning" %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Tutorial
|
||||
|
||||
`tfhe::integer` is dedicated to unsigned integers smaller than 256 bits. The steps to homomorphically evaluate an integer circuit are described here.
|
||||
`tfhe::integer` is dedicated to integers smaller than 256 bits. The steps to homomorphically evaluate an integer circuit are described here.
|
||||
|
||||
## Key Types
|
||||
|
||||
@@ -25,7 +25,7 @@ To generate the keys, a user needs two parameters:
|
||||
* A set of `shortint` cryptographic parameters.
|
||||
* The number of ciphertexts used to encrypt an integer (we call them "shortint blocks").
|
||||
|
||||
We are now going to build a pair of keys that can encrypt an **8-bit** integer by using **4** shortint blocks that store **2** bits of message each.
|
||||
We are now going to build a pair of keys that can encrypt **8-bit** integers (signed or unsigned) by using **4** shortint blocks that store **2** bits of message each.
|
||||
|
||||
```rust
|
||||
use tfhe::integer::gen_keys_radix;
|
||||
|
||||
@@ -40,8 +40,7 @@ use tfhe::{ConfigBuilder, generate_keys, set_server_key, FheUint8};
|
||||
use tfhe::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
let config = ConfigBuilder::default()
|
||||
.build();
|
||||
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
@@ -141,7 +140,7 @@ use tfhe::integer::gen_keys_radix;
|
||||
use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
|
||||
|
||||
fn main() {
|
||||
// We create keys for radix represention to create 16 bits integers
|
||||
// We create keys for radix representation to create 16 bits integers
|
||||
// using 8 blocks of 2 bits
|
||||
let (cks, sks) = gen_keys_radix(PARAM_MESSAGE_2_CARRY_2, 8);
|
||||
|
||||
|
||||
@@ -37,8 +37,14 @@ Each operation may come in different 'flavors':
|
||||
|
||||
Not all operations have these 4 flavors, as some of them are implemented in a way that the operation is always possible without ever exceeding the plaintext space capacity.
|
||||
|
||||
{% hint style="info" %}
|
||||
If you don't know which flavor to use, you should use the `default` one.
|
||||
{% endhint %}
|
||||
|
||||
|
||||
## How to use operation types
|
||||
|
||||
|
||||
Let's try to do a circuit evaluation using the different flavors of operations that we have already introduced. For a very small circuit, the `unchecked` flavour may be enough to do the computation correctly. Otherwise,`checked` and `smart` are the best options.
|
||||
|
||||
Let's do a scalar multiplication, a subtraction, and a multiplication.
|
||||
@@ -367,14 +373,14 @@ fn main() {
|
||||
let modulus = client_key.parameters.message_modulus().0 as u64;
|
||||
|
||||
// We use the private client key to encrypt two messages:
|
||||
let ct_1 = client_key.encrypt(msg1);
|
||||
let mut ct_1 = client_key.encrypt(msg1);
|
||||
let mut ct_2 = client_key.encrypt(msg2);
|
||||
|
||||
// Compute the lookup table for the bivariate functions
|
||||
let acc = server_key.generate_lookup_table_bivariate(|x,y| (x.count_ones()
|
||||
+ y.count_ones()) as u64 % modulus );
|
||||
|
||||
let ct_res = server_key.smart_apply_lookup_table_bivariate(&ct_1, &mut ct_2, &acc);
|
||||
let ct_res = server_key.smart_apply_lookup_table_bivariate(&mut ct_1, &mut ct_2, &acc);
|
||||
|
||||
// We use the client key to decrypt the output of the circuit:
|
||||
let output = client_key.decrypt(&ct_res);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Tutorial
|
||||
|
||||
`tfhe::shortint` is dedicated to small unsigned integers smaller than 8 bits. The steps to homomorphically evaluate a circuit are described below.
|
||||
`tfhe::shortint` is dedicated to unsigned integers smaller than 8 bits. The steps to homomorphically evaluate a circuit are described below.
|
||||
|
||||
## Key generation
|
||||
|
||||
|
||||
@@ -1,101 +1,106 @@
|
||||
# Benchmarks
|
||||
|
||||
Due to their nature, homomorphic operations are naturally slower than their clear equivalent. Some timings are exposed for basic operations. For completeness, benchmarks for other libraries are also given.
|
||||
Due to their nature, homomorphic operations are naturally slower than their cleartext equivalents. Some timings are exposed for basic operations. For completeness, benchmarks for other libraries are also given.
|
||||
|
||||
{% hint style="info" %}
|
||||
All benchmarks were launched on an AWS m6i.metal with the following specifications: Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz and 512GB of RAM.
|
||||
{% endhint %}
|
||||
|
||||
## Integer
|
||||
|
||||
This measures the execution time for some operation sets of tfhe-rs::integer (the unsigned version). Note that the timings for `FheInt` (i.e., the signed integers) are similar.
|
||||
|
||||
| Operation \ Size | `FheUint8` | `FheUint16` | `FheUint32` | `FheUint64` | `FheUint128` | `FheUint256` |
|
||||
|--------------------------------------------------------|------------|-------------|-------------|-------------|--------------|--------------|
|
||||
| Negation (`-`) | 70.9 ms | 99.3 ms | 129 ms | 180 ms | 239 ms | 333 ms |
|
||||
| Add / Sub (`+`,`-`) | 70.5 ms | 100 ms | 132 ms | 186 ms | 249 ms | 334 ms |
|
||||
| Mul (`x`) | 144 ms | 216 ms | 333 ms | 832 ms | 2.50 s | 8.85 s |
|
||||
| Equal / Not Equal (`eq`, `ne`) | 36.1 ms | 36.5 ms | 57.4 ms | 64.2 ms | 67.3 ms | 78.1 ms |
|
||||
| Comparisons (`ge`, `gt`, `le`, `lt`) | 52.6 ms | 73.1 ms | 98.8 ms | 124 ms | 165 ms | 201 ms |
|
||||
| Max / Min (`max`,`min`) | 76.2 ms | 102 ms | 135 ms | 171 ms | 212 ms | 301 ms |
|
||||
| Bitwise operations (`&`, `\|`, `^`) | 19.4 ms | 20.3 ms | 21.0 ms | 27.2 ms | 31.6 ms | 40.2 ms |
|
||||
| Div / Rem (`/`, `%`) | 729 ms | 1.93 s | 4.81 s | 12.2 s | 30.7 s | 89.6 s |
|
||||
| Left / Right Shifts (`<<`, `>>`) | 99.4 ms | 129 ms | 180 ms | 243 ms | 372 ms | 762 ms |
|
||||
| Left / Right Rotations (`left_rotate`, `right_rotate`) | 103 ms | 128 ms | 182 ms | 241 ms | 374 ms | 763 ms |
|
||||
|
||||
|
||||
All timings are related to parallelized Radix-based integer operations, where each block is encrypted using the default parameters (i.e., PARAM\_MESSAGE\_2\_CARRY\_2\_KS\_PBS, more information about parameters can be found [here](../fine_grained_api/shortint/parameters.md)).
|
||||
To ensure predictable timings, the operation flavor is the `default` one: the carry is propagated if needed. The operation costs may be reduced by using `unchecked`, `checked`, or `smart`.
|
||||
|
||||
|
||||
## Shortint
|
||||
|
||||
This measures the execution time for some operations using various parameter sets of tfhe-rs::shortint. Except for `unchecked_add`, all timings are related to the `default` operations. This flavor ensures predictable timings for an operation along the entire circuit by clearing the carry space after each operation.
|
||||
|
||||
This uses the Concrete FFT + AVX-512 configuration.
|
||||
|
||||
| Parameter set | PARAM\_MESSAGE\_1\_CARRY\_1 | PARAM\_MESSAGE\_2\_CARRY\_2 | PARAM\_MESSAGE\_3\_CARRY\_3 | PARAM\_MESSAGE\_4\_CARRY\_4 |
|
||||
|------------------------------------|-----------------------------|-----------------------------|-----------------------------|-----------------------------|
|
||||
| unchecked\_add | 348 ns | 413 ns | 2.95 µs | 12.1 µs |
|
||||
| add | 7.59 ms | 17.0 ms | 121 ms | 835 ms |
|
||||
| mul\_lsb | 8.13 ms | 16.8 ms | 121 ms | 827 ms |
|
||||
| keyswitch\_programmable\_bootstrap | 7.28 ms | 16.6 ms | 121 ms | 811 ms |
|
||||
|
||||
|
||||
## Boolean
|
||||
|
||||
This measures the execution time of a single binary Boolean gate.
|
||||
|
||||
### tfhe-rs::boolean.
|
||||
|
||||
| Parameter set | Concrete FFT | Concrete FFT + AVX-512 |
|
||||
| --------------------- | ------------ | ---------------------- |
|
||||
| DEFAULT\_PARAMETERS | 8.8ms | 6.8ms |
|
||||
| TFHE\_LIB\_PARAMETERS | 13.6ms | 10.9ms |
|
||||
| Parameter set | Concrete FFT + AVX-512 |
|
||||
|------------------------------------------------------|------------------------|
|
||||
| DEFAULT\_PARAMETERS\_KS\_PBS | 9.19 ms |
|
||||
| PARAMETERS\_ERROR\_PROB\_2\_POW\_MINUS\_165\_KS\_PBS | 14.1 ms |
|
||||
| TFHE\_LIB\_PARAMETERS | 10.0 ms |
|
||||
|
||||
|
||||
### tfhe-lib.
|
||||
|
||||
| Parameter set | fftw | spqlios-fma |
|
||||
| ------------------------------------------------ | ------ | ----------- |
|
||||
| default\_128bit\_gate\_bootstrapping\_parameters | 28.9ms | 15.7ms |
|
||||
Using the same m6i.metal machine as the one for tfhe-rs, the timings are:
|
||||
|
||||
### OpenFHE.
|
||||
| Parameter set | spqlios-fma |
|
||||
|--------------------------------------------------|-------------|
|
||||
| default\_128bit\_gate\_bootstrapping\_parameters | 15.4 ms |
|
||||
|
||||
| Parameter set | GINX | GINX (Intel HEXL) |
|
||||
| ------------- | ----- | ----------------- |
|
||||
| STD\_128 | 172ms | 78ms |
|
||||
| MEDIUM | 113ms | 50.2ms |
|
||||
### OpenFHE (v1.1.1).
|
||||
|
||||
Following the official instructions from OpenFHE, `clang14` and the following command are used to setup the project:
|
||||
`cmake -DNATIVE_SIZE=32 -DWITH_NATIVEOPT=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DWITH_OPENMP=OFF ..`
|
||||
|
||||
To use the HEXL library, the configuration used is as follows:
|
||||
```bash
|
||||
export CXX=clang++
|
||||
export CC=clang
|
||||
|
||||
scripts/configure.sh
|
||||
Release -> y
|
||||
hexl -> y
|
||||
|
||||
scripts/build-openfhe-development-hexl.sh
|
||||
```
|
||||
|
||||
Using the same m6i.metal machine as the one for tfhe-rs, the timings are:
|
||||
|
||||
| Parameter set | GINX | GINX w/ Intel HEXL |
|
||||
|----------------------------------|---------|--------------------|
|
||||
| FHEW\_BINGATE/STD128\_OR | 40.2 ms | 31.0 ms |
|
||||
| FHEW\_BINGATE/STD128\_LMKCDEY_OR | 38.6 ms | 28.4 ms |
|
||||
|
||||
|
||||
## Integer
|
||||
This measures the execution time for some operation sets of tfhe-rs::integer.
|
||||
## How to reproduce TFHE-rs benchmarks
|
||||
|
||||
| Operation \ Size | `FheUint8` | `FheUint16` | `FheUint32` | ` FheUint64` | `FheUint128` | `FheUint256` |
|
||||
|--------------------------------------------------------|------------|-------------|-------------|--------------|--------------|--------------|
|
||||
| Negation (`-`) | 80.4 ms | 106 ms | 132 ms | 193 ms | 257 ms | 348 ms |
|
||||
| Add / Sub (`+`,`-`) | 81.5 ms | 110 ms | 139 ms | 200 ms | 262 ms | 355 ms |
|
||||
| Mul (`x`) | 150 ms | 221 ms | 361 ms | 928 ms | 2.90 s | 10.97 s |
|
||||
| Equal / Not Equal (`eq`, `ne`) | 39.4 ms | 40.2 ms | 61.1 ms | 66.4 ms | 74.5 ms | 85.7 ms |
|
||||
| Comparisons (`ge`, `gt`, `le`, `lt`) | 57.5 ms | 79.6 ms | 105 ms | 136 ms | 174 ms | 219 ms |
|
||||
| Max / Min (`max`,`min`) | 100 ms | 130 ms | 163 ms | 204 ms | 245 ms | 338 ms |
|
||||
| Bitwise operations (`&`, `|`, `^`) | 20.7 ms | 21.1 ms | 22.6 ms | 30.2 ms | 34.1 ms | 42.1 ms |
|
||||
| Div / Rem (`/`, `%`) | 1.37 s | 3.50 s | 9.12 s | 23.9 s | 59.9 s | 149.2 s |
|
||||
| Left / Right Shifts (`<<`, `>>`) | 106 ms | 140 ms | 202 ms | 262 ms | 403 ms | 827 ms |
|
||||
| Left / Right Rotations (`left_rotate`, `right_rotate`) | 105 ms | 140 ms | 199 ms | 263 ms | 403 ms | 829 ms |
|
||||
|
||||
|
||||
|
||||
All timings are related to parallelized Radix-based integer operations, where each block is encrypted using the default parameters (i.e., PARAM\_MESSAGE\_2\_CARRY\_2, more information about parameters can be found [here](../fine_grained_api/shortint/parameters.md)).
|
||||
To ensure predictable timings, the operation flavor is the `default` one: the carry is propagated if needed. The operation costs could be reduced by using `unchecked`, `checked`, or `smart`.
|
||||
|
||||
|
||||
## Shortint
|
||||
This measures the execution time for some operations using various parameter sets of tfhe-rs::shortint.
|
||||
|
||||
This uses the Concrete FFT + AVX-512 configuration.
|
||||
|
||||
| Parameter set | unchecked\_add | unchecked\_mul\_lsb | keyswitch\_programmable\_bootstrap |
|
||||
|-----------------------------|----------------|---------------------|------------------------------------|
|
||||
| PARAM\_MESSAGE\_1\_CARRY\_1 | 338 ns | 8.3 ms | 8.1 ms |
|
||||
| PARAM\_MESSAGE\_2\_CARRY\_2 | 406 ns | 18.4 ms | 18.4 ms |
|
||||
| PARAM\_MESSAGE\_3\_CARRY\_3 | 3.06 µs | 134 ms | 129.4 ms |
|
||||
| PARAM\_MESSAGE\_4\_CARRY\_4 | 11.7 µs | 854 ms | 828.1 ms |
|
||||
|
||||
Next, the timings for the operation flavor `default` are given. This flavor ensures predictable timings of an operation along the entire circuit by clearing the carry space after each operation.
|
||||
|
||||
| Parameter set | add | mul\_lsb | keyswitch\_programmable\_bootstrap |
|
||||
| --------------------------- | -------------- | ------------------- | ---------------------------------- |
|
||||
| PARAM\_MESSAGE\_1\_CARRY\_1 | 7.90 ms | 8.00 ms | 8.10 ms |
|
||||
| PARAM\_MESSAGE\_2\_CARRY\_2 | 18.4 ms | 18.1 ms | 18.4 ms |
|
||||
| PARAM\_MESSAGE\_3\_CARRY\_3 | 131.5 ms | 129.5 ms | 129.4 ms |
|
||||
| PARAM\_MESSAGE\_4\_CARRY\_4 | 852.5 ms | 839.7 ms | 828.1 ms |
|
||||
|
||||
## How to reproduce benchmarks
|
||||
|
||||
TFHE-rs benchmarks can easily be reproduced from the [sources](https://github.com/zama-ai/tfhe-rs).
|
||||
TFHE-rs benchmarks can be easily reproduced from [source](https://github.com/zama-ai/tfhe-rs).
|
||||
|
||||
```shell
|
||||
#Boolean benchmarks:
|
||||
make bench_boolean
|
||||
make AVX512_SUPPORT=ON bench_boolean
|
||||
|
||||
#Integer benchmarks:
|
||||
make bench_integer
|
||||
|
||||
#Shortint benchmarks:
|
||||
make bench_shortint
|
||||
```
|
||||
|
||||
If the host machine supports AVX-512, then the argument `AVX512_SUPPORT=ON' should be added, e.g.:
|
||||
|
||||
```shell
|
||||
#Integer benchmarks:
|
||||
make AVX512_SUPPORT=ON bench_integer
|
||||
|
||||
#Shortint benchmarks:
|
||||
make AVX512_SUPPORT=ON bench_shortint
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
If the host machine does not support AVX512, then turning on `AVX512_SUPPORT` will not provide any speed-up.
|
||||
|
||||
@@ -4,12 +4,22 @@
|
||||
|
||||
## Importing into your project
|
||||
|
||||
To use `TFHE-rs` in your project, you first need to add it as a dependency in your `Cargo.toml`:
|
||||
To use `TFHE-rs` in your project, you first need to add it as a dependency in your `Cargo.toml`.
|
||||
|
||||
If you are using an `x86` machine:
|
||||
```toml
|
||||
tfhe = { version = "0.4.0", features = [ "boolean", "shortint", "integer", "x86_64-unix" ] }
|
||||
tfhe = { version = "0.5.0", features = [ "boolean", "shortint", "integer", "x86_64-unix" ] }
|
||||
```
|
||||
|
||||
If you are using an `ARM` machine:
|
||||
```toml
|
||||
tfhe = { version = "0.5.0", features = [ "boolean", "shortint", "integer", "aarch64-unix" ] }
|
||||
```
|
||||
|
||||
{% hint style="info" %}
|
||||
You need to use a Rust version >= 1.72 to compile TFHE-rs.
|
||||
{% endhint %}
|
||||
|
||||
{% hint style="success" %}
|
||||
When running code that uses `TFHE-rs`, it is highly recommended to run in release mode with cargo's `--release` flag to have the best possible performance
|
||||
{% endhint %}
|
||||
@@ -25,7 +35,3 @@ TFHE-rs is supported on Linux (x86, aarch64), macOS (x86, aarch64) and Windows (
|
||||
| Linux | `x86_64-unix` | `aarch64-unix`\* |
|
||||
| macOS | `x86_64-unix` | `aarch64-unix`\* |
|
||||
| Windows | `x86_64` | Unsupported |
|
||||
|
||||
{% hint style="info" %}
|
||||
Users who have ARM devices can compile TFHE-rs using a stable toolchain with version >= 1.72 (see [Configuration](../how_to/rust_configuration.md) for more details).
|
||||
{% endhint %}
|
||||
|
||||
@@ -1,260 +1,57 @@
|
||||
# Operations
|
||||
# Homomorphic Types and Operations
|
||||
|
||||
The table below contains an overview of the available operations in `TFHE-rs`. More details, and further examples, are given in the following sections.
|
||||
## Types
|
||||
`TFHE-rs` includes two main types to represent encrypted data:
|
||||
- `FheUint`: this is the homomorphic equivalent of Rust unsigned integers `u8, u16, ...`
|
||||
- `FheInt`: this is the homomorphic equivalent of Rust (signed) integers `i8, i16, ...`
|
||||
|
||||
| name | symbol | FheUint/FheUint | FheUint/Uint | Uint/FheUint |
|
||||
|-----------------------|-------------|--------------------|--------------------------|--------------------------|
|
||||
| Neg | `-` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Add | `+` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Sub | `-` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Mul | `*` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Div | `/` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Rem | `%` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Not | `!` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| BitAnd | `&` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| BitOr | `\|` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| BitXor | `^` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Shr | `>>` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Shl | `<<` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Min | `min` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Max | `max` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Greater than | `gt` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Greater or equal than | `ge` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Lower than | `lt` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Lower or equal than | `le` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Equal | `eq` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Cast (into dest type) | `cast_into` | :heavy_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
|
||||
| Cast (from src type) | `cast_from` | :heavy_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
|
||||
In the same manner as many programming languages, the number of bits used to represent the data must be chosen when declaring a variable. For instance:
|
||||
|
||||
## Boolean Operations
|
||||
```Rust
|
||||
// let clear_a: u64 = 7;
|
||||
let mut a = FheUint64::try_encrypt(clear_a, &keys)?;
|
||||
|
||||
Native homomorphic Booleans support common Boolean operations.
|
||||
// let clear_b: i8 = 3;
|
||||
let mut b = FheInt8::try_encrypt(clear_b, &keys)?;
|
||||
|
||||
The list of supported operations is:
|
||||
|
||||
| name | symbol | type |
|
||||
| ------------------------------------------------------------- | ------ | ------ |
|
||||
| [BitAnd](https://doc.rust-lang.org/std/ops/trait.BitAnd.html) | `&` | Binary |
|
||||
| [BitOr](https://doc.rust-lang.org/std/ops/trait.BitOr.html) | `\|` | Binary |
|
||||
| [BitXor](https://doc.rust-lang.org/std/ops/trait.BitXor.html) | `^` | Binary |
|
||||
| [Not](https://doc.rust-lang.org/std/ops/trait.Not.html) | `!` | Unary |
|
||||
|
||||
## ShortInt Operations
|
||||
|
||||
Native small homomorphic integer types (e.g., FheUint3 or FheUint4) easily compute various operations. In general, computing over encrypted data is as easy as computing over clear data, since the same operation symbol is used. The addition between two ciphertexts is done using the symbol `+` between two FheUint values. Many operations can be computed between a clear value (i.e. a scalar) and a ciphertext.
|
||||
|
||||
In Rust, operations on native types are modular. For example, computations on `u8` are carried out modulo $$2^{8}$$. A similar idea applies for FheUintX, where operations are done modulo $$2^{X}$$. For FheUint3, operations are done modulo $$8 = 2^{3}$$.
|
||||
|
||||
### Arithmetic operations.
|
||||
|
||||
Small homomorphic integer types support all common arithmetic operations, meaning `+`, `-`, `x`, `/`, `mod`.
|
||||
|
||||
The division operation implements a subtlety: since data is encrypted, it is possible to compute a division by 0. In this case, the division is tweaked so that dividing by 0 returns the max possible value for the message.
|
||||
|
||||
The list of supported operations is:
|
||||
|
||||
| name | symbol | type |
|
||||
| ------------------------------------------------------- | ------ | ------ |
|
||||
| [Add](https://doc.rust-lang.org/std/ops/trait.Add.html) | `+` | Binary |
|
||||
| [Sub](https://doc.rust-lang.org/std/ops/trait.Sub.html) | `-` | Binary |
|
||||
| [Mul](https://doc.rust-lang.org/std/ops/trait.Mul.html) | `*` | Binary |
|
||||
| [Div](https://doc.rust-lang.org/std/ops/trait.Div.html) | `/` | Binary |
|
||||
| [Rem](https://doc.rust-lang.org/std/ops/trait.Rem.html) | `%` | Binary |
|
||||
| [Neg](https://doc.rust-lang.org/std/ops/trait.Neg.html) | `-` | Unary |
|
||||
|
||||
A simple example on how to use these operations:
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint3};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_uint3().build();
|
||||
let (keys, server_keys) = generate_keys(config);
|
||||
set_server_key(server_keys);
|
||||
|
||||
let clear_a = 7;
|
||||
let clear_b = 3;
|
||||
let clear_c = 2;
|
||||
|
||||
let mut a = FheUint3::try_encrypt(clear_a, &keys)?;
|
||||
let mut b = FheUint3::try_encrypt(clear_b, &keys)?;
|
||||
let mut c = FheUint3::try_encrypt(clear_c, &keys)?;
|
||||
|
||||
|
||||
a = a * &b; // Clear equivalent computations: 7 * 3 mod 8 = 5
|
||||
b = &b + &c; // Clear equivalent computations: 3 + 2 mod 8 = 5
|
||||
b = b - 5; // Clear equivalent computations: 5 - 5 mod 8 = 0
|
||||
|
||||
let dec_a = a.decrypt(&keys);
|
||||
let dec_b = b.decrypt(&keys);
|
||||
|
||||
// We homomorphically swapped values using bitwise operations
|
||||
assert_eq!(dec_a, (clear_a * clear_b) % 8);
|
||||
assert_eq!(dec_b, ((clear_b + clear_c) - 5) % 8);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// let clear_c: u128 = 2;
|
||||
let mut c = FheUint128::try_encrypt(clear_c, &keys)?;
|
||||
```
|
||||
|
||||
### Bitwise operations.
|
||||
## Operation list
|
||||
The table below contains an overview of the available operations in `TFHE-rs`. The notation `Enc` (for Encypted) either refers to `FheInt` or `FheUint`, for any size between 1 and 256-bits.
|
||||
|
||||
Small homomorphic integer types support some bitwise operations.
|
||||
More details, and further examples, are given in the following sections.
|
||||
|
||||
The list of supported operations is:
|
||||
| name | symbol | `Enc`/`Enc` | `Enc`/ `Int` |
|
||||
|-----------------------|----------------|--------------------|--------------------------|
|
||||
| Neg | `-` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Add | `+` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Sub | `-` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Mul | `*` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Div | `/` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Rem | `%` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Not | `!` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| BitAnd | `&` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| BitOr | `\|` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| BitXor | `^` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Shr | `>>` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Shl | `<<` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Min | `min` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Max | `max` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Greater than | `gt` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Greater or equal than | `ge` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Lower than | `lt` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Lower or equal than | `le` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Equal | `eq` | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Cast (into dest type) | `cast_into` | :heavy_check_mark: | :heavy_multiplication_x: |
|
||||
| Cast (from src type) | `cast_from` | :heavy_check_mark: | :heavy_multiplication_x: |
|
||||
| Ternary operator | `if_then_else` | :heavy_check_mark: | :heavy_multiplication_x: |
|
||||
|
||||
| name | symbol | type |
|
||||
|--------------------------------------------------------------------------------------|----------------|--------|
|
||||
| [Not](https://doc.rust-lang.org/std/ops/trait.Not.html) | `!` | Unary |
|
||||
| [BitAnd](https://doc.rust-lang.org/std/ops/trait.BitAnd.html) | `&` | Binary |
|
||||
| [BitOr](https://doc.rust-lang.org/std/ops/trait.BitOr.html) | `\|` | Binary |
|
||||
| [BitXor](https://doc.rust-lang.org/std/ops/trait.BitXor.html) | `^` | Binary |
|
||||
| [Shr](https://doc.rust-lang.org/std/ops/trait.Shr.html) | `>>` | Binary |
|
||||
| [Shl](https://doc.rust-lang.org/std/ops/trait.Shl.html) | `<<` | Binary |
|
||||
| [Rotate Right](https://doc.rust-lang.org/std/primitive.u32.html#method.rotate_right) | `rotate_right` | Binary |
|
||||
| [Rotate Left](https://doc.rust-lang.org/std/primitive.u32.html#method.rotate_left) | `rotate_left` | Binary |
|
||||
|
||||
A simple example on how to use these operations:
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint3};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_uint3().build();
|
||||
let (keys, server_keys) = generate_keys(config);
|
||||
set_server_key(server_keys);
|
||||
|
||||
let clear_a = 7;
|
||||
let clear_b = 3;
|
||||
|
||||
let mut a = FheUint3::try_encrypt(clear_a, &keys)?;
|
||||
let mut b = FheUint3::try_encrypt(clear_b, &keys)?;
|
||||
|
||||
a = a ^ &b;
|
||||
b = b ^ &a;
|
||||
a = a ^ &b;
|
||||
|
||||
let dec_a = a.decrypt(&keys);
|
||||
let dec_b = b.decrypt(&keys);
|
||||
|
||||
// We homomorphically swapped values using bitwise operations
|
||||
assert_eq!(dec_a, clear_b);
|
||||
assert_eq!(dec_b, clear_a);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### Comparisons.
|
||||
|
||||
Small homomorphic integer types support comparison operations.
|
||||
|
||||
Due to some Rust limitations, it is not possible to overload the comparison symbols because of the inner definition of the operations. Rust expects to have a Boolean as an output, whereas a ciphertext is returned when using homomorphic types.
|
||||
|
||||
You will need to use different methods instead of using symbols for the comparisons. These methods follow the same naming conventions as the two standard Rust traits:
|
||||
|
||||
* [PartialOrd](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html)
|
||||
* [PartialEq](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html)
|
||||
|
||||
The list of supported operations is:
|
||||
|
||||
| name | symbol | type |
|
||||
|-----------------------------------------------------------------------------|--------|--------|
|
||||
| [Equal ](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html) | `eq` | Binary |
|
||||
| [Not Equal ](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html) | `ne` | Binary |
|
||||
| [Greater Than ](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html) | `gt` | Binary |
|
||||
| [Greater or Equal](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html) | `ge` | Binary |
|
||||
| [Lower ](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html) | `lt` | Binary |
|
||||
| [Lower or Equal ](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html) | `le` | Binary |
|
||||
|
||||
|
||||
A simple example on how to use these operations:
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint3};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_uint3().build();
|
||||
let (keys, server_keys) = generate_keys(config);
|
||||
set_server_key(server_keys);
|
||||
|
||||
let clear_a = 7;
|
||||
let clear_b = 3;
|
||||
|
||||
let mut a = FheUint3::try_encrypt(clear_a, &keys)?;
|
||||
let mut b = FheUint3::try_encrypt(clear_b, &keys)?;
|
||||
|
||||
assert_eq!(a.gt(&b).decrypt(&keys) != 0, true);
|
||||
assert_eq!(b.le(&a).decrypt(&keys) != 0, true);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### Univariate function evaluation.
|
||||
|
||||
The shortint type also supports the computation of univariate functions, which make use of TFHE's _programmable bootstrapping_.
|
||||
|
||||
A simple example on how to use these operations:
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint4};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_uint4().build();
|
||||
let (keys, server_keys) = generate_keys(config);
|
||||
set_server_key(server_keys);
|
||||
|
||||
let pow_5 = |value: u64| {
|
||||
value.pow(5) % FheUint4::MODULUS as u64
|
||||
};
|
||||
|
||||
let clear_a = 12;
|
||||
let a = FheUint4::try_encrypt(12, &keys)?;
|
||||
|
||||
let c = a.map(pow_5);
|
||||
let decrypted = c.decrypt(&keys);
|
||||
assert_eq!(decrypted, pow_5(clear_a) as u8);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### Bivariate function evaluations.
|
||||
|
||||
Using the shortint type allows you to evaluate bivariate functions (i.e., functions that take two ciphertexts as input).
|
||||
|
||||
A simple code example:
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint2};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_uint2().build();
|
||||
let (keys, server_keys) = generate_keys(config);
|
||||
set_server_key(server_keys);
|
||||
|
||||
let clear_a = 1;
|
||||
let clear_b = 3;
|
||||
let a = FheUint2::try_encrypt(clear_a, &keys)?;
|
||||
let b = FheUint2::try_encrypt(clear_b, &keys)?;
|
||||
|
||||
|
||||
let c = a.bivariate_function(&b, std::cmp::max);
|
||||
let decrypted = c.decrypt(&keys);
|
||||
assert_eq!(decrypted, std::cmp::max(clear_a, clear_b) as u8);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
## Integer
|
||||
|
||||
In TFHE-rs, integers are used to encrypt any messages larger than 4 bits. All supported operations are listed below.
|
||||
In `TFHE-rs`, integers are used to encrypt all messages which are larger than 4 bits. All supported operations are listed below.
|
||||
|
||||
### Arithmetic operations.
|
||||
|
||||
@@ -271,40 +68,43 @@ The list of supported operations is:
|
||||
| [Div](https://doc.rust-lang.org/std/ops/trait.Div.html)* | `/` | Binary |
|
||||
| [Rem](https://doc.rust-lang.org/std/ops/trait.Rem.html)* | `%` | Binary |
|
||||
|
||||
For division by $$0$$, the convention is to return $$modulus - 1$$. For instance, for FheUint8, the modulus is $$2^8=256$$, so a division by $$0$$ will return an encryption of $$255$$.
|
||||
For the remainder operator, the convention is to return the first input without any modification. For instance, for $$ct1 = FheUint8(63)$$ and $$ct2 = FheUint8(0)$$, then $$ct1 % ct2$$ will return $$FheUint8(63)$$.
|
||||
For division by 0, the convention is to return `modulus - 1`. For instance, for `FheUint8`, the modulus is $$2^8=256$$, so a division by 0 will return an encryption of 255.
|
||||
For the remainder operator, the convention is to return the first input without any modification. For instance, if `ct1 = FheUint8(63)` and `ct2 = FheUint8(0)` then `ct1 % ct2` will return `FheUint8(63)`.
|
||||
|
||||
|
||||
|
||||
A simple example on how to use these operations:
|
||||
A simple example of how to use these operations:
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint8};
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheInt8, FheUint8};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_integers().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (keys, server_keys) = generate_keys(config);
|
||||
set_server_key(server_keys);
|
||||
|
||||
let clear_a = 15_u64;
|
||||
let clear_b = 27_u64;
|
||||
let clear_c = 43_u64;
|
||||
let clear_d = -87_i64;
|
||||
|
||||
let mut a = FheUint8::try_encrypt(clear_a, &keys)?;
|
||||
let mut b = FheUint8::try_encrypt(clear_b, &keys)?;
|
||||
let mut c = FheUint8::try_encrypt(clear_c, &keys)?;
|
||||
let mut d = FheInt8::try_encrypt(clear_d, &keys)?;
|
||||
|
||||
|
||||
a = a * &b; // Clear equivalent computations: 15 * 27 mod 256 = 149
|
||||
b = &b + &c; // Clear equivalent computations: 27 + 43 mod 256 = 70
|
||||
a = a * &b; // Clear equivalent computations: 15 * 27 mod 256 = 149
|
||||
b = &b + &c; // Clear equivalent computations: 27 + 43 mod 256 = 70
|
||||
b = b - 76u8; // Clear equivalent computations: 70 - 76 mod 256 = 250
|
||||
d = d - 13i8; // Clear equivalent computations: -87 - 13 = 100 in [-128, 128[
|
||||
|
||||
let dec_a: u8 = a.decrypt(&keys);
|
||||
let dec_b: u8 = b.decrypt(&keys);
|
||||
let dec_d: i8 = d.decrypt(&keys);
|
||||
|
||||
assert_eq!(dec_a, ((clear_a * clear_b) % 256_u64) as u8);
|
||||
assert_eq!(dec_b, (((clear_b + clear_c).wrapping_sub(76_u64)) % 256_u64) as u8);
|
||||
assert_eq!(dec_d, (clear_d - 13) as i8);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -327,14 +127,14 @@ The list of supported operations is:
|
||||
| [Rotate Right](https://doc.rust-lang.org/std/primitive.u32.html#method.rotate_right) | `rotate_right` | Binary |
|
||||
| [Rotate Left](https://doc.rust-lang.org/std/primitive.u32.html#method.rotate_left) | `rotate_left` | Binary |
|
||||
|
||||
A simple example on how to use these operations:
|
||||
A simple example of how to use these operations:
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint8};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_integers().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (keys, server_keys) = generate_keys(config);
|
||||
set_server_key(server_keys);
|
||||
|
||||
@@ -361,7 +161,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
### Comparisons.
|
||||
|
||||
Homomorphic integers support comparison operations. Since Rust does not allow the overloading of these operations, a simple function has been associated to each one.
|
||||
Homomorphic integers support comparison operations.
|
||||
|
||||
Due to some Rust limitations, it is not possible to overload the comparison symbols because of the inner definition of the operations. This is because Rust expects to have a Boolean as an output, whereas a ciphertext is returned when using homomorphic types.
|
||||
|
||||
You will need to use different methods instead of using symbols for the comparisons. These methods follow the same naming conventions as the two standard Rust traits:
|
||||
|
||||
* [PartialOrd](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html)
|
||||
* [PartialEq](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html)
|
||||
|
||||
The list of supported operations is:
|
||||
|
||||
@@ -374,22 +181,22 @@ The list of supported operations is:
|
||||
| [Lower ](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html) | `lt` | Binary |
|
||||
| [Lower or Equal ](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html) | `le` | Binary |
|
||||
|
||||
A simple example on how to use these operations:
|
||||
A simple example of how to use these operations:
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint8};
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheInt8};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_integers().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (keys, server_keys) = generate_keys(config);
|
||||
set_server_key(server_keys);
|
||||
|
||||
let clear_a:u8 = 164;
|
||||
let clear_b:u8 = 212;
|
||||
let clear_a: i8 = -121;
|
||||
let clear_b: i8 = 87;
|
||||
|
||||
let mut a = FheUint8::try_encrypt(clear_a, &keys)?;
|
||||
let mut b = FheUint8::try_encrypt(clear_b, &keys)?;
|
||||
let mut a = FheInt8::try_encrypt(clear_a, &keys)?;
|
||||
let mut b = FheInt8::try_encrypt(clear_b, &keys)?;
|
||||
|
||||
let greater = a.gt(&b);
|
||||
let greater_or_equal = a.ge(&b);
|
||||
@@ -397,18 +204,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let lower_or_equal = a.le(&b);
|
||||
let equal = a.eq(&b);
|
||||
|
||||
let dec_gt : u8 = greater.decrypt(&keys);
|
||||
let dec_ge : u8 = greater_or_equal.decrypt(&keys);
|
||||
let dec_lt : u8 = lower.decrypt(&keys);
|
||||
let dec_le : u8 = lower_or_equal.decrypt(&keys);
|
||||
let dec_eq : u8 = equal.decrypt(&keys);
|
||||
let dec_gt = greater.decrypt(&keys);
|
||||
let dec_ge = greater_or_equal.decrypt(&keys);
|
||||
let dec_lt = lower.decrypt(&keys);
|
||||
let dec_le = lower_or_equal.decrypt(&keys);
|
||||
let dec_eq = equal.decrypt(&keys);
|
||||
|
||||
// We homomorphically swapped values using bitwise operations
|
||||
assert_eq!(dec_gt, (clear_a > clear_b ) as u8);
|
||||
assert_eq!(dec_ge, (clear_a >= clear_b) as u8);
|
||||
assert_eq!(dec_lt, (clear_a < clear_b ) as u8);
|
||||
assert_eq!(dec_le, (clear_a <= clear_b) as u8);
|
||||
assert_eq!(dec_eq, (clear_a == clear_b) as u8);
|
||||
assert_eq!(dec_gt, clear_a > clear_b);
|
||||
assert_eq!(dec_ge, clear_a >= clear_b);
|
||||
assert_eq!(dec_lt, clear_a < clear_b);
|
||||
assert_eq!(dec_le, clear_a <= clear_b);
|
||||
assert_eq!(dec_eq, clear_a == clear_b);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -423,14 +229,14 @@ Homomorphic integers support the min/max operations.
|
||||
| Min | `min` | Binary |
|
||||
| Max | `max` | Binary |
|
||||
|
||||
A simple example on how to use these operations:
|
||||
A simple example of how to use these operations:
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint8};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_integers().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (keys, server_keys) = generate_keys(config);
|
||||
set_server_key(server_keys);
|
||||
|
||||
@@ -446,7 +252,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let dec_min : u8 = min.decrypt(&keys);
|
||||
let dec_max : u8 = max.decrypt(&keys);
|
||||
|
||||
// We homomorphically swapped values using bitwise operations
|
||||
assert_eq!(dec_min, u8::min(clear_a, clear_b));
|
||||
assert_eq!(dec_max, u8::max(clear_a, clear_b));
|
||||
|
||||
@@ -454,19 +259,67 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
```
|
||||
|
||||
### Casting.
|
||||
### Ternary conditional operator.
|
||||
The ternary conditional operator allows computing conditional instructions of the form `if cond { choice_if } else { choice_else }`.
|
||||
|
||||
| name | symbol | type |
|
||||
|------------------|----------------|---------|
|
||||
| Ternary operator | `if_then_else` | Ternary |
|
||||
|
||||
The syntax is `encrypted_condition.if_then_else(encrypted_choice_if, encrypted_choice_else)`. The `encrypted_condition` should be an encryption of 0 or 1 in order to be valid.
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheInt32};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Basic configuration to use homomorphic integers
|
||||
let config = ConfigBuilder::default().build();
|
||||
|
||||
// Key generation
|
||||
let (client_key, server_keys) = generate_keys(config);
|
||||
|
||||
let clear_a = 32i32;
|
||||
let clear_b = -45i32;
|
||||
|
||||
// Encrypting the input data using the (private) client_key
|
||||
// FheInt32: Encrypted equivalent to i32
|
||||
let encrypted_a = FheInt32::try_encrypt(clear_a, &client_key)?;
|
||||
let encrypted_b = FheInt32::try_encrypt(clear_b, &client_key)?;
|
||||
|
||||
// On the server side:
|
||||
set_server_key(server_keys);
|
||||
|
||||
// Clear equivalent computations: 32 > -45
|
||||
let encrypted_comp = &encrypted_a.gt(&encrypted_b);
|
||||
let clear_res = encrypted_comp.decrypt(&client_key);
|
||||
assert_eq!(clear_res, clear_a > clear_b);
|
||||
|
||||
// `encrypted_comp` is a FheBool, thus it encrypts a boolean value.
|
||||
// This acts as a condition on which the
|
||||
// `if_then_else` function can be applied on.
|
||||
// Clear equivalent computations:
|
||||
// if 32 > -45 {result = 32} else {result = -45}
|
||||
let encrypted_res = &encrypted_comp.if_then_else(&encrypted_a, &encrypted_b);
|
||||
|
||||
let clear_res: i32 = encrypted_res.decrypt(&client_key);
|
||||
assert_eq!(clear_res, clear_a);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Casting.
|
||||
Casting between integer types is possible via the `cast_from` associated function
|
||||
or the `cast_into` method.
|
||||
|
||||
```rust
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint8, FheUint32, FheUint16};
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheInt16, FheUint8, FheUint32, FheUint16};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
// Casting requires server_key to set
|
||||
@@ -503,6 +356,30 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
assert_eq!(da, (clear as u32) as u8);
|
||||
}
|
||||
|
||||
{
|
||||
let clear = 12_837i16;
|
||||
let a = FheInt16::encrypt(clear, &client_key);
|
||||
|
||||
// Casting from FheInt16 to FheUint16
|
||||
let a = FheUint16::cast_from(a);
|
||||
let da: u16 = a.decrypt(&client_key);
|
||||
assert_eq!(da, clear as u16);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Boolean Operations
|
||||
|
||||
Native homomorphic Booleans support common Boolean operations.
|
||||
|
||||
The list of supported operations is:
|
||||
|
||||
| name | symbol | type |
|
||||
| ------------------------------------------------------------- | ------ | ------ |
|
||||
| [BitAnd](https://doc.rust-lang.org/std/ops/trait.BitAnd.html) | `&` | Binary |
|
||||
| [BitOr](https://doc.rust-lang.org/std/ops/trait.BitOr.html) | `\|` | Binary |
|
||||
| [BitXor](https://doc.rust-lang.org/std/ops/trait.BitXor.html) | `^` | Binary |
|
||||
| [Not](https://doc.rust-lang.org/std/ops/trait.Not.html) | `!` | Unary |
|
||||
|
||||
@@ -18,9 +18,7 @@ use tfhe::{ConfigBuilder, generate_keys, set_server_key, FheUint8};
|
||||
use tfhe::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
|
||||
// Client-side
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
@@ -46,7 +44,7 @@ fn main() {
|
||||
|
||||
The default configuration for x86 Unix machines:
|
||||
```toml
|
||||
tfhe = { version = "0.4.0", features = ["integer", "x86_64-unix"]}
|
||||
tfhe = { version = "0.5.0", features = ["integer", "x86_64-unix"]}
|
||||
```
|
||||
|
||||
Configuration options for different platforms can be found [here](../getting_started/installation.md). Other rust and homomorphic types features can be found [here](../how_to/rust_configuration.md).
|
||||
@@ -76,9 +74,8 @@ The config is generated by first creating a builder with all types deactivated.
|
||||
use tfhe::{ConfigBuilder, generate_keys};
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
|
||||
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
}
|
||||
@@ -98,9 +95,7 @@ This function will **move** the server key to an internal state of the crate and
|
||||
use tfhe::{ConfigBuilder, generate_keys, set_server_key};
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
@@ -139,6 +134,3 @@ let clear_result = clear_a + clear_b;
|
||||
|
||||
assert_eq!(decrypted_result, clear_result);
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ The figure below illustrates this problem in the case of an addition, where an e
|
||||
|
||||
### Programmable BootStrapping (PBS)
|
||||
|
||||
The bootstrapping of TFHE has the particularity of being programmable: this means that any function can be homomorphically computed over an encrypted input, while also reducing the noise. These functions are represented by look-up tables. The computation of a PBS is in general either preceded or followed by a keyswitch, which is an operation used to change the encryption key. The output ciphertext is then encrypted with the same key as the input one. To do this, two (public) evaluation keys are required: a boostrapping key and a keyswitching key. These operations are quite complex to describe, more information about these operations (or about TFHE in general) can be found here [TFHE Deep Dive](https://www.zama.ai/post/tfhe-deep-dive-part-1).
|
||||
The bootstrapping of TFHE has the particularity of being programmable: this means that any function can be homomorphically computed over an encrypted input, while also reducing the noise. These functions are represented by look-up tables. The computation of a PBS is in general either preceded or followed by a keyswitch, which is an operation used to change the encryption key. The output ciphertext is then encrypted with the same key as the input one. To do this, two (public) evaluation keys are required: a bootstrapping key and a keyswitching key. These operations are quite complex to describe, more information about these operations (or about TFHE in general) can be found here [TFHE Deep Dive](https://www.zama.ai/post/tfhe-deep-dive-part-1).
|
||||
|
||||
|
||||
### Carry.
|
||||
|
||||
@@ -13,9 +13,7 @@ use tfhe::prelude::*;
|
||||
use tfhe::{ConfigBuilder, generate_keys, set_server_key, CompressedFheUint16};
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, _) = generate_keys(config);
|
||||
|
||||
let clear = 12_837u16;
|
||||
@@ -48,9 +46,7 @@ use tfhe::{
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
|
||||
let cks = ClientKey::generate(config);
|
||||
let compressed_sks = CompressedServerKey::new(&cks);
|
||||
@@ -84,7 +80,7 @@ fn main() {
|
||||
This example shows how to compress the classical public keys.
|
||||
|
||||
{% hint style="warning" %}
|
||||
It is not currently recommended to use the CompressedPublicKey to encrypt ciphertexts without first decompressing it. In case the resulting PublicKey is too large to fit in memory the encryption with the CompressedPublicKey will be very slow, this is a known problem and will be adressed in future releases.
|
||||
It is not currently recommended to use the CompressedPublicKey to encrypt ciphertexts without first decompressing it. In case the resulting PublicKey is too large to fit in memory the encryption with the CompressedPublicKey will be very slow, this is a known problem and will be addressed in future releases.
|
||||
{% endhint %}
|
||||
|
||||
```rust
|
||||
@@ -92,9 +88,7 @@ use tfhe::prelude::*;
|
||||
use tfhe::{ConfigBuilder, generate_keys, set_server_key, FheUint8, CompressedPublicKey};
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, _) = generate_keys(config);
|
||||
|
||||
let compressed_public_key = CompressedPublicKey::new(&client_key);
|
||||
@@ -122,8 +116,8 @@ use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, CompressedCompactPublicKey, ConfigBuilder, FheUint8};
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_custom_integers(
|
||||
let config = ConfigBuilder::default()
|
||||
.use_custom_parameters(
|
||||
tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS,
|
||||
None,
|
||||
)
|
||||
|
||||
@@ -10,8 +10,8 @@ use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint32};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_custom_integers(
|
||||
let config = ConfigBuilder::default()
|
||||
.use_custom_parameters(
|
||||
tfhe::shortint::parameters::PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS,
|
||||
None,
|
||||
)
|
||||
@@ -41,8 +41,8 @@ use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint32};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_custom_integers(
|
||||
let config = ConfigBuilder::default()
|
||||
.use_custom_parameters(
|
||||
tfhe::shortint::parameters::PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS.with_deterministic_execution(),
|
||||
None,
|
||||
)
|
||||
@@ -63,6 +63,3 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,9 +12,7 @@ use tfhe::prelude::*;
|
||||
use tfhe::{ConfigBuilder, generate_keys, set_server_key, FheUint8, PublicKey};
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, _) = generate_keys(config);
|
||||
|
||||
let public_key = PublicKey::new(&client_key);
|
||||
@@ -34,8 +32,8 @@ use tfhe::prelude::*;
|
||||
use tfhe::{ConfigBuilder, generate_keys, set_server_key, FheUint8, CompactPublicKey};
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_custom_integers(
|
||||
let config = ConfigBuilder::default()
|
||||
.use_custom_parameters(
|
||||
tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS,
|
||||
None,
|
||||
)
|
||||
@@ -49,4 +47,3 @@ fn main() {
|
||||
assert_eq!(clear, 255u8);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Using the right toolchain for TFHE-rs.
|
||||
|
||||
TFHE-rs only requires a nighlty toolchain for building the C API and using advanced SIMD instructions, otherwise you can use a stable toolchain (with version >= 1.72 for ARM devices)
|
||||
TFHE-rs only requires a nightly toolchain for building the C API and using advanced SIMD instructions, otherwise you can use a stable toolchain (with version >= 1.72)
|
||||
Install the needed Rust toolchain:
|
||||
|
||||
```shell
|
||||
@@ -27,7 +27,7 @@ cargo +nightly test
|
||||
|
||||
```shell
|
||||
# This should not be necessary by default, but if you want to make sure your configuration is
|
||||
# correct you can still set the overriden toolchain to stable
|
||||
# correct you can still set the overridden toolchain to stable
|
||||
rustup override set stable
|
||||
# cargo will use the `stable` toolchain.
|
||||
cargo build
|
||||
@@ -52,11 +52,11 @@ rustup show
|
||||
|
||||
This crate exposes two kinds of data types. Each kind is enabled by activating its corresponding feature in the TOML line. Each kind may have multiple types:
|
||||
|
||||
| Kind | Features | Type(s) |
|
||||
| --------- | ---------- | --------------------------------- |
|
||||
| Booleans | `boolean` | Booleans |
|
||||
| ShortInts | `shortint` | Short unsigned integers |
|
||||
| Integers | `integer` | Arbitrary-sized unsigned integers |
|
||||
| Kind | Features | Type(s) |
|
||||
|-----------|------------|---------------------------|
|
||||
| Booleans | `boolean` | Booleans |
|
||||
| ShortInts | `shortint` | Short integers |
|
||||
| Integers | `integer` | Arbitrary-sized integers |
|
||||
|
||||
|
||||
## AVX-512
|
||||
|
||||
@@ -11,7 +11,7 @@ To serialize our data, a [data format](https://serde.rs/#data-formats) should be
|
||||
|
||||
[dependencies]
|
||||
# ...
|
||||
tfhe = { version = "0.4.0", features = ["integer","x86_64-unix"]}
|
||||
tfhe = { version = "0.5.0", features = ["integer","x86_64-unix"]}
|
||||
bincode = "1.3.3"
|
||||
```
|
||||
|
||||
@@ -26,9 +26,7 @@ use tfhe::{ConfigBuilder, ServerKey, generate_keys, set_server_key, FheUint8};
|
||||
use tfhe::prelude::*;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>>{
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
|
||||
let ( client_key, server_key) = generate_keys(config);
|
||||
|
||||
|
||||
@@ -68,8 +68,7 @@ pub fn ex4<FheType, ClearType>(a: FheType, b: FheType, pt: ClearType) -> FheType
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
let config = ConfigBuilder::default()
|
||||
.build();
|
||||
|
||||
let (client_key, server_keys) = generate_keys(config);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Trival Ciphertext
|
||||
# Trivial Ciphertext
|
||||
|
||||
Sometimes, the server side needs to initialize a value.
|
||||
For example, when computing the sum of a list of ciphertext,
|
||||
@@ -11,9 +11,7 @@ the server can do a *trivial encryption*
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint8};
|
||||
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, sks) = generate_keys(config);
|
||||
|
||||
set_server_key(sks);
|
||||
@@ -38,9 +36,7 @@ value if the ciphertext/clear-value operation (often called scalar operation) yo
|
||||
use tfhe::prelude::*;
|
||||
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint32};
|
||||
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
.build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
let (client_key, sks) = generate_keys(config);
|
||||
|
||||
set_server_key(sks);
|
||||
|
||||
@@ -24,7 +24,7 @@ To use the `FheUint8` type, the `integer` feature must be activated:
|
||||
|
||||
[dependencies]
|
||||
# Default configuration for x86 Unix machines:
|
||||
tfhe = { version = "0.4.0", features = ["integer", "x86_64-unix"]}
|
||||
tfhe = { version = "0.5.0", features = ["integer", "x86_64-unix"]}
|
||||
```
|
||||
|
||||
Other configurations can be found [here](../getting_started/installation.md).
|
||||
@@ -69,7 +69,7 @@ use tfhe::FheUint8;
|
||||
pub const UP_LOW_DISTANCE: u8 = 32;
|
||||
|
||||
fn to_lower(c: &FheUint8) -> FheUint8 {
|
||||
c + (c.gt(64) & c.lt(91)) * UP_LOW_DISTANCE
|
||||
c + FheUint8::cast_from(c.gt(64) & c.lt(91)) * UP_LOW_DISTANCE
|
||||
}
|
||||
```
|
||||
|
||||
@@ -86,11 +86,11 @@ struct FheAsciiString {
|
||||
}
|
||||
|
||||
fn to_upper(c: &FheUint8) -> FheUint8 {
|
||||
c - (c.gt(96) & c.lt(123)) * UP_LOW_DISTANCE
|
||||
c - FheUint8::cast_from(c.gt(96) & c.lt(123)) * UP_LOW_DISTANCE
|
||||
}
|
||||
|
||||
fn to_lower(c: &FheUint8) -> FheUint8 {
|
||||
c + (c.gt(64) & c.lt(91)) * UP_LOW_DISTANCE
|
||||
c + FheUint8::cast_from(c.gt(64) & c.lt(91)) * UP_LOW_DISTANCE
|
||||
}
|
||||
|
||||
impl FheAsciiString {
|
||||
@@ -131,8 +131,7 @@ impl FheAsciiString {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled()
|
||||
.enable_default_integers()
|
||||
let config = ConfigBuilder::default()
|
||||
.build();
|
||||
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
@@ -15,13 +15,11 @@ This function returns a Boolean that will be either `true` or `false` so that th
|
||||
|
||||
### Non-generic version.
|
||||
|
||||
To use Booleans, the `booleans` feature in our Cargo.toml must be enabled:
|
||||
|
||||
```toml
|
||||
# Cargo.toml
|
||||
|
||||
# Default configuration for x86 Unix machines:
|
||||
tfhe = { version = "0.4.0", features = ["boolean", "x86_64-unix"]}
|
||||
tfhe = { version = "0.5.0", features = ["integer", "x86_64-unix"]}
|
||||
```
|
||||
|
||||
Other configurations can be found [here](../getting_started/installation.md).
|
||||
@@ -129,7 +127,7 @@ fn check_parity_bit_validity(bits: &[bool], mode: ParityMode, parity_bit: bool)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_bool().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
|
||||
let (client_key, server_key) = generate_keys(config);
|
||||
|
||||
@@ -347,7 +345,7 @@ fn check_parity_bit_validity(bits: &[bool], mode: ParityMode, parity_bit: bool)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let config = ConfigBuilder::all_disabled().enable_default_bool().build();
|
||||
let config = ConfigBuilder::default().build();
|
||||
|
||||
let ( client_key, server_key) = generate_keys(config);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::time::Instant;
|
||||
use rayon::prelude::*;
|
||||
|
||||
use tfhe::integer::ciphertext::RadixCiphertext;
|
||||
use tfhe::integer::ServerKey;
|
||||
use tfhe::integer::{IntegerCiphertext, ServerKey};
|
||||
|
||||
use crate::NUMBER_OF_BLOCKS;
|
||||
|
||||
@@ -70,10 +70,12 @@ fn fill_orders(
|
||||
);
|
||||
|
||||
// total_orders > prefix_sum
|
||||
let mut cond = server_key.smart_gt_parallelized(
|
||||
&mut total_orders.clone(),
|
||||
&mut previous_prefix_sum.clone(),
|
||||
);
|
||||
let mut cond = server_key
|
||||
.smart_gt_parallelized(
|
||||
&mut total_orders.clone(),
|
||||
&mut previous_prefix_sum.clone(),
|
||||
)
|
||||
.into_radix(diff.blocks().len(), server_key);
|
||||
|
||||
// (total_orders - previous_prefix_sum) * (total_orders > previous_prefix_sum)
|
||||
// = (total_orders - previous_prefix_sum).max(0)
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::time::Instant;
|
||||
|
||||
use tfhe::integer::ciphertext::RadixCiphertext;
|
||||
use tfhe::integer::keycache::IntegerKeyCache;
|
||||
use tfhe::integer::ServerKey;
|
||||
use tfhe::integer::{IntegerKeyKind, ServerKey};
|
||||
use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS;
|
||||
|
||||
mod fhe;
|
||||
@@ -73,7 +73,8 @@ fn test_volume_match_fhe(
|
||||
) {
|
||||
println!("Generating keys...");
|
||||
let time = Instant::now();
|
||||
let (client_key, server_key) = IntegerKeyCache.get_from_params(PARAM_MESSAGE_2_CARRY_2_KS_PBS);
|
||||
let (client_key, server_key) =
|
||||
IntegerKeyCache.get_from_params(PARAM_MESSAGE_2_CARRY_2_KS_PBS, IntegerKeyKind::Radix);
|
||||
println!("Keys generated in {:?}", time.elapsed());
|
||||
|
||||
println!("Running test cases for the FHE implementation");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use tfhe::integer::{RadixCiphertext, ServerKey};
|
||||
use tfhe::integer::{IntegerCiphertext, RadixCiphertext, ServerKey};
|
||||
|
||||
use crate::parser::u8_to_char;
|
||||
|
||||
@@ -72,7 +72,12 @@ impl Execution {
|
||||
|
||||
let mut ct_a = a.0.clone();
|
||||
let mut ct_b = b.0.clone();
|
||||
(exec.sk.smart_eq(&mut ct_a, &mut ct_b), ctx.clone())
|
||||
(
|
||||
exec.sk
|
||||
.smart_eq(&mut ct_a, &mut ct_b)
|
||||
.into_radix(ct_a.blocks().len(), &exec.sk),
|
||||
ctx.clone(),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -89,7 +94,12 @@ impl Execution {
|
||||
|
||||
let mut ct_a = a.0.clone();
|
||||
let mut ct_b = b.0.clone();
|
||||
(exec.sk.smart_gt(&mut ct_a, &mut ct_b), ctx.clone())
|
||||
(
|
||||
exec.sk
|
||||
.smart_gt(&mut ct_a, &mut ct_b)
|
||||
.into_radix(ct_a.blocks().len(), &exec.sk),
|
||||
ctx.clone(),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -106,7 +116,12 @@ impl Execution {
|
||||
|
||||
let mut ct_a = a.0.clone();
|
||||
let mut ct_b = b.0.clone();
|
||||
(exec.sk.smart_le(&mut ct_a, &mut ct_b), ctx.clone())
|
||||
(
|
||||
exec.sk
|
||||
.smart_le(&mut ct_a, &mut ct_b)
|
||||
.into_radix(ct_a.blocks().len(), &exec.sk),
|
||||
ctx.clone(),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user