Skip to content

Commit

Permalink
Saving work 1
Browse files Browse the repository at this point in the history
  • Loading branch information
dsuponitskiy-duality committed Oct 2, 2024
1 parent 85a8f63 commit 30422b6
Show file tree
Hide file tree
Showing 14 changed files with 330 additions and 180 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/third-party/google-test/googlet
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/third-party/google-test/googletest/include )
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/src/core/include )
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/src/binfhe/include )
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/prng_libs )

include_directories( ${CMAKE_CURRENT_BINARY_DIR}/src/core )

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,18 @@
#ifndef _SRC_LIB_UTILS_BLAKE2ENGINE_H
#define _SRC_LIB_UTILS_BLAKE2ENGINE_H

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <array>
#include <limits>

#include "prng.h"
#include "blake2.h"

#include "utils/exception.h"
#include <stdexcept>
#include <array>
#include <limits>
#include <memory>
#include <cstdint>
#include <chrono>
#include <thread>
#include <random>

namespace lbcrypto {

// the buffer stores 1024 samples of 32-bit integers
const uint32_t PRNG_BUFFER_SIZE = 1024;
Expand All @@ -56,56 +57,38 @@ const uint32_t PRNG_BUFFER_SIZE = 1024;
* @brief Defines the PRNG engine used by OpenFHE. It is based on BLAKE2. Use
* this as a template for adding other PRNG engines to OpenFHE.
*/
class Blake2Engine {
class Blake2Engine : public PRNG {
public:
// all C++11 distributions used in OpenFHE work by default with uint32_t
// a different data type can be specified if needed for a particular
// architecture
using result_type = uint32_t;
enum {MAX_SEED_GENS = 16};

/**
* @brief Constructor using a small seed - used for generating a large seed
*/
explicit Blake2Engine(result_type seed)
: m_counter(0), m_buffer({}), m_bufferIndex(0) {
explicit Blake2Engine(PRNG::result_type seed)
: PRNG(seed), m_counter(0), m_buffer({}), m_bufferIndex(0) {
m_seed[0] = seed;
}

/**
* @brief Main constructor taking a vector of 16 integers as a seed
*/
explicit Blake2Engine(const std::array<result_type, 16>& seed)
: m_counter(0), m_seed(seed), m_buffer({}), m_bufferIndex(0) {}
// TODO (dsuponit): commented the constructor below and added a default paramter value to the next contructor
// /**
// * @brief Main constructor taking a vector of MAX_SEED_GENS integers as a seed
// */
// explicit Blake2Engine(const std::array<PRNG::result_type, MAX_SEED_GENS>& seed)
// : m_counter(0), m_seed(seed), m_buffer({}), m_bufferIndex(0) {}

/**
* @brief Main constructor taking a vector of 16 integers as a seed and a
* @brief Main constructor taking a vector of MAX_SEED_GENS integers as a seed and a
* counter
*/
explicit Blake2Engine(const std::array<result_type, 16>& seed,
result_type counter)
explicit Blake2Engine(const std::array<PRNG::result_type, MAX_SEED_GENS>& seed,
PRNG::result_type counter = 0)
: m_counter(counter), m_seed(seed), m_buffer({}), m_bufferIndex(0) {}

/**
* @brief minimum value used by C+11 distribution generators when no lower
* bound is explicitly specified by the user
*/
static constexpr result_type min() {
return std::numeric_limits<result_type>::min();
}

/**
* @brief maximum value used by C+11 distribution generators when no upper
* bound is explicitly specified by the user
*/
static constexpr result_type max() {
return std::numeric_limits<result_type>::max();
}

/**
* @brief main call to the PRNG
*/
result_type operator()() {
result_type result;
PRNG::result_type operator()() override {
PRNG::result_type result;

if (m_bufferIndex == PRNG_BUFFER_SIZE) m_bufferIndex = 0;

Expand Down Expand Up @@ -142,10 +125,10 @@ class Blake2Engine {
void Generate() {
// m_counter is the input to the hash function
// m_buffer is the output
if (blake2xb(m_buffer.begin(), m_buffer.size() * sizeof(result_type),
if (blake2xb(m_buffer.begin(), m_buffer.size() * sizeof(PRNG::result_type),
&m_counter, sizeof(m_counter), m_seed.cbegin(),
m_seed.size() * sizeof(result_type)) != 0) {
OPENFHE_THROW("PRNG: blake2xb failed");
m_seed.size() * sizeof(PRNG::result_type)) != 0) {
throw std::runtime_error("PRNG: blake2xb failed");
}
m_counter++;
return;
Expand All @@ -156,16 +139,64 @@ class Blake2Engine {
uint64_t m_counter = 0;

// the seed for the BLAKE2 hash function
std::array<result_type, 16> m_seed{};
std::array<PRNG::result_type, MAX_SEED_GENS> m_seed{};

// The vector that stores random samples generated using the hash function
std::array<result_type, PRNG_BUFFER_SIZE> m_buffer{};
std::array<PRNG::result_type, PRNG_BUFFER_SIZE> m_buffer{};

// Index in m_buffer corresponding to the current PRNG sample
uint16_t m_bufferIndex = 0;
};

} // namespace lbcrypto
// the code calling createEngineInstance() should clean the memory allocated by createEngineInstance()
// TODO (dsuponit): check with Jack if createEngineInstance() can return an object instead of a pointer. We can do it
// for Blake2Engine
extern "C" {
Blake2Engine* createEngineInstance();
}
// extern "C" Blake2Engine* createEngineInstance() {
// // initialization of PRNGs
// constexpr size_t maxGens = Blake2Engine::MAX_SEED_GENS;
// #pragma omp critical
// std::array<uint32_t, maxGens> initKey{};
// initKey[0] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
// initKey[1] = std::hash<std::thread::id>{}(std::this_thread::get_id());
// #if !defined(__arm__) && !defined(__EMSCRIPTEN__)
// if (sizeof(size_t) == 8)
// initKey[2] = (std::hash<std::thread::id>{}(std::this_thread::get_id()) >> 32);
// #endif
// void* mem = malloc(1);
// uint32_t counter = reinterpret_cast<long long>(mem); // NOLINT
// free(mem);

// Blake2Engine gen(initKey, counter);

// std::uniform_int_distribution<uint32_t> distribution(0);
// std::array<uint32_t, maxGens> seed{};
// for (uint32_t i = 0; i < maxGens; i++) {
// seed[i] = distribution(gen);
// }

// std::array<uint32_t, maxGens> rdseed{};
// size_t attempts = 3;
// bool rdGenPassed = false;
// for(size_t i = 0; i < attempts && !rdGenPassed; ++i) {
// try {
// std::random_device genR;
// for (uint32_t i = 0; i < maxGens; i++) {
// rdseed[i] = distribution(genR);
// }
// rdGenPassed = true;
// }
// catch (std::exception& e) {
// }
// }
// for (uint32_t i = 0; i < maxGens; i++) {
// seed[i] += rdseed[i];
// }

// return new Blake2Engine(seed);
// }

#endif
// clang-format on
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
#include <string.h>
#include <stdio.h>

#include "utils/prng/blake2.h"
#include "utils/prng/blake2-impl.h"
#include "blake2.h"
#include "blake2-impl.h"

static const uint64_t blake2b_IV[8] = {
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
Expand Down
57 changes: 57 additions & 0 deletions prng_libs/blake2_lib/lib/blake2engine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//==================================================================================
// © 2024 Duality Technologies, Inc. All rights reserved.
// This is a proprietary software product of Duality Technologies, Inc.
// protected under copyright laws and international copyright treaties, patent
// law, trade secret law and other intellectual property rights of general
// applicability. Any use of this software is strictly prohibited absent a
// written agreement executed by Duality Technologies, Inc., which provides
// certain limited rights to use this software. You may not copy, distribute,
// make publicly available, publicly perform, disassemble, de-compile or reverse
// engineer any part of this software, breach its security, or circumvent,
// manipulate, impair or disrupt its operation.
//==================================================================================
#include "blake2engine.h"

Blake2Engine* createEngineInstance() {
// initialization of PRNGs
constexpr size_t maxGens = Blake2Engine::MAX_SEED_GENS;
#pragma omp critical
std::array<uint32_t, maxGens> initKey{};
initKey[0] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
initKey[1] = std::hash<std::thread::id>{}(std::this_thread::get_id());
#if !defined(__arm__) && !defined(__EMSCRIPTEN__)
if (sizeof(size_t) == 8)
initKey[2] = (std::hash<std::thread::id>{}(std::this_thread::get_id()) >> 32);
#endif
void* mem = malloc(1);
uint32_t counter = reinterpret_cast<long long>(mem); // NOLINT
free(mem);

Blake2Engine gen(initKey, counter);

std::uniform_int_distribution<uint32_t> distribution(0);
std::array<uint32_t, maxGens> seed{};
for (uint32_t i = 0; i < maxGens; i++) {
seed[i] = distribution(gen);
}

std::array<uint32_t, maxGens> rdseed{};
size_t attempts = 3;
bool rdGenPassed = false;
for(size_t i = 0; i < attempts && !rdGenPassed; ++i) {
try {
std::random_device genR;
for (uint32_t i = 0; i < maxGens; i++) {
rdseed[i] = distribution(genR);
}
rdGenPassed = true;
}
catch (std::exception& e) {
}
}
for (uint32_t i = 0; i < maxGens; i++) {
seed[i] += rdseed[i];
}

return new Blake2Engine(seed);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
#include <string.h>
#include <stdio.h>

#include "utils/prng/blake2.h"
#include "utils/prng/blake2-impl.h"
#include "blake2.h"
#include "blake2-impl.h"

int blake2xb_init(blake2xb_state *S, const size_t outlen) {
return blake2xb_init_key(S, outlen, NULL, 0);
Expand Down
6 changes: 6 additions & 0 deletions prng_libs/blake2_lib/link.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

# set -x

g++ -fPIC -shared -o libblake2.so -I./include -I../ ./lib/*.c ./lib/*.cpp

49 changes: 49 additions & 0 deletions prng_libs/prng.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//==================================================================================
// © 2024 Duality Technologies, Inc. All rights reserved.
// This is a proprietary software product of Duality Technologies, Inc.
// protected under copyright laws and international copyright treaties, patent
// law, trade secret law and other intellectual property rights of general
// applicability. Any use of this software is strictly prohibited absent a
// written agreement executed by Duality Technologies, Inc., which provides
// certain limited rights to use this software. You may not copy, distribute,
// make publicly available, publicly perform, disassemble, de-compile or reverse
// engineer any part of this software, breach its security, or circumvent,
// manipulate, impair or disrupt its operation.
//==================================================================================
#ifndef __PRNG_H__
#define __PRNG_H__

#include <cstdint>
#include <limits>


class PRNG {
public:
// all C++11 distributions used in OpenFHE work by default with uint32_t
// a different data type can be specified if needed for a particular
// architecture
using result_type = uint32_t;

PRNG(result_type seed) {}
/**
* @brief minimum value used by C+11 distribution generators when no lower
* bound is explicitly specified by the user
*/
static constexpr result_type min() {
return std::numeric_limits<result_type>::min();
}

/**
* @brief maximum value used by C+11 distribution generators when no upper
* bound is explicitly specified by the user
*/
static constexpr result_type max() {
return std::numeric_limits<result_type>::max();
}

virtual result_type operator()() = 0;
virtual ~PRNG() = default;
};

#endif // __PRNG_H__

Loading

0 comments on commit 30422b6

Please sign in to comment.