use mbedtls

This commit is contained in:
Andrew Morris
2024-10-11 10:21:39 +11:00
parent 29e119cf9a
commit 6ab298b3f2
14 changed files with 416 additions and 275 deletions

View File

@@ -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.

View File

@@ -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' \

View File

@@ -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
View 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
View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -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

View File

@@ -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]);
}
}

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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);
}
};
}