Skip to content

Commit

Permalink
Support stable Rust with features
Browse files Browse the repository at this point in the history
Update CI to test in stable Rust.
  • Loading branch information
myl7 committed Jul 30, 2024
1 parent 9eb8683 commit a6b473f
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 25 deletions.
13 changes: 8 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@ jobs:
test:
name: Test
runs-on: ubuntu-latest
strategy:
matrix:
toolchain: ['nightly', 'stable']
feat_multi_thread: ['', 'multi-thread']
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.toolchain }}
components: rustfmt, clippy
- name: Format
run: cargo fmt --check
- name: Lint
run: cargo clippy --no-deps -- -Dwarnings
- name: Test with multithreading
run: cargo test
- name: Test without multithreading
run: cargo test --no-default-features -F prg
- name: Test
run: cargo test --no-default-features -F prg,${{ matrix.feat_multi_thread }},$(if [ "${{ matrix.toolchain }}" = "stable" ]; then echo "stable"; fi)
26 changes: 26 additions & 0 deletions Cargo.lock

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

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ keywords = ["crypto", "fss", "dcf", "dpf"]
categories = ["cryptography"]

[features]
default = ["full"]
full = ["prg", "multi-thread"]
default = ["prg", "multi-thread"]
prg = ["aes"]
multi-thread = ["rayon"]
stable = ["wide"]
int-be = []

[dependencies]
bitvec = "1.0.1"
aes = { version = "0.8.3", optional = true }
rayon = { version = "1.7.0", optional = true }
wide = { version = "0.7.26", optional = true }

[dev-dependencies]
rand = { version = "0.8.5", features = ["std", "std_rng"] }
Expand Down
2 changes: 0 additions & 2 deletions rust-toolchain.toml

This file was deleted.

2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

//! Many variable names and the LaTeX math expressions in the doc comment are from the paper _Function Secret Sharing for Mixed-Mode and Fixed-Point Secure Computation_.
#![feature(portable_simd)]
#![cfg_attr(not(feature = "stable"), feature(portable_simd))]

use group::Group;

Expand Down
70 changes: 55 additions & 15 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,76 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2023 Yulong Ming (myl7)

use std::simd::{u8x16, u8x32, u8x64};
#[cfg(not(feature = "stable"))]
use std::simd::{u8x16, u8x32};
#[cfg(feature = "stable")]
use wide::{i8x32, u8x16};

pub fn xor<const BLEN: usize>(xs: &[&[u8; BLEN]]) -> [u8; BLEN] {
let mut res = [0; BLEN];
xor_inplace(&mut res, xs);
res
}

/// # Safety
///
/// Unsafe casting here is safe because:
///
/// - Sizes of `u8` and `i8` are the same.
/// - Rust arrays are compact and contiguous in memory.
/// - Array lengths match here by slicing.
pub fn xor_inplace<const BLEN: usize>(lhs: &mut [u8; BLEN], rhss: &[&[u8; BLEN]]) {
rhss.iter().fold(lhs, |lhs, &rhs| {
assert_eq!(lhs.len(), rhs.len());
let mut i = 0;
while i < BLEN {
let left = BLEN - i;
if left >= 64 {
let lhs_simd = u8x64::from_slice(&lhs[i..i + 64]);
let rhs_simd = u8x64::from_slice(&rhs[i..i + 64]);
lhs[i..i + 64].copy_from_slice((lhs_simd ^ rhs_simd).as_array());
i += 64;
} else if left >= 32 {
let lhs_simd = u8x32::from_slice(&lhs[i..i + 32]);
let rhs_simd = u8x32::from_slice(&rhs[i..i + 32]);
lhs[i..i + 32].copy_from_slice((lhs_simd ^ rhs_simd).as_array());
// if left >= 64 {
// let lhs_simd = u8x64::from_slice(&lhs[i..i + 64]);
// let rhs_simd = u8x64::from_slice(&rhs[i..i + 64]);
// lhs[i..i + 64].copy_from_slice((lhs_simd ^ rhs_simd).as_array());
// i += 64;
// continue;
// }
if left >= 32 {
#[cfg(not(feature = "stable"))]
{
let lhs_simd = u8x32::from_slice(&lhs[i..i + 32]);
let rhs_simd = u8x32::from_slice(&rhs[i..i + 32]);
lhs[i..i + 32].copy_from_slice((lhs_simd ^ rhs_simd).as_array());
}
#[cfg(feature = "stable")]
{
let lhs_simd =
i8x32::from(unsafe { &*(&lhs[i..i + 32] as *const [u8] as *const [i8]) });
let rhs_simd =
i8x32::from(unsafe { &*(&rhs[i..i + 32] as *const [u8] as *const [i8]) });
let res_simd = lhs_simd ^ rhs_simd;
lhs[i..i + 32].copy_from_slice(unsafe {
&*(res_simd.as_array_ref() as *const [i8] as *const [u8])
});
}
i += 32;
} else if left >= 16 {
let lhs_simd = u8x16::from_slice(&lhs[i..i + 16]);
let rhs_simd = u8x16::from_slice(&rhs[i..i + 16]);
lhs[i..i + 16].copy_from_slice((lhs_simd ^ rhs_simd).as_array());
continue;
}
if left >= 16 {
#[cfg(not(feature = "stable"))]
{
let lhs_simd = u8x16::from_slice(&lhs[i..i + 16]);
let rhs_simd = u8x16::from_slice(&rhs[i..i + 16]);
lhs[i..i + 16].copy_from_slice((lhs_simd ^ rhs_simd).as_array());
}
#[cfg(feature = "stable")]
{
let lhs_simd = u8x16::from(&lhs[i..i + 16]);
let rhs_simd = u8x16::from(&rhs[i..i + 16]);
let res_simd = lhs_simd ^ rhs_simd;
lhs[i..i + 16].copy_from_slice(res_simd.as_array_ref());
}
i += 16;
} else {
continue;
}
{
// Since a AES block is 16 bytes, and we usually use AES to construct the PRG,
// no need to specially handle the case where OUT_BLEN % 16 != 0.
// So we just xor them one by one in case wired situations make the program enter here.
Expand Down

0 comments on commit a6b473f

Please sign in to comment.