Skip to content

Commit

Permalink
init: add src files and build for v0.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
muqsitnawaz committed Apr 27, 2024
0 parents commit 844d146
Show file tree
Hide file tree
Showing 25 changed files with 3,169 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# IDE.
.idea/

# Build
bin
lib
cmake-build-debug/
build/
CMakeFiles/
Makefile
CMakeCache.txt
cmake_install.cmake

# Logs.
logs/*

# Docs.
docs/html/
docs/latex/
53 changes: 53 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
cmake_minimum_required(VERSION 3.10)

project(fss)

if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif ()

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED on)

add_compile_options(-Wall -Wextra -g -Ofast)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")

set(BUILD_SHARED_LIBS OFF)
set(DCMAKE_EXE_LINKER_FLAGS "-static")

set(OPENSSL_USE_STATIC_LIBS TRUE)
find_package(OpenSSL REQUIRED)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)

set(INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")

set(FSS_SRC_FILES
include/fss/seal/uintarith.cpp
include/fss/seal/smallmodulus.cpp
include/fss/expandingprf.cpp
include/fss/fsscontext.cpp
include/fss/fssevaluator.cpp
include/fss/fssgenerator.cpp
)

set(COMMON_SRC_FILES ${FSS_SRC_FILES})

add_executable(fss_example ${COMMON_SRC_FILES} src/fss_example.cpp)
target_link_libraries(fss_example PRIVATE OpenSSL::Crypto)
target_include_directories(fss_example PRIVATE ${INC_DIR})

add_library(fss ${FSS_SRC_FILES})
target_link_libraries(fss PRIVATE OpenSSL::Crypto)
target_include_directories(fss PUBLIC ${INC_DIR})

install(TARGETS fss
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib)

install(DIRECTORY ${INC_DIR}/fss
DESTINATION include
FILES_MATCHING PATTERN "*.hpp")
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Muqsit Nawaz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# FSS

FSS implements a two-party Function Secret Sharing protocol that allows non-colluding parties to execute a function
without knowing the original inputs of the user.

The inputs and the function are secret shared between the parties making it information therotic secure against an
adversary (given the non-colluding assumption).

## Theory

- [Function Secret Sharing](https://cs.idc.ac.il/~elette/FunctionSecretSharing.pdf)
- [Function Secret Sharing: Improvements and Extensions](https://eprint.iacr.org/2018/707.pdf)

## Applications

- [Pika: Secure Computation
using Function Secret Sharing over Rings](https://petsymposium.org/popets/2022/popets-2022-0113.pdf)

## Dependencies

```bash
brew install openssl
```

## Installation

```bash
cmake -S .. -B build
cd build
make
sudo make install
```

This will install the library at `/usr/local/include/fss`.

## Usage

```cpp
#include <fss/fssgenerator.hpp>
#include <fss/fssevaluator.hpp>

FSSGenerator generator(fss_context);

ReLUKey key_s0, key_s1;
generator.relu(key_s0, key_s1);

FSSEvaluator evaluator1(fss_context, 0);
FSSEvaluator evaluator2(fss_context, 1);
```
## License
[MIT License](LICENSE)
60 changes: 60 additions & 0 deletions include/fss/common.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

#pragma once

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/rand.h>

#include <fss/openssl-aes.h>

namespace fss {
/**
* @returns The bit at desired position from the given input.
*
* @param n The number to extract bit from.
* @param pos The position of the desired bit.
*/
inline uint64_t get_bit(uint64_t n, uint64_t pos) noexcept {
return (n & (((uint64_t) 1) << (64 - pos))) >> (64 - pos);
}

/**
* @returns The 128-bit unsigned number corresponding to the given byte array.
*
* @param arr The given array of bytes.
*/
inline uint64_t byte_array_to_integer(const u_char *arr) noexcept {
uint64_t i = ((uint64_t) arr[7] << 56u) | ((uint64_t) arr[6] << 48u) |
((uint64_t) arr[5] << 40u) | ((uint64_t) arr[4] << 32u) |
((uint64_t) arr[3] << 24u) | ((uint64_t) arr[2] << 16u) |
((uint64_t) arr[1] << 8u) | ((uint64_t) arr[0]);
return i;
}

/**
* @returns The closest power of 2 greater than or equal to the given number.
*/
inline uint64_t fast_floor_log2(uint64_t n) {
uint64_t count = 0;

if (n && !(n & (n - 1))) {
while (n != 1) {
n >>= 1u;
count += 1;
}
return count;
}

while (n != 0) {
n >>= 1u;
count += 1;
}

return count;
}
}
19 changes: 19 additions & 0 deletions include/fss/expandingprf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

#include "expandingprf.hpp"

namespace fss {
void ExpandingPRF::generate(u_char *key, size_t input_size, u_char *out) {
// Run PRNG for the given input_size.
size_t num_keys_required = input_size / 16;
for (size_t i = 0; i < num_keys_required; i++) {
#ifndef AESNI
AES_encrypt(key, out + (i * 16), &aes_keys_[i]);
#else
aesni_encrypt(key, out + (i * 16), &aes_keys_[i]);
#endif
}
for (size_t i = 0; i < input_size; i++) {
out[i] = out[i] ^ key[i % 16];
}
}
}
40 changes: 40 additions & 0 deletions include/fss/expandingprf.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

#pragma once

#include <fss/fsscontext.hpp>

namespace fss {
class ExpandingPRF {
public:
/**
* Constructs an ExpandingPRF instance with the given FSSContext.
*
* @param fss_context The given FSSContext.
*/
explicit ExpandingPRF(const std::shared_ptr<FSSContext> &fss_context) {
// Verify parameters.
if (!fss_context) {
throw std::invalid_argument("Invalid FSSContext.");
}

// Copy over AESKeys from FSSContext.
auto expansion_factor = fss_context->prf_expansion_factor();
aes_keys_ = (AES_KEY *) malloc(sizeof(AES_KEY) * expansion_factor);
for (size_t i = 0; i < expansion_factor; ++i) {
aes_keys_[i] = fss_context->aes_key(i);
}
}

/**
* Implements an expanding pseudorandom function.
*
* @param[in] input_size The size of input.
* @param[in] key The pointer to PRF key.
* @param[out] out The pointer to output.
*/
void generate(u_char *key, size_t input_size, u_char *out);

private:
AES_KEY *aes_keys_{nullptr};
};
}
27 changes: 27 additions & 0 deletions include/fss/fsscontext.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

#include "fsscontext.hpp"

namespace fss {
FSSContext::FSSContext(uint64_t p, uint8_t scaling, bool to_generate_keys) {
num_bits_ = fast_floor_log2(p) + 1;
plain_modulus_ = SmallModulus(p);
scaling_ = scaling;

aes_keys_ = (AES_KEY *) malloc(sizeof(AES_KEY) * prf_expansion_factor_);

if (to_generate_keys) {
// Initialize keys for Matyas–Meyer–Oseas one-way compression function
for (size_t i = 0; i < prf_expansion_factor_; i++) {
u_char rand_bytes[16];
if (!RAND_bytes(rand_bytes, 16)) {
throw std::runtime_error("Random bytes failed.");
}
#ifndef AESNI
AES_set_encrypt_key(rand_bytes, 128, &(aes_keys_[i]));
#else
aesni_set_encrypt_key(rand_bytes, 128, &(f->aes_keys[i]));
#endif
}
}
}
}
85 changes: 85 additions & 0 deletions include/fss/fsscontext.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@

#pragma once

#include <cstdint>
#include <memory>
#include <exception>

#include <openssl/rand.h>
#include <openssl/aes.h>

#include "seal/smallmodulus.hpp"

#include <fss/common.hpp>

using namespace seal;

namespace fss {
class FSSContext {
public:
/**
* @returns A std::shared_ptr to FSSContext.
*/
static auto Create(uint64_t plain_modulus, uint8_t frac_bits_count, bool to_generate_keys = true) {
return std::shared_ptr<FSSContext>(new FSSContext(plain_modulus, frac_bits_count, to_generate_keys));
}

/**
* Sets the AES_Key at given index.
*/
inline void set_aes_key(size_t index, AES_KEY aes_key) const {
if (index > prf_expansion_factor_ - 1) {
throw std::invalid_argument("Index must be within [0, PRF_EXPANSION_FACTOR).");
}
aes_keys_[index] = aes_key;
}

[[nodiscard]] inline auto num_bits() const noexcept {
return num_bits_;
}

[[nodiscard]] inline auto scaling() const noexcept {
return scaling_;
}

[[nodiscard]] inline auto &plain_modulus() const noexcept {
return plain_modulus_;
}

[[nodiscard]] inline auto prf_expansion_factor() const noexcept {
return prf_expansion_factor_;
}

[[nodiscard]] inline auto &aes_key(size_t index) {
if (index > prf_expansion_factor_ - 1) {
throw std::invalid_argument("Index must be within [0, PRF_EXPANSION_FACTOR).");
}
return aes_keys_[index];
}

[[nodiscard]] inline const auto &aes_key(size_t index) const {
if (index > prf_expansion_factor_ - 1) {
throw std::invalid_argument("Index must be within [0, PRF_EXPANSION_FACTOR).");
}
return aes_keys_[index];
}

/*
* Delete unnecessary members.
*/
FSSContext() = delete;

private:
FSSContext(uint64_t p, uint8_t scaling, bool to_generate_keys);

AES_KEY *aes_keys_;

uint32_t num_bits_ = 0;

uint8_t scaling_ = 0;

SmallModulus plain_modulus_ = 0;

const size_t prf_expansion_factor_ = 8;
};
}
Loading

0 comments on commit 844d146

Please sign in to comment.