Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion harness/run_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def main():
print(f"\n [harness] Run {run+1} of {num_runs}")

# 4. Client-side: Generate a new random input using harness/generate_input.py
cmd_args = [str(size),]
cmd_args = [str(size), "--dataset", dataset_name]
if seed is not None:
# Use a different seed for each run but derived from the base seed
rng = np.random.default_rng(seed)
Expand Down
21 changes: 16 additions & 5 deletions harness/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def parse_submission_arguments(workload: str) -> Tuple[int, InstanceParams, int,
help='Specify with 1 if to rerun the cleartext computation')
parser.add_argument('--remote', action='store_true',
help='Run example submission in remote backend mode')
parser.add_argument('--model', default='mlp', type=str,
parser.add_argument('--model', default=None, type=str,
help='Pick a model run (default: mlp)')
parser.add_argument('--dataset', default='mnist', type=str,
help='Pick a dataset run (default: mnist)')
Expand All @@ -64,9 +64,20 @@ def parse_submission_arguments(workload: str) -> Tuple[int, InstanceParams, int,
remote_be = args.remote

# adding model and dataset to the arguments
model_name = args.model.lower()
dataset_name = args.dataset.lower()

# Dataset-specific model defaults
dataset_model_defaults = {
"mnist": "mlp",
"cifar10": "resnet20",
}

# Model selection: use provided model or dataset-specific default
if args.model is None:
model_name = dataset_model_defaults.get(dataset_name, "mlp")
else:
model_name = args.model.lower()

# Use params.py to get instance parameters
params = InstanceParams(size)
return size, params, seed, num_runs, clrtxt, remote_be, model_name, dataset_name
Expand All @@ -81,17 +92,17 @@ def ensure_directories(rootdir: Path):
f"not found in {rootdir}")
sys.exit(1)

def build_submission(script_dir: Path, model_name: str, remote_be: bool):
def build_submission(script_dir: Path, dataset_name: str, remote_be: bool):
"""
Build the submission, including pulling dependencies as neeed
"""
if remote_be:
subprocess.run(["pip", "install", "-r", f"./submission_remote/{model_name}/requirements.txt"], check=True)
subprocess.run(["pip", "install", "-r", f"./submission_remote/{dataset_name}/requirements.txt"], check=True)
else:
# Clone and build OpenFHE if needed
subprocess.run([script_dir/"get_openfhe.sh"], check=True)
# CMake build of the submission itself
subprocess.run([script_dir/"build_task.sh", f"./submissions/{model_name}"], check=True)
subprocess.run([script_dir/"build_task.sh", f"./submissions/{dataset_name}"], check=True)

class TextFormat:
BOLD = "\033[1m"
Expand Down
Binary file not shown.
115 changes: 115 additions & 0 deletions submissions/cifar10/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
cmake_minimum_required(VERSION 3.14)
project(add_resnet20 LANGUAGES CXX)

# ---------------------------------------------------------------
# 1. Compiler / flags
# --------------------------------------------------------------------
set(CMAKE_CXX_STANDARD 17)
# set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# add_compile_options(-O3 -Wall -Wextra -Wno-unused-parameter)
option( BUILD_STATIC "Set to ON to include static versions of the library" OFF)

# --------------------------------------------------------------------
# 2. Find the OpenFHE *package* that the install script put into
# third_party/openfhe
# --------------------------------------------------------------------
# scripts/get_openfhe.sh installs:
# third_party/openfhe/lib/cmake/OpenFHE/OpenFHEConfig.cmake

find_package(OpenFHE CONFIG REQUIRED)
if (OpenFHE_FOUND)
message(STATUS "FOUND PACKAGE OpenFHE")
message(STATUS "OpenFHE Version: ${BASE_OPENFHE_VERSION}")
message(STATUS "OpenFHE installed as shared libraries: ${OpenFHE_SHARED}")
message(STATUS "OpenFHE include files location: ${OpenFHE_INCLUDE}")
message(STATUS "OpenFHE lib files location: ${OpenFHE_LIBDIR}")
message(STATUS "OpenFHE Native Backend size: ${OpenFHE_NATIVE_SIZE}")
else()
message(FATAL_ERROR "PACKAGE OpenFHE NOT FOUND")
endif ()

set( CMAKE_CXX_FLAGS "${OpenFHE_CXX_FLAGS} -Werror")

# --------------------------------------------------------------------
# 3. Link libraries
# --------------------------------------------------------------------

include_directories( ${OPENMP_INCLUDES} )
include_directories( ${OpenFHE_INCLUDE} )
include_directories( ${OpenFHE_INCLUDE}/third-party/include )
include_directories( ${OpenFHE_INCLUDE}/core )
include_directories( ${OpenFHE_INCLUDE}/pke )
include_directories( ${OpenFHE_INCLUDE}/binfhe )
### add directories for other OpenFHE modules as needed for your project

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/fheon)

link_directories( ${OpenFHE_LIBDIR} )
link_directories( ${OPENMP_LIBRARIES} )

# set(CMAKE_SKIP_BUILD_RPATH FALSE)
# set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF)
# set(CMAKE_BUILD_RPATH "${OpenFHE_LIBDIR}")
# set(CMAKE_INSTALL_RPATH "${OpenFHE_LIBDIR}")
# set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
add_link_options(-Wl,--no-as-needed)

# These should take care of setting the correct LD path without manually setting LD_LIBRARY_PATH.
# But if a shared library or symbol lookup error occurs, you need to set the LD_LIBRARY_PATH environment
# to the OpenFHE lib directory: export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/path/to/OpenFHE/lib

if(BUILD_STATIC)
set( CMAKE_EXE_LINKER_FLAGS "${OpenFHE_EXE_LINKER_FLAGS} -static")
link_libraries( ${OpenFHE_STATIC_LIBRARIES} )
message(STATUS "Build with static libs")
else()
set( CMAKE_EXE_LINKER_FLAGS ${OpenFHE_EXE_LINKER_FLAGS} )
link_libraries( ${OpenFHE_SHARED_LIBRARIES} )
endif()

# --------------------------------------------------------------------
# 4. Create mlp library
# --------------------------------------------------------------------
add_library( fheonhecontroller ../fheon/FHEONHEController.cpp )
target_include_directories( fheonhecontroller PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/fheon )
add_library( fheonanncontroller ../fheon/FHEONANNController.cpp )
target_include_directories( fheonanncontroller PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/fheon )

#-----------------------------------------------------------------------
# Create the FHEON Libraries
#------------------------------------------------------------------------
add_library( encryption_utils src/encryption_utils.cpp )
target_include_directories( encryption_utils PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include )

# Use pre-built mlp_openfhe library
add_library( mlp_openfhe STATIC IMPORTED )
set_target_properties( mlp_openfhe PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../pre-built-library/libmlp_openfhe.a )

# --------------------------------------------------------------------
# 5. Each *.cpp file becomes its own executable.
# The seven stage names are hard-wired by the benchmark contract.
# --------------------------------------------------------------------

add_executable( client_key_generation src/client_key_generation.cpp )
target_link_libraries( client_key_generation fheonanncontroller )
target_link_libraries( client_key_generation fheonhecontroller )

add_executable( client_preprocess_input src/client_preprocess_input.cpp )

add_executable( client_encode_encrypt_input src/client_encode_encrypt_input.cpp )
target_link_libraries( client_encode_encrypt_input encryption_utils )

add_executable( client_decrypt_decode src/client_decrypt_decode.cpp )
target_link_libraries( client_decrypt_decode encryption_utils )

add_executable( client_postprocess src/client_postprocess.cpp )

add_executable( server_preprocess_model src/server_preprocess_model.cpp )

add_executable( server_encrypted_compute src/server_encrypted_compute.cpp src/resnet20_fheon.cpp )
target_link_libraries( server_encrypted_compute mlp_openfhe)
target_link_libraries( server_encrypted_compute encryption_utils )
target_link_libraries( server_encrypted_compute fheonhecontroller )
target_link_libraries( server_encrypted_compute fheonanncontroller )
target_compile_definitions(server_encrypted_compute PRIVATE WEIGHTS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/weights/resnet20/")
47 changes: 47 additions & 0 deletions submissions/cifar10/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# ResNet-20: Privacy-Preserving Encrypted Inference

This submission implements a ResNet-20 deep residual network using the FHEON framework for privacy-preserving machine learning inference on CIFAR-10 images.

## Overview

ResNet-20 is a deep residual network designed to classify 3×32×32 RGB images from the CIFAR-10 dataset using Fully Homomorphic Encryption (FHE). This implementation uses the FHEON framework built on top of OpenFHE.

## FHEON Framework

**FHEON** is a configurable framework designed to facilitate the implementation of privacy-preserving neural network inference using FHE. Built on top of OpenFHE, FHEON provides high-level abstractions for common deep learning components while optimizing for the unique constraints of homomorphic computation.

For more information, visit the [official website](https://fheon.pqcsecure.org/), explore the [source code](https://github.com/stamcenter/fheon), or read the [research paper](https://arxiv.org/abs/2510.03996).

## Model Architecture: ResNet-20

A deep residual network targeting CIFAR-10 built using FHEON.

- **Architecture**: Initial convolution, three stages of ResNet blocks with shortcuts, and Global Average Pooling.
- **Dataset**: CIFAR-10
- **Bootstrapping**: Strategic integration of CKKS bootstrapping to maintain circuit depth.
- **Implementation**: `submissions/resnet20/src/resnet20_fheon.cpp`

---

## Security Level

ResNet-20 is configured to satisfy the **128-bit security level** using the standardized parameters for CKKS as defined in the [Homomorphic Encryption Standard v1.1](https://homomorphicencryption.org/wp-content/uploads/2018/11/HomomorphicEncryptionStandardv1.1.pdf).

### CKKS Parameters
- **Ciphertexts depth**: 29
- **log PQ**: 708
- **Cyclotomic Order**: 131072
- **Ring dimension**: 65536
- **Number of Slots**: 32768


## Performance Optimization

The `client_key_generation` utilities provide equivalent ring dimensions and slot counts that target smaller security levels. These configurations are designed to significantly improve computation speed and reduce memory overhead, consistent with the performance benchmarks presented in the FHEON research paper.

---

### Execution Paths
The inference executables typically expect external weights and keys provided at runtime:
- **Weights**: `submissions/<model_name>/weights/`
- **Keys**: Generated and managed via model-specific `client_key_generation` utilities.
Loading