Skip to content

Commit

Permalink
add some documentation (#391)
Browse files Browse the repository at this point in the history
Co-authored-by: Rick Weber <[email protected]>
  • Loading branch information
rickwebiii and Rick Weber authored Jan 17, 2025
1 parent 83a1b48 commit 08b1660
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 55 deletions.
15 changes: 11 additions & 4 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ on:
branches: [ main ]
pull_request:
branches: [ main, debugger ]

workflow_dispatch:

env:
CARGO_TERM_COLOR: always

Expand Down Expand Up @@ -45,12 +46,18 @@ jobs:
# We do everything in release mode so tests run quickly and steps cache each other.
# Check the submitted change meets style guidelines

- name: Print cargo version
run: cargo --version

- name: Print clang version
run: clang --version

- name: Cargo Format
run: cargo fmt --check

# Check that common feature permutations compile
- name: Core compile check
run: cargo check --release
run: cargo check --release -vv
- name: Full compile check
run: cargo check --release --features deterministic,linkedproofs,logproof

Expand Down Expand Up @@ -129,9 +136,9 @@ jobs:
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-doc-${{ hashFiles('**/Cargo.lock') }}
key: ${{ runner.os }}-cargo-emscripten-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-doc-
${{ runner.os }}-cargo-emscripten-
${{ runner.os }}-cargo-
- name: Install gcc-multilib (32-bit headers)
run: |
Expand Down
64 changes: 17 additions & 47 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ wgpu-core = { version = "0.17.0", features = ["vulkan", "wgsl"] }
find_cuda_helper = "0.2.0"
criterion = { version = "0.5.1", default-features = false }
darling = "0.20.3"
proc-macro2 = "1.0.66"
proc-macro2 = "1.0"
quote = "1.0.32"
syn = { version = "2.0.28", features = ["full"] }
petgraph = { version = "0.6.0", features = ["serde-1"] }
Expand All @@ -83,7 +83,7 @@ sha3 = "0.10.5"
digest = "0.10.5"
link-cplusplus = "1.0.9"
cmake = "0.1.46"
bindgen = "0.66.1"
bindgen = "0.71"
once_cell = "1.18.0"
rlp = "0.5.2"
fs_extra = "1.2.0"
Expand Down
15 changes: 15 additions & 0 deletions purge-github-caches.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#! /bin/bash

gh auth status

if [ $? -ne 0 ]; then
gh auth login
fi

actions=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/sunscreen-tech/sunscreen/actions/caches | jq '.actions_caches | .[] | .id')

for i in $actions; do
echo "Deleting cache id " $i
gh api --method DELETE -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/sunscreen-tech/sunscreen/actions/caches/$i
done

6 changes: 4 additions & 2 deletions seal_fhe/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ fn main() {
}

let mut builder = bindgen::builder()
.clang_arg(format!("-I{}", out_path.join("include/SEAL-3.7").display()))
.clang_arg(format!("-I{}", out_path.join("include/SEAL-4.0").display()))
.clang_arg("-ISEAL/native/src")
.clang_arg("-xc++")
.clang_arg("-std=c++17");
Expand All @@ -153,7 +153,7 @@ fn main() {
let builder = builder
.detect_include_paths(true)
.header("bindgen_wrapper.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.allowlist_function("BatchEncoder_.*")
.allowlist_function("Ciphertext_.*")
.allowlist_function("CKKSEncoder_.*")
Expand Down Expand Up @@ -181,6 +181,8 @@ fn main() {

let bindings = builder.generate().unwrap();

println!("{}", bindings);

bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Failed to write bindings");
Expand Down
60 changes: 60 additions & 0 deletions sunscreen_tfhe/notes/glwe_scheme_switching.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
This document describes how to generalize scheme switching presented in Micheli et al. to the GLWE setting. In their paper, the authors describe an efficient algorithm for taking a GadgetRLWE (i.e. RLEV) ciphertext and producing an RGSW ciphertext. We generalize the algorithm to allow taking a GLEV ciphertext and producing a GGSW ciphertext.

# Background
Let $\mathcal{R}=\mathbb{Z_q}[X]/(X^N+1)$ for power of two $N$.

Recall that $\mathsf{GLEV}_{\vec{s}}(m)=[ \mathsf{GLWE}(\frac{q}{\beta^1}m), \mathsf{GLWE}(\frac{q}{\beta^2}m), ..., \mathsf{GLWE}(\frac{q}{\beta^\ell}m) ]$ where $\beta$ and $\ell$ are scheme parameters that define a radix decomposition.

Furthermore, recall the gadget product $\odot$ between $a \in \mathcal{R}$ and $\mathsf{GLEV}(m)$:

$$
a \odot \mathsf{GLEV}(m):=\sum_{i=0}^{\ell-1}\mathsf{Decomp}_{i, \beta}(a)\times\mathsf{GLWE}(\frac{q}{\beta^{i+1}}m)
$$
$$
\approx\mathsf{GLWE}(am)
$$

# Scheme switching
## Keygen
Given a GLWE scheme with poly degree $N$ and GLWE size $k$ and secret key $\vec{s}$, define a scheme switching key as follows:

* Let $\mathbf{sk} = \vec{s} \otimes \vec{s}$
* Compute scheme switching key $\mathbf{s_{ss}}$ where $\mathbf{s_{ss}}^{i,j}=\mathsf{GLEV_{\vec{s}}}(\mathbf{sk}_{i,j})$ for $i, j\in [0, k)$.
* Observe that since $\mathbf{sk_{i,j}}=\mathbf{sk_{j, i}}$, we can reduce our keysize by roughly half. Simply store $s_{ss}^{i,j}$ using standard symmetric matrix compression.

## Algorithm
### First, an observation
Suppose we have $(\vec{a}, b) = \mathsf{GLWE}(m)$. Construct trivial GLWE ciphertext $t$ by placing $b$ in the $p$'th place in the basis coefficients and 0 elsewhere $t_p(b)=((0, ..., b, ... 0), 0)$. Observe what happens if we decrypt $t_p(b)$ under any key $\vec{s}$:

$$
m = (\sum_{i \ne p}^{[0, k)}0\cdot s_i + b \cdot s_p) - 0
$$

$$
= b \cdot s_p
$$

Since the error is 0 as well, we can elide the rounding step. Thus, $t$ is a $\mathsf{GLWE}$ encryption of $b \cdot s_p$ under $\vec{s}$.

### Our regularly scheduled program
Given $x=\mathsf{GLEV}(m)$, we have $x_i=\mathsf{GLWE}(\frac{q}{\beta^{i+1}}m)=(\vec{a}^{(i)}, b^{(i)}), i\in[0,\ell_{ggsw})$.

For each $i \in [0, \ell_{ggsw}), j \in [0, k)$ compute using $\mathsf{s_{ss}}^{j,m}$

$$
y_{i, j}=t_j(b^{(i)}) + \sum_{m=0}^{k-1} a^{(i)}_m \odot \mathsf{GLEV}_{\vec{s}}(s_j \cdot s_m)=\mathsf{GLWE}_{\vec{s}}(\sum_{m=0}^{k-1}a^{(i)}_m \cdot s_m \cdot s_j + b^{(i)}\cdot s_j)
$$
$$
=\mathsf{GLWE}_{\vec{s}}((\sum_{m=0}^{k-1}a^{(i)}_m \cdot s_m + b^{(i)})\cdot s_j)
$$
$$
=\mathsf{GLWE}_{\vec{s}}(\frac{q}{\beta^{i+1}}\cdot m \cdot s_j + e_i \cdot s_j)
$$

Note the $e_i$ term is small if $s_j$ is small (i.e. binary), and thus we are left with encryptions of $s_j \cdot m$

Further note, the radix decomposition in the above $\odot$ is $\beta_{ss}, \ell_{ss}$, which may be distinct from $(\beta_{ggsw}, \ell_{ggsw})$

Let $z_j=\mathsf{GLEV}_{\vec{s}}(m \cdot s_j)=(y_{0,j}, y_{1,j}, ..., y_{\ell_{ggsw}-1, j})$

Output $\mathsf{GGSW}_{\vec{s}}(m)=(z_0, z_1, ..., z_{k-1}, x)$
Loading

1 comment on commit 08b1660

@Web5Josh
Copy link

Choose a reason for hiding this comment

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

This is comprehensive

Please sign in to comment.