Skip to content
Draft
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
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Build output
/build/
/build-*/

# CMake rdseed probe leftover (written to the source dir on Linux)
/rdseedtest.c

# Ferret precomputed OT cache (created at runtime when run from the repo root)
/ALICE_pre_ot_data/
/BOB_pre_ot_data/

# Local Claude Code guidance, not part of the project
/CLAUDE.md

# OS / editor cruft
.DS_Store
20 changes: 16 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
cmake_minimum_required (VERSION 3.3.2)
cmake_minimum_required (VERSION 3.5)

project (NumSeC)
set(NAME "NumSeC")

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Platform/arch detection, reused below and in src/.
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$")
set(NSC_ARCH_ARM TRUE)
else()
set(NSC_ARCH_ARM FALSE)
endif()
set(NSC_IS_APPLE ${APPLE})

# MATCHES catches both "Clang" and "AppleClang".
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-w)
endif()

Expand All @@ -15,6 +24,11 @@ message(STATUS "Option: NSC_USE_LFSR = ${NSC_USE_LFSR}")
option(NSC_USE_KKOT "Use KKOT instead of Ferret" OFF)
message(STATUS "Option: NSC_USE_KKOT = ${NSC_USE_KKOT}")

if(NSC_USE_KKOT AND NSC_ARCH_ARM)
message(FATAL_ERROR "NSC_USE_KKOT=ON is unsupported on Apple Silicon / arm64: "
"src/extern/SecFloatOTPack is x86-only. Leave NSC_USE_KKOT=OFF.")
endif()

option(NSC_BUILD_CTRACK "Build CTRACK dependency (optional)" OFF)
message(STATUS "Option: BUILD_CTRACK = ${NSC_BUILD_CTRACK}")

Expand Down Expand Up @@ -52,8 +66,6 @@ if (NSC_BUILD_TESTS)
add_subdirectory(tests)
endif()

add_compile_options(-march=native)


set(INSTALL_DIR "${CMAKE_INSTALL_PREFIX}")
set(BUILD_DIR "${PROJECT_SOURCE_DIR}/build")
38 changes: 34 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,68 @@ NumSeC is a C++17 library implementing floating point arithmetic in the framewor

## Supported OSs
- Linux
- macOS (Apple Silicon / arm64)

## Required Packages
- g++ (version >= 11)
- cmake (version >= 3.3.2)
- OpenSSL
- g++ (version >= 11) on Linux, or Apple clang (Xcode Command Line Tools) on macOS
- cmake (version >= 3.5)
- OpenSSL (Homebrew `openssl@3` on macOS)
- [emp-toolkit/emp-tool](https://github.com/emp-toolkit/emp-tool)
- [emp-toolkit/emp-ot](https://github.com/emp-toolkit/emp-ot)

Build emp-tool and emp-ot from the `0.3.0` tag. Later versions move Ferret to
`ot_extension/` and drop the `emp-ot/ferret/ferret_cot.h` API that NumSeC uses.

## Compilation

### Linux

To compile the library just run the bash script `compile-linux.sh` at the parent folder:

```
./compile-linux.sh
```

### macOS (Apple Silicon)

emp-tool and emp-ot have no macOS package, so build them first and install into a prefix
`compile-macos.sh` can find (here `~/.local`):

```
brew install cmake openssl@3 git
for repo in emp-tool emp-ot; do
git clone --branch 0.3.0 https://github.com/emp-toolkit/$repo.git
cmake -S $repo -B $repo/build -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$HOME/.local" \
-DCMAKE_PREFIX_PATH="$(brew --prefix);$HOME/.local" \
-DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)"
cmake --build $repo/build --target install -j
done
```

Then run `./compile-macos.sh`. Set `EMP_PREFIX` if you installed emp somewhere other than `~/.local`.

On successful compilation, the test binaries will be created in `build/bin/`. The libraries will be created in `build/lib/`.

## Running Unit Tests

To execute the unit tests just run the bash script `unit-tests-linux.sh` at the parent folder:
To execute the unit tests just run the bash script `unit-tests-linux.sh` at the parent folder
(it runs unchanged on macOS):

```
./unit-tests-linux.sh
```

It runs both parties on localhost. Optional positional arguments set the operation, RNG seed,
and batch size; the batch size must be at least 100.

# Acknowledgements

This library includes code from the following external repositories:

- [emp-toolkit/emp-tool](https://github.com/emp-toolkit/emp-tool) for cryptographic tools and network I/O.
- [emp-toolkit/emp-ot](https://github.com/emp-toolkit/emp-ot) for implementation of the [Ferret](https://eprint.iacr.org/2020/924) protocol for random correlated OT.
- [DLTcollab/sse2neon](https://github.com/DLTcollab/sse2neon) (MIT License) for mapping x86 SSE intrinsics to ARM NEON on Apple Silicon.

# License

Expand Down
16 changes: 16 additions & 0 deletions compile-macos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -e

# Build NumSeC on macOS (Apple Silicon). Architecture flags are selected by CMake;
# this script only supplies dependency locations.
# OpenSSL: Homebrew keg-only openssl@3
# emp-tool / emp-ot: installed prefix (default ~/.local; override with EMP_PREFIX)
EMP_PREFIX="${EMP_PREFIX:-$HOME/.local}"

mkdir -p build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=./install \
-DCMAKE_BUILD_TYPE=Release \
-DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)" \
-DCMAKE_PREFIX_PATH="$(brew --prefix);${EMP_PREFIX}"
cmake --build . --target install --parallel
48 changes: 32 additions & 16 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(cmake/source_of_randomness.cmake)

#find_package(GMP REQUIRED)
# Homebrew keeps openssl@3 keg-only; point FindOpenSSL at it on macOS.
if(NSC_IS_APPLE AND NOT DEFINED OPENSSL_ROOT_DIR)
execute_process(COMMAND brew --prefix openssl@3
OUTPUT_VARIABLE OPENSSL_ROOT_DIR OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
endif()
find_package(OpenSSL REQUIRED)

find_package(emp-tool REQUIRED)
Expand All @@ -17,35 +23,45 @@ endif()
add_library(NSC ${NSC_LIBRARY_TYPE} nsc-tables.cpp nsc-tool.cpp nsc-core.cpp nsc-reveal.cpp nsc.cpp
nsc-extra.cpp)

#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -msse4.1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -std=c++17 -march=native -msse4.2 -mavx -mavx2 -mavx512f -mpclmul -pthread -faligned-new -fPIC -no-pie -O3")

target_compile_options(NSC
INTERFACE
-std=c++17 -march=native -Wno-parentheses-equality
-Wno-ignored-attributes -Wno-deprecated-declarations -Wno-format
-maes -msse4.2 -mavx -mavx2 -mavx512f -mpclmul
-fPIC -no-pie
-O3
-Wno-macro-redefined -pthread -faligned-new
# Portable flags for every platform.
set(NSC_COMMON_FLAGS
-std=c++17 -O3 -pthread -faligned-new -fPIC
-Wno-parentheses-equality -Wno-ignored-attributes
-Wno-deprecated-declarations -Wno-format -Wno-macro-redefined
)

if(NSC_ARCH_ARM)
# Apple Silicon: NEON is baseline, no x86 ISA flags. emp maps SSE via sse2neon.
set(NSC_ARCH_FLAGS -mcpu=native)
else()
# Linux/x86 (and Intel mac): the original x86 flags.
set(NSC_ARCH_FLAGS
-march=native -maes -msse4.2 -mavx -mavx2 -mavx512f -mpclmul -no-pie)
endif()

# PUBLIC applies to NSC's own sources and propagates to consumers (unit-tests).
target_compile_options(NSC PUBLIC ${NSC_COMMON_FLAGS} ${NSC_ARCH_FLAGS})

# PUBLIC so NSC's own sources (which include emp's prg.h) also get the define.
if(USE_RANDOM_DEVICE)
target_compile_definitions(NSC INTERFACE EMP_USE_RANDOM_DEVICE=1)
target_compile_definitions(NSC PUBLIC EMP_USE_RANDOM_DEVICE=1)
else(USE_RANDOM_DEVICE)
target_compile_options(NSC INTERFACE "-mrdseed")
target_compile_options(NSC PUBLIC "-mrdseed")
endif(USE_RANDOM_DEVICE)

target_include_directories(NSC INTERFACE
# emp-tool's config exports plain variables (not an imported target), so wire its
# include and library dirs explicitly; emp can then live in any prefix, not just
# a default one. EMP-TOOL_INCLUDE_DIRS / EMP-TOOL_LIBRARIES already fold in OpenSSL.
target_include_directories(NSC PUBLIC
#${GMP_INCLUDE_DIR}
${EMP-TOOL_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
)

target_link_libraries(NSC
#${GMP_LIBRARIES}
${EMP-TOOL_LIBRARIES}
${OPENSSL_LIBRARIES}
emp-tool
#emp-ot
)

if (NSC_BUILD_CTRACK)
Expand Down
56 changes: 32 additions & 24 deletions src/cmake/source_of_randomness.cmake
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
OPTION(USE_RANDOM_DEVICE "Option description" OFF)
set(CMAKE_C_FLAGS "-mrdseed")
OPTION(USE_RANDOM_DEVICE "Use std::random_device instead of x86 rdseed" OFF)

# Use rdseed if available
unset(RDSEED_COMPILE_RESULT CACHE)
unset(RDSEED_RUN_RESULT CACHE)
file(WRITE ${CMAKE_SOURCE_DIR}/rdseedtest.c "#include <stdio.h>\n#include <x86intrin.h>\nint main(){\nunsigned long long r;\n_rdseed64_step(&r);\nreturn 0;\n}\n")
try_run(RDSEED_RUN_RESULT RDSEED_COMPILE_RESULT ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/rdseedtest.c CMAKE_FLAGS ${CMAKE_C_FLAGS})
file(REMOVE ${CMAKE_SOURCE_DIR}/rdseedtest.c)
if(NSC_ARCH_ARM OR NSC_IS_APPLE)
# No x86 RDSEED on Apple / arm64: force random_device and skip the probe
# (x86intrin.h / _rdseed64_step / -mrdseed do not exist here).
set(USE_RANDOM_DEVICE ON)
message("-- Source of Randomness: random_device (Apple/arm64)")
else()
set(CMAKE_C_FLAGS "-mrdseed")

cmake_policy(SET CMP0012 NEW)
IF(NOT ${RDSEED_COMPILE_RESULT})
set(USE_RANDOM_DEVICE ON)
ELSE(NOT ${RDSEED_COMPILE_RESULT})
string(COMPARE EQUAL "${RDSEED_RUN_RESULT}" "0" RDSEED_RUN_SUCCESS)
IF(NOT ${RDSEED_RUN_SUCCESS})
set(USE_RANDOM_DEVICE ON)
ELSE(NOT ${RDSEED_RUN_SUCCESS})
set(USE_RANDOM_DEVICE OFF)
ENDIF(NOT ${RDSEED_RUN_SUCCESS})
ENDIF(NOT ${RDSEED_COMPILE_RESULT})
# Use rdseed if available
unset(RDSEED_COMPILE_RESULT CACHE)
unset(RDSEED_RUN_RESULT CACHE)
file(WRITE ${CMAKE_SOURCE_DIR}/rdseedtest.c "#include <stdio.h>\n#include <x86intrin.h>\nint main(){\nunsigned long long r;\n_rdseed64_step(&r);\nreturn 0;\n}\n")
try_run(RDSEED_RUN_RESULT RDSEED_COMPILE_RESULT ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/rdseedtest.c CMAKE_FLAGS ${CMAKE_C_FLAGS})
file(REMOVE ${CMAKE_SOURCE_DIR}/rdseedtest.c)

IF(${USE_RANDOM_DEVICE})
message("${Red}-- Source of Randomness: random_device${ColourReset}")
ELSE(${USE_RANDOM_DEVICE})
message("${Green}-- Source of Randomness: rdseed${ColourReset}")
ENDIF(${USE_RANDOM_DEVICE})
cmake_policy(SET CMP0012 NEW)
IF(NOT ${RDSEED_COMPILE_RESULT})
set(USE_RANDOM_DEVICE ON)
ELSE(NOT ${RDSEED_COMPILE_RESULT})
string(COMPARE EQUAL "${RDSEED_RUN_RESULT}" "0" RDSEED_RUN_SUCCESS)
IF(NOT ${RDSEED_RUN_SUCCESS})
set(USE_RANDOM_DEVICE ON)
ELSE(NOT ${RDSEED_RUN_SUCCESS})
set(USE_RANDOM_DEVICE OFF)
ENDIF(NOT ${RDSEED_RUN_SUCCESS})
ENDIF(NOT ${RDSEED_COMPILE_RESULT})

IF(${USE_RANDOM_DEVICE})
message("${Red}-- Source of Randomness: random_device${ColourReset}")
ELSE(${USE_RANDOM_DEVICE})
message("${Green}-- Source of Randomness: rdseed${ColourReset}")
ENDIF(${USE_RANDOM_DEVICE})
endif()
Loading