mirror of
https://github.com/privacy-scaling-explorations/emp-wasm.git
synced 2026-01-07 01:03:50 -05:00
use mbedtls
This commit is contained in:
@@ -4,12 +4,13 @@ Work in progress compiling authenticated garbling from [emp-toolkit/emp-ag2pc](h
|
||||
|
||||
Currently this is just a stripped down version that you can compile with a single clang++ command (see `build.sh`).
|
||||
|
||||
# Uncertain Refactors
|
||||
# Uncertain Changes
|
||||
|
||||
For most of the changes I'm reasonably confident that I preserved behavior, but there some things I'm less confident about:
|
||||
|
||||
- send and recv swapped for bob in `Fpre::generate` (see TODO comment)
|
||||
- after removing threading, I also moved everything to a single io channel
|
||||
- rewrite of simd code to not use simd and updated aes usage written by chatgpt o1 preview
|
||||
- used chatgpt o1 preview to migrate from openssl to mbedtls
|
||||
|
||||
Regardless, this version of emp-toolkit needs some checking.
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Variables
|
||||
MBEDTLS_DIR="../external/mbedtls"
|
||||
BUILD_DIR="$MBEDTLS_DIR/build/library"
|
||||
|
||||
# Emscripten build
|
||||
em++ async.cpp Buffer.cpp -sASYNCIFY -o index.html \
|
||||
-O3 \
|
||||
-I ../src/ \
|
||||
-I $(brew --prefix openssl)/include \
|
||||
-L $(brew --prefix openssl)/lib \
|
||||
-lcrypto \
|
||||
-lssl \
|
||||
-I "$MBEDTLS_DIR/include" \
|
||||
-L "$BUILD_DIR" \
|
||||
-lmbedtls \
|
||||
-lmbedcrypto \
|
||||
-lmbedx509 \
|
||||
-lembind \
|
||||
-s MODULARIZE=1 -s EXPORT_ES6=1 \
|
||||
-s ENVIRONMENT='web,worker' \
|
||||
|
||||
10
build.sh
10
build.sh
@@ -1,11 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
clang++ \
|
||||
-O3 \
|
||||
-std=c++17 \
|
||||
programs/2pc.cpp \
|
||||
-I src/ \
|
||||
-I $(brew --prefix openssl)/include \
|
||||
-L $(brew --prefix openssl)/lib \
|
||||
-lcrypto \
|
||||
-lssl \
|
||||
-I $(brew --prefix mbedtls)/include \
|
||||
-L $(brew --prefix mbedtls)/lib \
|
||||
-lmbedtls \
|
||||
-lmbedcrypto \
|
||||
-lmbedx509 \
|
||||
-o bin/2pc
|
||||
|
||||
56
build_embedtls.sh
Executable file
56
build_embedtls.sh
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Set variables
|
||||
MBEDTLS_REPO="https://github.com/Mbed-TLS/mbedtls.git"
|
||||
MBEDTLS_VERSION="v3.6.1" # The specific release tag of mbed TLS to use
|
||||
MBEDTLS_DIR="./external/mbedtls" # Directory outside your tracked repo for mbedtls
|
||||
BUILD_DIR="$MBEDTLS_DIR/build" # Build directory
|
||||
EMSDK_PATH=$(dirname $(which emsdk)) # Automatically determine the directory of emsdk
|
||||
|
||||
# Set up Emscripten environment
|
||||
source "$EMSDK_PATH/emsdk_env.sh"
|
||||
|
||||
# Determine the path to the Emscripten installation
|
||||
EMSCRIPTEN=$(echo $EMSDK_PATH/upstream/emscripten)
|
||||
|
||||
# Create directory for mbed TLS if it doesn't exist
|
||||
mkdir -p "$MBEDTLS_DIR"
|
||||
|
||||
# Clone mbed TLS if the directory is empty
|
||||
if [ ! -d "$MBEDTLS_DIR/.git" ]; then
|
||||
echo "Cloning mbed TLS repository..."
|
||||
git clone "$MBEDTLS_REPO" "$MBEDTLS_DIR"
|
||||
cd "$MBEDTLS_DIR" || exit
|
||||
echo "Checking out mbed TLS version $MBEDTLS_VERSION..."
|
||||
git checkout "$MBEDTLS_VERSION"
|
||||
echo "Initializing and updating submodules..."
|
||||
git submodule update --init --recursive
|
||||
cd - || exit
|
||||
else
|
||||
echo "mbed TLS repository already cloned. Ensuring version $MBEDTLS_VERSION is checked out..."
|
||||
cd "$MBEDTLS_DIR" || exit
|
||||
git fetch --tags
|
||||
git checkout "$MBEDTLS_VERSION"
|
||||
echo "Updating submodules..."
|
||||
git submodule update --init --recursive
|
||||
cd - || exit
|
||||
fi
|
||||
|
||||
# Create build directory if it doesn't exist
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
# Configure mbed TLS using Emscripten's CMake toolchain
|
||||
echo "Configuring mbed TLS for WebAssembly..."
|
||||
cmake -S "$MBEDTLS_DIR" -B "$BUILD_DIR" \
|
||||
-DCMAKE_TOOLCHAIN_FILE="${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DENABLE_TESTING=OFF \
|
||||
-DENABLE_PROGRAMS=OFF
|
||||
|
||||
# Build mbed TLS
|
||||
echo "Building mbed TLS..."
|
||||
cmake --build "$BUILD_DIR"
|
||||
|
||||
echo "mbed TLS build complete. The libraries are located in $BUILD_DIR/library"
|
||||
2
external/.gitignore
vendored
Normal file
2
external/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -1,52 +1,63 @@
|
||||
#ifndef EMP_AES_H
|
||||
#define EMP_AES_H
|
||||
|
||||
#include "emp-tool/utils/utils.h"
|
||||
#include "block.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <mbedtls/cipher.h> // Include mbed TLS cipher headers
|
||||
|
||||
namespace emp {
|
||||
|
||||
using AES_KEY = EVP_CIPHER_CTX*; // Use pointer to OpenSSL's EVP_CIPHER_CTX structure
|
||||
using AES_KEY = mbedtls_cipher_context_t; // Use mbed TLS cipher context
|
||||
|
||||
inline void AES_set_encrypt_key(const block userkey, AES_KEY *key) {
|
||||
// Allocate and initialize the EVP_CIPHER_CTX
|
||||
*key = EVP_CIPHER_CTX_new();
|
||||
mbedtls_cipher_init(key);
|
||||
const mbedtls_cipher_info_t *cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
|
||||
mbedtls_cipher_setup(key, cipher_info);
|
||||
unsigned char key_bytes[16];
|
||||
memcpy(key_bytes, &userkey.low, 8);
|
||||
memcpy(key_bytes + 8, &userkey.high, 8);
|
||||
// Initialize the context for encryption with the given key
|
||||
EVP_EncryptInit_ex(*key, EVP_aes_128_ecb(), NULL, key_bytes, NULL);
|
||||
// Disable padding
|
||||
EVP_CIPHER_CTX_set_padding(*key, 0);
|
||||
mbedtls_cipher_setkey(key, key_bytes, 128, MBEDTLS_ENCRYPT);
|
||||
mbedtls_cipher_set_padding_mode(key, MBEDTLS_PADDING_NONE);
|
||||
}
|
||||
|
||||
inline void AES_ecb_encrypt_blks(block *blks, unsigned int nblks, const AES_KEY key) {
|
||||
inline void AES_ecb_encrypt_blks(block *blks, unsigned int nblks, AES_KEY *key) {
|
||||
unsigned char *data = reinterpret_cast<unsigned char*>(blks);
|
||||
int outlen1, outlen2;
|
||||
int total_len = nblks * 16; // Each block is 16 bytes
|
||||
size_t outlen1 = 0, outlen2 = 0;
|
||||
size_t total_len = nblks * 16; // Each block is 16 bytes
|
||||
unsigned char *output = new unsigned char[total_len + 16]; // Allocate output buffer
|
||||
|
||||
// Reinitialize the context
|
||||
EVP_EncryptInit_ex(key, NULL, NULL, NULL, NULL);
|
||||
mbedtls_cipher_reset(key);
|
||||
|
||||
// Encrypt data in-place
|
||||
EVP_EncryptUpdate(key, data, &outlen1, data, total_len);
|
||||
// Encrypt data
|
||||
int ret = mbedtls_cipher_update(key, data, total_len, output, &outlen1);
|
||||
if (ret != 0) {
|
||||
error("Error in AES_ecb_encrypt_blks");
|
||||
}
|
||||
|
||||
// Finalize encryption
|
||||
EVP_EncryptFinal_ex(key, data + outlen1, &outlen2);
|
||||
ret = mbedtls_cipher_finish(key, output + outlen1, &outlen2);
|
||||
if (ret != 0) {
|
||||
error("Error in AES_ecb_encrypt_blks");
|
||||
}
|
||||
|
||||
// Verify that the total output length matches the input length
|
||||
assert(outlen1 + outlen2 == total_len);
|
||||
|
||||
// Copy output back to data
|
||||
memcpy(data, output, total_len);
|
||||
delete[] output; // Free allocated memory
|
||||
}
|
||||
|
||||
// Templated function for encrypting a fixed number of blocks
|
||||
template<int N>
|
||||
inline void AES_ecb_encrypt_blks(block *blks, const AES_KEY key) {
|
||||
inline void AES_ecb_encrypt_blks(block *blks, AES_KEY *key) {
|
||||
AES_ecb_encrypt_blks(blks, N, key);
|
||||
}
|
||||
|
||||
// Function to free the AES key context
|
||||
inline void AES_KEY_free(AES_KEY key) {
|
||||
EVP_CIPHER_CTX_free(key);
|
||||
inline void AES_KEY_free(AES_KEY *key) {
|
||||
mbedtls_cipher_free(key);
|
||||
}
|
||||
|
||||
} // namespace emp
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef EMP_AES_OPT_KS_H
|
||||
#define EMP_AES_OPT_KS_H
|
||||
|
||||
#include "emp-tool/utils/utils.h"
|
||||
#include "aes.h" // Updated to include our standard AES functions without SIMD
|
||||
|
||||
namespace emp {
|
||||
@@ -14,12 +15,12 @@ static inline void AES_opt_key_schedule(block* user_keys, AES_KEY *keys) {
|
||||
unsigned char key_bytes[16];
|
||||
memcpy(key_bytes, &user_keys[i].low, 8);
|
||||
memcpy(key_bytes + 8, &user_keys[i].high, 8);
|
||||
// Allocate and initialize the EVP_CIPHER_CTX
|
||||
keys[i] = EVP_CIPHER_CTX_new();
|
||||
// Initialize the context for encryption with the given key
|
||||
EVP_EncryptInit_ex(keys[i], EVP_aes_128_ecb(), NULL, key_bytes, NULL);
|
||||
// Disable padding
|
||||
EVP_CIPHER_CTX_set_padding(keys[i], 0);
|
||||
// Initialize the mbed TLS cipher context
|
||||
mbedtls_cipher_init(&keys[i]);
|
||||
const mbedtls_cipher_info_t *cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
|
||||
mbedtls_cipher_setup(&keys[i], cipher_info);
|
||||
mbedtls_cipher_setkey(&keys[i], key_bytes, 128, MBEDTLS_ENCRYPT);
|
||||
mbedtls_cipher_set_padding_mode(&keys[i], MBEDTLS_PADDING_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,20 +31,31 @@ template<int numKeys, int numEncs>
|
||||
static inline void ParaEnc(block *blks, AES_KEY *keys) {
|
||||
for(int i = 0; i < numKeys; ++i) {
|
||||
unsigned char *data = reinterpret_cast<unsigned char*>(blks + i * numEncs);
|
||||
int outlen1, outlen2;
|
||||
int total_len = numEncs * 16; // Each block is 16 bytes
|
||||
size_t outlen1 = 0, outlen2 = 0;
|
||||
size_t total_len = numEncs * 16; // Each block is 16 bytes
|
||||
unsigned char *output = new unsigned char[total_len + 16]; // Allocate output buffer
|
||||
|
||||
// Reinitialize the context
|
||||
EVP_EncryptInit_ex(keys[i], NULL, NULL, NULL, NULL);
|
||||
mbedtls_cipher_reset(&keys[i]);
|
||||
|
||||
// Encrypt data in-place
|
||||
EVP_EncryptUpdate(keys[i], data, &outlen1, data, total_len);
|
||||
// Encrypt data
|
||||
int ret = mbedtls_cipher_update(&keys[i], data, total_len, output, &outlen1);
|
||||
if (ret != 0) {
|
||||
error("Error in ParaEnc");
|
||||
}
|
||||
|
||||
// Finalize encryption
|
||||
EVP_EncryptFinal_ex(keys[i], data + outlen1, &outlen2);
|
||||
ret = mbedtls_cipher_finish(&keys[i], output + outlen1, &outlen2);
|
||||
if (ret != 0) {
|
||||
error("Error in ParaEnc");
|
||||
}
|
||||
|
||||
// Verify that the total output length matches the input length
|
||||
assert(outlen1 + outlen2 == total_len);
|
||||
|
||||
// Copy output back to data
|
||||
memcpy(data, output, total_len);
|
||||
delete[] output; // Free allocated memory
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +63,7 @@ static inline void ParaEnc(block *blks, AES_KEY *keys) {
|
||||
template<int NumKeys>
|
||||
static inline void AES_opt_key_free(AES_KEY *keys) {
|
||||
for(int i = 0; i < NumKeys; ++i) {
|
||||
EVP_CIPHER_CTX_free(keys[i]);
|
||||
mbedtls_cipher_free(&keys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
#ifndef EMP_GROUP_H
|
||||
#define EMP_GROUP_H
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include "emp-tool/utils/utils.h"
|
||||
|
||||
//#ifdef ECC_USE_OPENSSL
|
||||
//#else
|
||||
//#include "group_relic.h"
|
||||
//#endif
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
|
||||
namespace emp {
|
||||
class BigInt { public:
|
||||
BIGNUM *n = nullptr;
|
||||
class BigInt {
|
||||
public:
|
||||
mbedtls_mpi n;
|
||||
BigInt();
|
||||
BigInt(const BigInt &oth);
|
||||
BigInt &operator=(BigInt oth);
|
||||
@@ -25,40 +25,40 @@ class BigInt { public:
|
||||
void from_bin(const unsigned char * in, int length);
|
||||
|
||||
BigInt add(const BigInt &oth);
|
||||
BigInt mul(const BigInt &oth, BN_CTX *ctx);
|
||||
BigInt mod(const BigInt &oth, BN_CTX *ctx);
|
||||
BigInt add_mod(const BigInt & b, const BigInt& m, BN_CTX *ctx);
|
||||
BigInt mul_mod(const BigInt & b, const BigInt& m, BN_CTX *ctx);
|
||||
BigInt mul(const BigInt &oth);
|
||||
BigInt mod(const BigInt &oth);
|
||||
BigInt add_mod(const BigInt & b, const BigInt& m);
|
||||
BigInt mul_mod(const BigInt & b, const BigInt& m);
|
||||
};
|
||||
class Group;
|
||||
class Point {
|
||||
public:
|
||||
EC_POINT *point = nullptr;
|
||||
Group * group = nullptr;
|
||||
Point (Group * g = nullptr);
|
||||
~Point();
|
||||
Point(const Point & p);
|
||||
Point& operator=(Point p);
|
||||
public:
|
||||
mbedtls_ecp_point point;
|
||||
Group * group = nullptr;
|
||||
Point (Group * g = nullptr);
|
||||
~Point();
|
||||
Point(const Point & p);
|
||||
Point& operator=(Point p);
|
||||
|
||||
void to_bin(unsigned char * buf, size_t buf_len);
|
||||
size_t size();
|
||||
void from_bin(Group * g, const unsigned char * buf, size_t buf_len);
|
||||
void to_bin(unsigned char * buf, size_t buf_len);
|
||||
size_t size();
|
||||
void from_bin(Group * g, const unsigned char * buf, size_t buf_len);
|
||||
|
||||
Point add(Point & rhs);
|
||||
// Point sub(Point & rhs);
|
||||
// bool is_at_infinity();
|
||||
// bool is_on_curve();
|
||||
Point mul(const BigInt &m);
|
||||
Point inv();
|
||||
bool operator==(Point & rhs);
|
||||
Point add(Point & rhs);
|
||||
Point mul(const BigInt &m);
|
||||
Point inv();
|
||||
bool operator==(Point & rhs);
|
||||
};
|
||||
|
||||
class Group { public:
|
||||
EC_GROUP *ec_group = nullptr;
|
||||
BN_CTX * bn_ctx = nullptr;
|
||||
class Group {
|
||||
public:
|
||||
mbedtls_ecp_group ec_group;
|
||||
BigInt order;
|
||||
unsigned char * scratch;
|
||||
size_t scratch_size = 256;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
mbedtls_entropy_context entropy;
|
||||
|
||||
Group();
|
||||
~Group();
|
||||
void resize_scratch(size_t size);
|
||||
@@ -68,7 +68,7 @@ class Group { public:
|
||||
};
|
||||
|
||||
}
|
||||
#include "group_openssl.h"
|
||||
|
||||
#include "group_mbedtls.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
228
src/emp-tool/utils/group_mbedtls.h
Normal file
228
src/emp-tool/utils/group_mbedtls.h
Normal file
@@ -0,0 +1,228 @@
|
||||
#ifndef EMP_GROUP_MBEDTLS_H
|
||||
#define EMP_GROUP_MBEDTLS_H
|
||||
|
||||
namespace emp {
|
||||
|
||||
// BigInt implementation
|
||||
inline BigInt::BigInt() {
|
||||
mbedtls_mpi_init(&n);
|
||||
}
|
||||
inline BigInt::BigInt(const BigInt &oth) {
|
||||
mbedtls_mpi_init(&n);
|
||||
mbedtls_mpi_copy(&n, &oth.n);
|
||||
}
|
||||
inline BigInt& BigInt::operator=(BigInt oth) {
|
||||
std::swap(n, oth.n);
|
||||
return *this;
|
||||
}
|
||||
inline BigInt::~BigInt() {
|
||||
mbedtls_mpi_free(&n);
|
||||
}
|
||||
|
||||
inline int BigInt::size() {
|
||||
return mbedtls_mpi_size(&n);
|
||||
}
|
||||
|
||||
inline void BigInt::to_bin(unsigned char * in) {
|
||||
mbedtls_mpi_write_binary(&n, in, mbedtls_mpi_size(&n));
|
||||
}
|
||||
|
||||
inline void BigInt::from_bin(const unsigned char * in, int length) {
|
||||
mbedtls_mpi_read_binary(&n, in, length);
|
||||
}
|
||||
|
||||
inline BigInt BigInt::add(const BigInt &oth) {
|
||||
BigInt ret;
|
||||
mbedtls_mpi_add_mpi(&ret.n, &n, &oth.n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline BigInt BigInt::mul_mod(const BigInt & b, const BigInt &m) {
|
||||
BigInt ret;
|
||||
mbedtls_mpi_mul_mpi(&ret.n, &n, &b.n);
|
||||
mbedtls_mpi_mod_mpi(&ret.n, &ret.n, &m.n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline BigInt BigInt::add_mod(const BigInt & b, const BigInt &m) {
|
||||
BigInt ret;
|
||||
mbedtls_mpi_add_mpi(&ret.n, &n, &b.n);
|
||||
mbedtls_mpi_mod_mpi(&ret.n, &ret.n, &m.n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline BigInt BigInt::mul(const BigInt &oth) {
|
||||
BigInt ret;
|
||||
mbedtls_mpi_mul_mpi(&ret.n, &n, &oth.n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline BigInt BigInt::mod(const BigInt &oth) {
|
||||
BigInt ret;
|
||||
mbedtls_mpi_mod_mpi(&ret.n, &n, &oth.n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Point implementation
|
||||
inline Point::Point (Group * g) {
|
||||
if (g == nullptr) return;
|
||||
this->group = g;
|
||||
mbedtls_ecp_point_init(&point);
|
||||
}
|
||||
|
||||
inline Point::~Point() {
|
||||
if (group == nullptr) return;
|
||||
mbedtls_ecp_point_free(&point);
|
||||
}
|
||||
|
||||
inline Point::Point(const Point & p) {
|
||||
if (p.group == nullptr) return;
|
||||
this->group = p.group;
|
||||
mbedtls_ecp_point_init(&point);
|
||||
int ret = mbedtls_ecp_copy(&point, &p.point);
|
||||
if(ret != 0) error("ECC COPY");
|
||||
}
|
||||
|
||||
inline Point& Point::operator=(Point p) {
|
||||
std::swap(p.point, point);
|
||||
std::swap(p.group, group);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void Point::to_bin(unsigned char * buf, size_t buf_len) {
|
||||
size_t olen = 0;
|
||||
int ret = mbedtls_ecp_point_write_binary(&group->ec_group, &point,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, buf_len);
|
||||
if(ret != 0) error("ECC TO_BIN");
|
||||
}
|
||||
|
||||
inline size_t Point::size() {
|
||||
size_t olen = 0;
|
||||
mbedtls_ecp_point_write_binary(&group->ec_group, &point,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, NULL, 0);
|
||||
return olen;
|
||||
}
|
||||
|
||||
inline void Point::from_bin(Group * g, const unsigned char * buf, size_t buf_len) {
|
||||
if (group == nullptr) {
|
||||
group = g;
|
||||
mbedtls_ecp_point_init(&point);
|
||||
}
|
||||
int ret = mbedtls_ecp_point_read_binary(&group->ec_group, &point, buf, buf_len);
|
||||
if(ret != 0) error("ECC FROM_BIN");
|
||||
}
|
||||
|
||||
inline Point Point::add(Point & rhs) {
|
||||
Point ret(group);
|
||||
mbedtls_mpi one;
|
||||
mbedtls_mpi_init(&one);
|
||||
|
||||
// Set 'one' to 1
|
||||
if (mbedtls_mpi_lset(&one, 1) != 0) {
|
||||
error("Failed to set MPI value");
|
||||
}
|
||||
|
||||
int res = mbedtls_ecp_muladd(&group->ec_group, &ret.point, &one, &point, &one, &rhs.point);
|
||||
mbedtls_mpi_free(&one);
|
||||
|
||||
if (res != 0) {
|
||||
error("ECC ADD");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline Point Point::mul(const BigInt &m) {
|
||||
Point ret (group);
|
||||
int res = mbedtls_ecp_mul(&group->ec_group, &ret.point, &m.n, &point, mbedtls_ctr_drbg_random, &group->ctr_drbg);
|
||||
if(res != 0) error("ECC MUL");
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline Point Point::inv() {
|
||||
Point ret(group); // Create a new Point associated with the same Group
|
||||
mbedtls_mpi order_minus_one;
|
||||
mbedtls_mpi_init(&order_minus_one);
|
||||
|
||||
// Compute (order - 1) which is equivalent to -1 mod order
|
||||
mbedtls_mpi_copy(&order_minus_one, &group->ec_group.N);
|
||||
mbedtls_mpi_sub_int(&order_minus_one, &order_minus_one, 1);
|
||||
|
||||
// Check if the point is valid and on the curve before inversion
|
||||
int check = mbedtls_ecp_check_pubkey(&group->ec_group, &point);
|
||||
if (check != 0) {
|
||||
mbedtls_mpi_free(&order_minus_one);
|
||||
error("Point is not on the curve");
|
||||
}
|
||||
|
||||
// Perform the point inversion using scalar multiplication with (order - 1)
|
||||
int res = mbedtls_ecp_mul(&group->ec_group, &ret.point, &order_minus_one, &point, mbedtls_ctr_drbg_random, &group->ctr_drbg);
|
||||
if (res != 0) {
|
||||
mbedtls_mpi_free(&order_minus_one);
|
||||
error("ECC INV");
|
||||
}
|
||||
|
||||
mbedtls_mpi_free(&order_minus_one);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool Point::operator==(Point & rhs) {
|
||||
int ret = mbedtls_ecp_point_cmp(&point, &rhs.point);
|
||||
if(ret < 0) error("ECC CMP");
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
// Group implementation
|
||||
inline Group::Group() {
|
||||
mbedtls_ecp_group_init(&ec_group);
|
||||
mbedtls_ecp_group_load(&ec_group, MBEDTLS_ECP_DP_SECP256R1); // NIST P-256
|
||||
mbedtls_mpi_init(&order.n);
|
||||
mbedtls_mpi_copy(&order.n, &ec_group.N);
|
||||
scratch = new unsigned char[scratch_size];
|
||||
// Initialize entropy and DRBG
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
mbedtls_entropy_init(&entropy);
|
||||
const char *pers = "emp_group";
|
||||
int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
|
||||
(const unsigned char *) pers, strlen(pers));
|
||||
if (ret != 0) error("DRBG SEED");
|
||||
}
|
||||
|
||||
inline Group::~Group(){
|
||||
mbedtls_ecp_group_free(&ec_group);
|
||||
mbedtls_mpi_free(&order.n);
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_entropy_free(&entropy);
|
||||
|
||||
if(scratch != nullptr)
|
||||
delete[] scratch;
|
||||
}
|
||||
|
||||
inline void Group::resize_scratch(size_t size) {
|
||||
if (size > scratch_size) {
|
||||
delete[] scratch;
|
||||
scratch_size = size;
|
||||
scratch = new unsigned char[scratch_size];
|
||||
}
|
||||
}
|
||||
|
||||
inline void Group::get_rand_bn(BigInt & n) {
|
||||
int ret = mbedtls_mpi_fill_random(&n.n, mbedtls_mpi_size(&order.n), mbedtls_ctr_drbg_random, &ctr_drbg);
|
||||
if(ret != 0) error("RAND BN");
|
||||
mbedtls_mpi_mod_mpi(&n.n, &n.n, &order.n);
|
||||
}
|
||||
|
||||
inline Point Group::get_generator() {
|
||||
Point res(this);
|
||||
int ret = mbedtls_ecp_copy(&res.point, &ec_group.G);
|
||||
if(ret != 0) error("ECC GEN");
|
||||
return res;
|
||||
}
|
||||
|
||||
inline Point Group::mul_gen(const BigInt &m) {
|
||||
Point res(this);
|
||||
int ret = mbedtls_ecp_mul(&ec_group, &res.point, &m.n, &ec_group.G, mbedtls_ctr_drbg_random, &ctr_drbg);
|
||||
if(ret != 0) error("ECC GEN MUL");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,180 +0,0 @@
|
||||
#ifndef EMP_GROUP_OPENSSL_H
|
||||
#define EMP_GROUP_OPENSSL_H
|
||||
|
||||
namespace emp {
|
||||
inline BigInt::BigInt() {
|
||||
n = BN_new();
|
||||
}
|
||||
inline BigInt::BigInt(const BigInt &oth) {
|
||||
n = BN_new();
|
||||
BN_copy(n, oth.n);
|
||||
}
|
||||
inline BigInt& BigInt::operator=(BigInt oth) {
|
||||
std::swap(n, oth.n);
|
||||
return *this;
|
||||
}
|
||||
inline BigInt::~BigInt() {
|
||||
if (n != nullptr)
|
||||
BN_free(n);
|
||||
}
|
||||
|
||||
inline int BigInt::size() {
|
||||
return BN_num_bytes(n);
|
||||
}
|
||||
|
||||
inline void BigInt::to_bin(unsigned char * in) {
|
||||
BN_bn2bin(n, in);
|
||||
}
|
||||
|
||||
inline void BigInt::from_bin(const unsigned char * in, int length) {
|
||||
BN_free(n);
|
||||
n = BN_bin2bn(in, length, nullptr);
|
||||
}
|
||||
|
||||
inline BigInt BigInt::add(const BigInt &oth) {
|
||||
BigInt ret;
|
||||
BN_add(ret.n, n, oth.n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline BigInt BigInt::mul_mod(const BigInt & b, const BigInt &m, BN_CTX *ctx) {
|
||||
BigInt ret;
|
||||
BN_mod_mul(ret.n, n, b.n, m.n, ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline BigInt BigInt::add_mod(const BigInt & b, const BigInt &m, BN_CTX *ctx) {
|
||||
BigInt ret;
|
||||
BN_mod_add(ret.n, n, b.n, m.n, ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline BigInt BigInt::mul(const BigInt &oth, BN_CTX *ctx) {
|
||||
BigInt ret;
|
||||
BN_mul(ret.n, n, oth.n, ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline BigInt BigInt::mod(const BigInt &oth, BN_CTX *ctx) {
|
||||
BigInt ret;
|
||||
BN_mod(ret.n, n, oth.n, ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline Point::Point (Group * g) {
|
||||
if (g == nullptr) return;
|
||||
this->group = g;
|
||||
point = EC_POINT_new(group->ec_group);
|
||||
}
|
||||
|
||||
inline Point::~Point() {
|
||||
if(point != nullptr)
|
||||
EC_POINT_free(point);
|
||||
}
|
||||
|
||||
inline Point::Point(const Point & p) {
|
||||
if (p.group == nullptr) return;
|
||||
this->group = p.group;
|
||||
point = EC_POINT_new(group->ec_group);
|
||||
int ret = EC_POINT_copy(point, p.point);
|
||||
if(ret == 0) error("ECC COPY");
|
||||
}
|
||||
|
||||
inline Point& Point::operator=(Point p) {
|
||||
std::swap(p.point, point);
|
||||
std::swap(p.group, group);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void Point::to_bin(unsigned char * buf, size_t buf_len) {
|
||||
int ret = EC_POINT_point2oct(group->ec_group, point, POINT_CONVERSION_UNCOMPRESSED, buf, buf_len, group->bn_ctx);
|
||||
if(ret == 0) error("ECC TO_BIN");
|
||||
}
|
||||
|
||||
inline size_t Point::size() {
|
||||
size_t ret = EC_POINT_point2oct(group->ec_group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, group->bn_ctx);
|
||||
if(ret == 0) error("ECC SIZE_BIN");
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void Point::from_bin(Group * g, const unsigned char * buf, size_t buf_len) {
|
||||
if (point == nullptr) {
|
||||
group = g;
|
||||
point = EC_POINT_new(group->ec_group);
|
||||
}
|
||||
int ret = EC_POINT_oct2point(group->ec_group, point, buf, buf_len, group->bn_ctx);
|
||||
if(ret == 0) error("ECC FROM_BIN");
|
||||
}
|
||||
|
||||
inline Point Point::add(Point & rhs) {
|
||||
Point ret(group);
|
||||
int res = EC_POINT_add(group->ec_group, ret.point, point, rhs.point, group->bn_ctx);
|
||||
if(res == 0) error("ECC ADD");
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline Point Point::mul(const BigInt &m) {
|
||||
Point ret (group);
|
||||
int res = EC_POINT_mul(group->ec_group, ret.point, NULL, point, m.n, group->bn_ctx);
|
||||
if(res == 0) error("ECC MUL");
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline Point Point::inv() {
|
||||
Point ret (*this);
|
||||
int res = EC_POINT_invert(group->ec_group, ret.point, group->bn_ctx);
|
||||
if(res == 0) error("ECC INV");
|
||||
return ret;
|
||||
}
|
||||
inline bool Point::operator==(Point & rhs) {
|
||||
int ret = EC_POINT_cmp(group->ec_group, point, rhs.point, group->bn_ctx);
|
||||
if(ret == -1) error("ECC CMP");
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
|
||||
inline Group::Group() {
|
||||
ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);//NIST P-256
|
||||
bn_ctx = BN_CTX_new();
|
||||
EC_GROUP_get_order(ec_group, order.n, bn_ctx);
|
||||
scratch = new unsigned char[scratch_size];
|
||||
}
|
||||
|
||||
inline Group::~Group(){
|
||||
if(ec_group != nullptr)
|
||||
EC_GROUP_free(ec_group);
|
||||
|
||||
if(bn_ctx != nullptr)
|
||||
BN_CTX_free(bn_ctx);
|
||||
|
||||
if(scratch != nullptr)
|
||||
delete[] scratch;
|
||||
}
|
||||
|
||||
inline void Group::resize_scratch(size_t size) {
|
||||
if (size > scratch_size) {
|
||||
delete[] scratch;
|
||||
scratch_size = size;
|
||||
scratch = new unsigned char[scratch_size];
|
||||
}
|
||||
}
|
||||
|
||||
inline void Group::get_rand_bn(BigInt & n) {
|
||||
BN_rand_range(n.n, order.n);
|
||||
}
|
||||
|
||||
inline Point Group::get_generator() {
|
||||
Point res(this);
|
||||
int ret = EC_POINT_copy(res.point, EC_GROUP_get0_generator(ec_group));
|
||||
if(ret == 0) error("ECC GEN");
|
||||
return res;
|
||||
}
|
||||
|
||||
inline Point Group::mul_gen(const BigInt &m) {
|
||||
Point res(this);
|
||||
int ret = EC_POINT_mul(ec_group, res.point, m.n ,NULL, NULL, bn_ctx);
|
||||
if(ret == 0) error("ECC GEN MUL");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2,34 +2,35 @@
|
||||
#define EMP_HASH_H
|
||||
|
||||
#include "block.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace emp {
|
||||
class Hash {
|
||||
public:
|
||||
EVP_MD_CTX *mdctx;
|
||||
mbedtls_sha256_context mdctx;
|
||||
static const int HASH_BUFFER_SIZE = 4096;
|
||||
char buffer[HASH_BUFFER_SIZE];
|
||||
int size = 0;
|
||||
static const int DIGEST_SIZE = 32;
|
||||
|
||||
Hash() {
|
||||
mdctx = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
|
||||
mbedtls_sha256_init(&mdctx);
|
||||
mbedtls_sha256_starts(&mdctx, 0); // 0 for SHA-256
|
||||
}
|
||||
|
||||
~Hash() {
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
mbedtls_sha256_free(&mdctx);
|
||||
}
|
||||
|
||||
void put(const void * data, int nbyte) {
|
||||
if (nbyte >= HASH_BUFFER_SIZE)
|
||||
EVP_DigestUpdate(mdctx, data, nbyte);
|
||||
else if(size + nbyte < HASH_BUFFER_SIZE) {
|
||||
if (nbyte >= HASH_BUFFER_SIZE) {
|
||||
mbedtls_sha256_update(&mdctx, (const unsigned char *)data, nbyte);
|
||||
} else if(size + nbyte < HASH_BUFFER_SIZE) {
|
||||
memcpy(buffer+size, data, nbyte);
|
||||
size+=nbyte;
|
||||
} else {
|
||||
EVP_DigestUpdate(mdctx, buffer, size);
|
||||
mbedtls_sha256_update(&mdctx, (const unsigned char *)buffer, size);
|
||||
memcpy(buffer, data, nbyte);
|
||||
size = nbyte;
|
||||
}
|
||||
@@ -41,16 +42,15 @@ public:
|
||||
|
||||
void digest(void * a) {
|
||||
if(size > 0) {
|
||||
EVP_DigestUpdate(mdctx, buffer, size);
|
||||
mbedtls_sha256_update(&mdctx, (const unsigned char *)buffer, size);
|
||||
size=0;
|
||||
}
|
||||
unsigned int len = 0;
|
||||
EVP_DigestFinal_ex(mdctx, (unsigned char *)a, &len);
|
||||
mbedtls_sha256_finish(&mdctx, (unsigned char *)a);
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
|
||||
mbedtls_sha256_starts(&mdctx, 0);
|
||||
size=0;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace emp {
|
||||
*/
|
||||
|
||||
template<int BatchSize = 8>
|
||||
class MITCCRH { public:
|
||||
class MITCCRH {
|
||||
public:
|
||||
AES_KEY scheduled_key[BatchSize];
|
||||
block keys[BatchSize];
|
||||
int key_used = BatchSize;
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
void random_block(block * data, int nblocks=1) {
|
||||
for(int i = 0; i < nblocks; ++i) {
|
||||
block blk = makeBlock(0LL, counter++);
|
||||
AES_ecb_encrypt_blks(&blk, 1, aes);
|
||||
AES_ecb_encrypt_blks(&blk, 1, &aes);
|
||||
data[i] = blk;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ namespace emp {
|
||||
* [REF] "Efficient Garbling from a Fixed-Key Blockcipher"
|
||||
* https://eprint.iacr.org/2013/426.pdf
|
||||
*/
|
||||
class PRP { public:
|
||||
class PRP {
|
||||
public:
|
||||
AES_KEY aes;
|
||||
|
||||
PRP(const char * key = nullptr) {
|
||||
@@ -29,11 +30,9 @@ class PRP { public:
|
||||
}
|
||||
|
||||
void permute_block(block *data, int nblocks) {
|
||||
for(int i = 0; i < nblocks/AES_BATCH_SIZE; ++i) {
|
||||
AES_ecb_encrypt_blks<AES_BATCH_SIZE>(data + i*AES_BATCH_SIZE, aes);
|
||||
for(int i = 0; i < nblocks; ++i) {
|
||||
AES_ecb_encrypt_blks(&data[i], 1, &aes);
|
||||
}
|
||||
int remain = nblocks % AES_BATCH_SIZE;
|
||||
AES_ecb_encrypt_blks(data + nblocks - remain, remain, aes);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user