Unverified Commit e2043c9f authored by Sveta Rogova's avatar Sveta Rogova Committed by GitHub

Merge pull request #1 from skalenetwork/enhancement/SKALE-1512-add-DKG-to-SGX

Enhancement/skale 1512 add dkg to sgx
parents 3c31e5a9 d92bb2eb
...@@ -104,6 +104,8 @@ add_custom_target(sgxd COMMAND make all ...@@ -104,6 +104,8 @@ add_custom_target(sgxd COMMAND make all
secure_enclave/secure_enclave.c secure_enclave/secure_enclave.c
secure_enclave/secure_enclave_t.c secure_enclave/secure_enclave_t.c
secure_enclave/secure_enclave_t.h secure_enclave/secure_enclave_t.h
secure_enclave/DKGUtils.h
secure_enclave/DKGUtils.cpp
create_enclave.c create_enclave.c
create_enclave.h create_enclave.h
oc_alloc.c oc_alloc.c
......
This diff is collapsed.
/usr/share/automake-1.15/compile /usr/share/automake-1.16/compile
\ No newline at end of file \ No newline at end of file
/usr/share/automake-1.15/depcomp /usr/share/automake-1.16/depcomp
\ No newline at end of file \ No newline at end of file
/usr/share/automake-1.15/install-sh /usr/share/automake-1.16/install-sh
\ No newline at end of file \ No newline at end of file
/usr/share/automake-1.15/missing /usr/share/automake-1.16/missing
\ No newline at end of file \ No newline at end of file
//
// Created by kladko on 9/5/19.
//
#include "DKGUtils.h"
#include <../trusted_libff/libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp>
#include <../trusted_libff/libff/algebra/fields/fp.hpp>
#include <../trusted_libff/libff/algebra/curves/alt_bn128/alt_bn128_g2.hpp>
#include "../sgxwallet_common.h"
#include <cstdio>
#include <stdio.h>
std::string stringFromFr(libff::alt_bn128_Fr& _el) {
mpz_t t;
mpz_init(t);
_el.as_bigint().to_mpz(t);
char arr[mpz_sizeinbase(t, 10) + 2];
char *tmp = mpz_get_str(arr, 10, t);
mpz_clear(t);
return std::string(tmp);
}
template<class T>
std::string ConvertToString(T field_elem) {
mpz_t t;
mpz_init(t);
field_elem.as_bigint().to_mpz(t);
char arr[mpz_sizeinbase (t, 10) + 2];
char * tmp = mpz_get_str(arr, 10, t);
mpz_clear(t);
std::string output = tmp;
return output;
}
std::vector<libff::alt_bn128_Fr> SplitStringToFr(const char* koefs, const char* symbol){
std::string str(koefs);
std::string delim(symbol);
std::vector<libff::alt_bn128_Fr> tokens;
size_t prev = 0, pos = 0;
do
{
pos = str.find(delim, prev);
if (pos == std::string::npos) pos = str.length();
std::string token = str.substr(prev, pos-prev);
if (!token.empty()) {
libff::alt_bn128_Fr koef(token.c_str());
tokens.push_back(koef);
}
prev = pos + delim.length();
}
while (pos < str.length() && prev < str.length());
return tokens;
}
void gen_dkg_poly( char* secret/*[BUF_LEN]*/, unsigned _t ){
libff::init_alt_bn128_params();
std::string result;
for (size_t i = 0; i < _t; ++i) {
libff::alt_bn128_Fr cur_coef = libff::alt_bn128_Fr::random_element();
while (i == _t - 1 && cur_coef == libff::alt_bn128_Fr::zero()) {
cur_coef = libff::alt_bn128_Fr::random_element();
}
result += stringFromFr(cur_coef);
result += ":";
}
strncpy(secret, result.c_str(), result.length());
}
libff::alt_bn128_Fr PolynomialValue(const std::vector<libff::alt_bn128_Fr>& pol, libff::alt_bn128_Fr point, unsigned _t) {
libff::alt_bn128_Fr value = libff::alt_bn128_Fr::zero();
libff::alt_bn128_Fr pow = libff::alt_bn128_Fr::one();
for (size_t i = 0; i < _t; ++i) {
if (i == _t - 1 && pol[i] == libff::alt_bn128_Fr::zero()) {
throw std::runtime_error("Error, incorrect degree of a polynomial");
}
value += pol[i] * pow;
pow *= point;
}
return value;
}
void calc_secret_shares(const char* decrypted_koefs, char * secret_shares,
unsigned _t, unsigned _n) {
// calculate for each node a list of secret values that will be used for verification
std::string result;
char symbol = ':';
std::vector<libff::alt_bn128_Fr> poly = SplitStringToFr(decrypted_koefs, &symbol);
for (size_t i = 0; i < _n; ++i) {
libff::alt_bn128_Fr secret_share = PolynomialValue(poly, libff::alt_bn128_Fr(i + 1), _t);
result += stringFromFr(secret_share);
result += ":";
}
strncpy(secret_shares, result.c_str(), result.length());
}
void calc_public_shares(const char* decrypted_koefs, char * public_shares,
unsigned _t) {
// calculate for each node a list of public shares
std::string result;
char symbol = ':';
std::vector<libff::alt_bn128_Fr> poly = SplitStringToFr(decrypted_koefs, &symbol);
for (size_t i = 0; i < _t; ++i) {
libff::alt_bn128_G2 pub_share = poly.at(i) * libff::alt_bn128_G2::one();
pub_share.to_affine_coordinates();
result += ConvertToString(pub_share.X.c0);
result += ":";
result += ConvertToString(pub_share.X.c1);
result += ":";
result += ConvertToString(pub_share.Y.c0);
result += ":";
result += ConvertToString(pub_share.Y.c1);
result += ",";
}
strncpy(public_shares, result.c_str(), result.length());
}
//
// Created by kladko on 9/5/19.
//
#ifndef SGXD_DKGUTILS_H
#define SGXD_DKGUTILS_H
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
EXTERNC void gen_dkg_poly( char* secret, unsigned _t);
EXTERNC void calc_secret_shares(const char* decrypted_koefs, char * secret_shares,
unsigned _t, unsigned _n);
EXTERNC void calc_public_shares(const char* decrypted_koefs, char * public_shares,
unsigned _t);
#endif //SGXD_DKGUTILS_H
...@@ -85,7 +85,8 @@ CLEANFILES+= secure_enclave_t.c secure_enclave_t.h ...@@ -85,7 +85,8 @@ CLEANFILES+= secure_enclave_t.c secure_enclave_t.h
secure_enclave_SOURCES = secure_enclave_t.c secure_enclave_t.h \ secure_enclave_SOURCES = secure_enclave_t.c secure_enclave_t.h \
secure_enclave.c \ secure_enclave.c \
BLSEnclave.cpp ../trusted_libff/libff/algebra/curves/alt_bn128/alt_bn128_init.cpp \ DKGUtils.cpp BLSUtils.cpp ../trusted_libff/libff/algebra/curves/alt_bn128/alt_bn128_init.cpp \
../trusted_libff/libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp \
../trusted_libff/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp $(ENCLAVE_KEY) $(ENCLAVE_CONFIG) ../trusted_libff/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp $(ENCLAVE_KEY) $(ENCLAVE_CONFIG)
......
This diff is collapsed.
...@@ -339,3 +339,47 @@ void ecdsa_sign_message(int *err_status, char *err_string, uint8_t *encrypted_ke ...@@ -339,3 +339,47 @@ void ecdsa_sign_message(int *err_status, char *err_string, uint8_t *encrypted_ke
*err_status = 0; *err_status = 0;
} }
void gen_dkg_secret (int *err_status, char *err_string, uint8_t *encrypted_dkg_secret, uint32_t* enc_len, size_t _t){
char* dkg_secret = (char*)malloc(DKG_BUFER_LENGTH);
gen_dkg_poly(dkg_secret, _t);
uint32_t sealedLen = sgx_calc_sealed_data_size(0, DKG_BUFER_LENGTH);//sizeof(sgx_sealed_data_t) + sizeof(dkg_secret);
sgx_status_t status = sgx_seal_data(0, NULL, DKG_BUFER_LENGTH, (uint8_t*)dkg_secret, sealedLen,(sgx_sealed_data_t*)encrypted_dkg_secret);
if( status != SGX_SUCCESS) {
snprintf(err_string, BUF_LEN,"SGX seal data failed");
}
*enc_len = sealedLen;
}
void decrypt_dkg_secret (int *err_status, char* err_string, uint8_t* encrypted_dkg_secret, uint8_t* decrypted_dkg_secret, uint32_t enc_len){
//uint32_t dec_size = DKG_BUFER_LENGTH;//sgx_get_encrypt_txt_len( ( sgx_sealed_data_t *)encrypted_dkg_secret);
sgx_status_t status = sgx_unseal_data(
(const sgx_sealed_data_t *)encrypted_dkg_secret, NULL, 0, decrypted_dkg_secret, &enc_len);
if (status != SGX_SUCCESS) {
snprintf(err_string, BUF_LEN,"sgx_unseal_data failed with status %d", status);
return;
}
}
void get_secret_shares(int *err_status, char* err_string, uint8_t* encrypted_dkg_secret, uint32_t enc_len, char* secret_shares,
unsigned _t, unsigned _n){
char* decrypted_dkg_secret = (char*)malloc(DKG_MAX_SEALED_LEN);
decrypt_dkg_secret(err_status, err_string, (uint8_t*)encrypted_dkg_secret, decrypted_dkg_secret, enc_len);
calc_secret_shares(decrypted_dkg_secret, secret_shares, _t, _n);
}
void get_public_shares(int *err_status, char* err_string, uint8_t* encrypted_dkg_secret, uint32_t enc_len, char* public_shares,
unsigned _t, unsigned _n){
char* decrypted_dkg_secret = (char*)malloc(DKG_MAX_SEALED_LEN);
decrypt_dkg_secret(err_status, err_string, (uint8_t*)encrypted_dkg_secret, decrypted_dkg_secret, enc_len);
calc_public_shares(decrypted_dkg_secret, public_shares, _t);
}
...@@ -56,6 +56,38 @@ enclave { ...@@ -56,6 +56,38 @@ enclave {
uint32_t enc_len, uint32_t enc_len,
[in, count = 1024] uint8_t* hash, [in, count = 1024] uint8_t* hash,
[out, count = 1024] char* signature); [out, count = 1024] char* signature);
public void gen_dkg_secret (
[user_check] int *err_status,
[out, count = 1024] char* err_string,
[out, count = 2000] uint8_t* encrypted_dkg_secret,
[user_check] uint32_t * enc_len,
size_t _t);
public void decrypt_dkg_secret (
[user_check] int *err_status,
[out, count = 1024] char* err_string,
[in, count = 2000] uint8_t* encrypted_dkg_secret,
[out, count = 2000] uint8_t* decrypted_dkg_secret,
uint32_t enc_len);
public void get_secret_shares (
[user_check] int *err_status,
[out, count = 1024] char* err_string,
[in, count = 2000] uint8_t* decrypted_dkg_secret,
uint32_t enc_len,
[out, count = 2000] char* secret_shares,
unsigned _t,
unsigned _n);
public void get_public_shares (
[user_check] int *err_status,
[out, count = 1024] char* err_string,
[in, count = 2000] uint8_t* decrypted_dkg_secret,
uint32_t enc_len,
[out, count = 4000] char* public_shares,
unsigned _t,
unsigned _n);
}; };
......
...@@ -44,7 +44,6 @@ void usage() { ...@@ -44,7 +44,6 @@ void usage() {
} }
sgx_launch_token_t token = {0}; sgx_launch_token_t token = {0};
sgx_enclave_id_t eid; sgx_enclave_id_t eid;
sgx_status_t status; sgx_status_t status;
int updated; int updated;
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Created by kladko on 9/3/19. // Created by kladko on 9/3/19.
// //
#ifndef SGXWALLET_SGXWALLET_COMMON_H #ifndef SGXD_SGXD_COMMON_H
#define SGXWALLET_SGXWALLET_COMMON_H #define SGXD_SGXD_COMMON_H
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#define ADD_ENTROPY_SIZE 32 #define ADD_ENTROPY_SIZE 32
#define DKG_BUFER_LENGTH 1250
#define DKG_MAX_SEALED_LEN 2000
#define UNKNOWN_ERROR -1 #define UNKNOWN_ERROR -1
#define PLAINTEXT_KEY_TOO_LONG -2 #define PLAINTEXT_KEY_TOO_LONG -2
......
...@@ -55,6 +55,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ...@@ -55,6 +55,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "catch.hpp" #include "catch.hpp"
std::string stringFromFr(libff::alt_bn128_Fr& el) {
mpz_t t;
mpz_init(t);
el.as_bigint().to_mpz(t);
char arr[mpz_sizeinbase(t, 10) + 2];
char *tmp = mpz_get_str(arr, 10, t);
mpz_clear(t);
return std::string(tmp);
}
void usage() { void usage() {
fprintf(stderr, "usage: sgxwallet\n"); fprintf(stderr, "usage: sgxwallet\n");
exit(1); exit(1);
...@@ -232,10 +248,103 @@ TEST_CASE("KeysDB test", "[keys-db]") { ...@@ -232,10 +248,103 @@ TEST_CASE("KeysDB test", "[keys-db]") {
TEST_CASE("DKG gen test", "[dkg-gen]") { TEST_CASE( "DKG gen test", "[dkg-gen]" ) {
init_all(); init_all();
// put your test here uint8_t* encrypted_dkg_secret = (uint8_t*) calloc(DKG_MAX_SEALED_LEN, 1);
char* errMsg = (char*) calloc(1024,1);
int err_status = 0;
uint32_t enc_len = 0;
status = gen_dkg_secret (eid, &err_status, errMsg, encrypted_dkg_secret, &enc_len, 16);
REQUIRE(status == SGX_SUCCESS);
printf("gen_dkg_secret completed with status: %d %s \n", err_status, errMsg);
printf("\n Length: %d \n", enc_len);
char* secret = (char*)calloc(DKG_MAX_SEALED_LEN, sizeof(char));
char* errMsg1 = (char*) calloc(1024,1);
status = decrypt_dkg_secret(eid, &err_status, errMsg1, encrypted_dkg_secret, (uint8_t*)secret, enc_len);
REQUIRE(status == SGX_SUCCESS);
printf("\ndecrypt_dkg_secret completed with status: %d %s \n", err_status, errMsg1);
printf("decrypted secret %s \n\n", secret);
free(errMsg);
free(errMsg1);
free(encrypted_dkg_secret);
free(secret);
} }
std::vector<libff::alt_bn128_Fr> SplitStringToFr(const char* koefs, const char* symbol){
std::string str(koefs);
std::string delim(symbol);
std::vector<libff::alt_bn128_Fr> tokens;
size_t prev = 0, pos = 0;
do
{
pos = str.find(delim, prev);
if (pos == std::string::npos) pos = str.length();
std::string token = str.substr(prev, pos-prev);
if (!token.empty()) {
libff::alt_bn128_Fr koef(token.c_str());
tokens.push_back(koef);
}
prev = pos + delim.length();
}
while (pos < str.length() && prev < str.length());
return tokens;
}
TEST_CASE( "DKG auto secret shares test", "[dkg-s_shares]" ) {
init_all();
uint8_t* encrypted_dkg_secret = (uint8_t*) calloc(DKG_MAX_SEALED_LEN, 1);
char* errMsg = (char*) calloc(1024,1);
int err_status = 0;
uint32_t enc_len = 0;
unsigned t = 3, n = 4;
status = gen_dkg_secret (eid, &err_status, errMsg, encrypted_dkg_secret, &enc_len, 3);
REQUIRE(status == SGX_SUCCESS);
printf("gen_dkg_secret completed with status: %d %s \n", err_status, errMsg);
printf("\n Length: %d \n", enc_len);
char* errMsg1 = (char*) calloc(1024,1);
char colon = ':';
char* secret_shares = (char*)calloc(DKG_MAX_SEALED_LEN, sizeof(char));
status = get_secret_shares(eid, &err_status, errMsg1, encrypted_dkg_secret, enc_len, secret_shares, t, n);
REQUIRE(status == SGX_SUCCESS);
printf("\nget_secret_shares: %d %s \n", err_status, errMsg1);
printf("secret shares %s \n\n", secret_shares);
std::vector <libff::alt_bn128_Fr> s_shares = SplitStringToFr( secret_shares, &colon);
char* secret = (char*)calloc(DKG_MAX_SEALED_LEN, sizeof(char));
status = decrypt_dkg_secret(eid, &err_status, errMsg1, encrypted_dkg_secret, (uint8_t*)secret, enc_len);
REQUIRE(status == SGX_SUCCESS);
printf("\ndecrypt_dkg_secret completed with status: %d %s \n", err_status, errMsg1);
printf("decrypted secret %s \n\n", secret);
signatures::Dkg dkg_obj(t,n);
std::vector < libff::alt_bn128_Fr> poly = SplitStringToFr((char*)secret, &colon);
std::vector < libff::alt_bn128_Fr> s_shares_dkg = dkg_obj.SecretKeyContribution(SplitStringToFr((char*)secret, &colon));
REQUIRE(s_shares == s_shares_dkg);
free(errMsg);
free(errMsg1);
free(encrypted_dkg_secret);
free(secret_shares);
}
This diff is collapsed.
/** @file
*****************************************************************************
* @author This file is part of libff, developed by SCIPR Lab
* and contributors (see AUTHORS).
* @copyright MIT license (see LICENSE file)
*****************************************************************************/
#ifndef ALT_BN128_G2_HPP_
#define ALT_BN128_G2_HPP_
#include <vector>
#include <libff/algebra/curves/alt_bn128/alt_bn128_init.hpp>
#include <libff/algebra/curves/curve_utils.hpp>
namespace libff {
class alt_bn128_G2;
//std::ostream& operator<<(std::ostream &, const alt_bn128_G2&);
//std::istream& operator>>(std::istream &, alt_bn128_G2&);
class alt_bn128_G2 {
public:
#ifdef PROFILE_OP_COUNTS
static long long add_cnt;
static long long dbl_cnt;
#endif
static std::vector<size_t> wnaf_window_table;
static std::vector<size_t> fixed_base_exp_window_table;
static alt_bn128_G2 G2_zero;
static alt_bn128_G2 G2_one;
typedef alt_bn128_Fq base_field;
typedef alt_bn128_Fq2 twist_field;
typedef alt_bn128_Fr scalar_field;
alt_bn128_Fq2 X, Y, Z;
// using Jacobian coordinates
alt_bn128_G2();
alt_bn128_G2(const alt_bn128_Fq2& X, const alt_bn128_Fq2& Y, const alt_bn128_Fq2& Z) : X(X), Y(Y), Z(Z) {};
static alt_bn128_Fq2 mul_by_b(const alt_bn128_Fq2 &elt);
void print() const;
void print_coordinates() const;
void to_affine_coordinates();
void to_special();
bool is_special() const;
bool is_zero() const;
bool operator==(const alt_bn128_G2 &other) const;
bool operator!=(const alt_bn128_G2 &other) const;
alt_bn128_G2 operator+(const alt_bn128_G2 &other) const;
alt_bn128_G2 operator-() const;
alt_bn128_G2 operator-(const alt_bn128_G2 &other) const;
alt_bn128_G2 add(const alt_bn128_G2 &other) const;
alt_bn128_G2 mixed_add(const alt_bn128_G2 &other) const;
alt_bn128_G2 dbl() const;
alt_bn128_G2 mul_by_q() const;
bool is_well_formed() const;
static alt_bn128_G2 zero();
static alt_bn128_G2 one();
static alt_bn128_G2 random_element();
static size_t size_in_bits() { return twist_field::size_in_bits() + 1; }
static bigint<base_field::num_limbs> base_field_char() { return base_field::field_char(); }
static bigint<scalar_field::num_limbs> order() { return scalar_field::field_char(); }
//friend std::ostream& operator<<(std::ostream &out, const alt_bn128_G2 &g);
//friend std::istream& operator>>(std::istream &in, alt_bn128_G2 &g);
static void batch_to_special_all_non_zeros(std::vector<alt_bn128_G2> &vec);
};
template<mp_size_t m>
alt_bn128_G2 operator*(const bigint<m> &lhs, const alt_bn128_G2 &rhs)
{
return scalar_mul<alt_bn128_G2, m>(rhs, lhs);
}
template<mp_size_t m, const bigint<m>& modulus_p>
alt_bn128_G2 operator*(const Fp_model<m,modulus_p> &lhs, const alt_bn128_G2 &rhs)
{
return scalar_mul<alt_bn128_G2, m>(rhs, lhs.as_bigint());
}
} // libff
#endif // ALT_BN128_G2_HPP_
...@@ -13,9 +13,13 @@ namespace libff { ...@@ -13,9 +13,13 @@ namespace libff {
bigint<alt_bn128_r_limbs> alt_bn128_modulus_r; bigint<alt_bn128_r_limbs> alt_bn128_modulus_r;
bigint<alt_bn128_q_limbs> alt_bn128_modulus_q; bigint<alt_bn128_q_limbs> alt_bn128_modulus_q;
alt_bn128_Fq alt_bn128_coeff_b; alt_bn128_Fq alt_bn128_coeff_b;
alt_bn128_Fq alt_bn128_twist_mul_by_b_c0; alt_bn128_Fq2 alt_bn128_twist;
alt_bn128_Fq alt_bn128_twist_mul_by_b_c1; alt_bn128_Fq2 alt_bn128_twist_coeff_b;
alt_bn128_Fq alt_bn128_twist_mul_by_b_c0;
alt_bn128_Fq alt_bn128_twist_mul_by_b_c1;
alt_bn128_Fq2 alt_bn128_twist_mul_by_q_X;
alt_bn128_Fq2 alt_bn128_twist_mul_by_q_Y;
bigint<alt_bn128_q_limbs> alt_bn128_ate_loop_count; bigint<alt_bn128_q_limbs> alt_bn128_ate_loop_count;
bool alt_bn128_ate_is_loop_count_neg; bool alt_bn128_ate_is_loop_count_neg;
...@@ -82,10 +86,26 @@ void init_alt_bn128_params() ...@@ -82,10 +86,26 @@ void init_alt_bn128_params()
alt_bn128_Fq::nqr = alt_bn128_Fq("3"); alt_bn128_Fq::nqr = alt_bn128_Fq("3");
alt_bn128_Fq::nqr_to_t = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); alt_bn128_Fq::nqr_to_t = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582");
/* parameters for twist field Fq2 */
alt_bn128_Fq2::euler = bigint<2*alt_bn128_q_limbs>("239547588008311421220994022608339370399626158265550411218223901127035046843189118723920525909718935985594116157406550130918127817069793474323196511433944");
alt_bn128_Fq2::s = 4;
alt_bn128_Fq2::t = bigint<2*alt_bn128_q_limbs>("29943448501038927652624252826042421299953269783193801402277987640879380855398639840490065738714866998199264519675818766364765977133724184290399563929243");
alt_bn128_Fq2::t_minus_1_over_2 = bigint<2*alt_bn128_q_limbs>("14971724250519463826312126413021210649976634891596900701138993820439690427699319920245032869357433499099632259837909383182382988566862092145199781964621");
alt_bn128_Fq2::non_residue = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582");
alt_bn128_Fq2::nqr = alt_bn128_Fq2(alt_bn128_Fq("2"),alt_bn128_Fq("1"));
alt_bn128_Fq2::nqr_to_t = alt_bn128_Fq2(alt_bn128_Fq("5033503716262624267312492558379982687175200734934877598599011485707452665730"),alt_bn128_Fq("314498342015008975724433667930697407966947188435857772134235984660852259084"));
alt_bn128_Fq2::Frobenius_coeffs_c1[0] = alt_bn128_Fq("1");
alt_bn128_Fq2::Frobenius_coeffs_c1[1] = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582");
/* choice of short Weierstrass curve and its twist */ /* choice of short Weierstrass curve and its twist */
alt_bn128_coeff_b = alt_bn128_Fq("3"); alt_bn128_coeff_b = alt_bn128_Fq("3");
alt_bn128_coeff_b = alt_bn128_Fq("3");
alt_bn128_twist = alt_bn128_Fq2(alt_bn128_Fq("9"), alt_bn128_Fq("1"));
alt_bn128_twist_coeff_b = alt_bn128_coeff_b * alt_bn128_twist.inverse();
alt_bn128_twist_mul_by_b_c0 = alt_bn128_coeff_b * alt_bn128_Fq2::non_residue;
alt_bn128_twist_mul_by_b_c1 = alt_bn128_coeff_b * alt_bn128_Fq2::non_residue;
/* choice of group G1 */ /* choice of group G1 */
alt_bn128_G1::G1_zero = alt_bn128_G1(alt_bn128_Fq::zero(), alt_bn128_G1::G1_zero = alt_bn128_G1(alt_bn128_Fq::zero(),
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define ALT_BN128_INIT_HPP_ #define ALT_BN128_INIT_HPP_
#include <libff/algebra/curves/public_params.hpp> #include <libff/algebra/curves/public_params.hpp>
#include <libff/algebra/fields/fp.hpp> #include <libff/algebra/fields/fp.hpp>
#include <libff/algebra/fields/fp2.hpp>
namespace libff { namespace libff {
...@@ -23,12 +24,17 @@ extern bigint<alt_bn128_q_limbs> alt_bn128_modulus_q; ...@@ -23,12 +24,17 @@ extern bigint<alt_bn128_q_limbs> alt_bn128_modulus_q;
typedef Fp_model<alt_bn128_r_limbs, alt_bn128_modulus_r> alt_bn128_Fr; typedef Fp_model<alt_bn128_r_limbs, alt_bn128_modulus_r> alt_bn128_Fr;
typedef Fp_model<alt_bn128_q_limbs, alt_bn128_modulus_q> alt_bn128_Fq; typedef Fp_model<alt_bn128_q_limbs, alt_bn128_modulus_q> alt_bn128_Fq;
typedef Fp2_model<alt_bn128_q_limbs, alt_bn128_modulus_q> alt_bn128_Fq2;
// parameters for Barreto--Naehrig curve E/Fq : y^2 = x^3 + b // parameters for Barreto--Naehrig curve E/Fq : y^2 = x^3 + b
extern alt_bn128_Fq alt_bn128_coeff_b; extern alt_bn128_Fq alt_bn128_coeff_b;
// parameters for twisted Barreto--Naehrig curve E'/Fq2 : y^2 = x^3 + b/xi // parameters for twisted Barreto--Naehrig curve E'/Fq2 : y^2 = x^3 + b/xi
extern alt_bn128_Fq alt_bn128_twist_mul_by_b_c0; extern alt_bn128_Fq2 alt_bn128_twist;
extern alt_bn128_Fq alt_bn128_twist_mul_by_b_c1; extern alt_bn128_Fq2 alt_bn128_twist_coeff_b;
extern alt_bn128_Fq alt_bn128_twist_mul_by_b_c0;
extern alt_bn128_Fq alt_bn128_twist_mul_by_b_c1;
extern alt_bn128_Fq2 alt_bn128_twist_mul_by_q_X;
extern alt_bn128_Fq2 alt_bn128_twist_mul_by_q_Y;
// parameters for pairing // parameters for pairing
extern bigint<alt_bn128_q_limbs> alt_bn128_ate_loop_count; extern bigint<alt_bn128_q_limbs> alt_bn128_ate_loop_count;
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include <cstring> #include <cstring>
#include <random> #include <random>
#include <sgx_trts.h>
namespace libff { namespace libff {
template<mp_size_t n> template<mp_size_t n>
...@@ -163,6 +165,30 @@ bool bigint<n>::test_bit(const std::size_t bitno) const ...@@ -163,6 +165,30 @@ bool bigint<n>::test_bit(const std::size_t bitno) const
} }
} }
template<mp_size_t n>
bigint<n>& bigint<n>::randomize()
{
const size_t size = 1;
static_assert(GMP_NUMB_BITS == sizeof(mp_limb_t) * 8, "Wrong GMP_NUMB_BITS value");
//std::random_device rd;
constexpr size_t num_random_words = sizeof(mp_limb_t) * n / size;//sizeof(std::random_device::result_type);
//auto random_words = reinterpret_cast<std::random_device::result_type*>(this->data);
auto random_words = reinterpret_cast<unsigned char*>(this->data);
sgx_read_rand(random_words, num_random_words);
/* auto random_words = reinterpret_cast<unsigned int*>(this->data);
for (size_t i = 0; i < num_random_words; ++i)
{
unsigned char rand[size];
sgx_read_rand(rand, size);
memcpy(&random_words[i], rand, size);
//random_words[i] = rd();
}*/
return (*this);
}
} // libff } // libff
#endif // BIGINT_TCC_ #endif // BIGINT_TCC_
...@@ -684,6 +684,35 @@ Fp_model<n,modulus>& Fp_model<n,modulus>::invert() ...@@ -684,6 +684,35 @@ Fp_model<n,modulus>& Fp_model<n,modulus>::invert()
return *this; return *this;
} }
template<mp_size_t n, const bigint<n>& modulus>
Fp_model<n, modulus> Fp_model<n,modulus>::random_element() /// returns random element of Fp_model
{
/* note that as Montgomery representation is a bijection then
selecting a random element of {xR} is the same as selecting a
random element of {x} */
Fp_model<n, modulus> r;
do
{
r.mont_repr.randomize();
/* clear all bits higher than MSB of modulus */
size_t bitno = GMP_NUMB_BITS * n - 1;
while (modulus.test_bit(bitno) == false)
{
const std::size_t part = bitno/GMP_NUMB_BITS;
const std::size_t bit = bitno - (GMP_NUMB_BITS*part);
r.mont_repr.data[part] &= ~(1ul<<bit);
bitno--;
}
}
/* if r.data is still >= modulus -- repeat (rejection sampling) */
while (mpn_cmp(r.mont_repr.data, modulus.data, n) >= 0);
return r;
}
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
Fp_model<n,modulus> Fp_model<n,modulus>::inverse() const Fp_model<n,modulus> Fp_model<n,modulus>::inverse() const
{ {
......
/** @file
*****************************************************************************
Implementation of arithmetic in the finite field F[p^2].
*****************************************************************************
* @author This file is part of libff, developed by SCIPR Lab
* and contributors (see AUTHORS).
* @copyright MIT license (see LICENSE file)
*****************************************************************************/
#ifndef FP2_HPP_
#define FP2_HPP_
#include <vector>
#include <libff/algebra/fields/fp.hpp>
namespace libff {
template<mp_size_t n, const bigint<n>& modulus>
class Fp2_model;
/*template<mp_size_t n, const bigint<n>& modulus>
std::ostream& operator<<(std::ostream &, const Fp2_model<n, modulus> &);
template<mp_size_t n, const bigint<n>& modulus>
std::istream& operator>>(std::istream &, Fp2_model<n, modulus> &);*/
/**
* Arithmetic in the field F[p^2].
*
* Let p := modulus. This interface provides arithmetic for the extension field
* Fp2 = Fp[U]/(U^2-non_residue), where non_residue is in Fp.
*
* ASSUMPTION: p = 1 (mod 6)
*/
template<mp_size_t n, const bigint<n>& modulus>
class Fp2_model {
public:
typedef Fp_model<n, modulus> my_Fp;
static bigint<2*n> euler; // (modulus^2-1)/2
static size_t s; // modulus^2 = 2^s * t + 1
static bigint<2*n> t; // with t odd
static bigint<2*n> t_minus_1_over_2; // (t-1)/2
static my_Fp non_residue; // X^4-non_residue irreducible over Fp; used for constructing Fp2 = Fp[X] / (X^2 - non_residue)
static Fp2_model<n, modulus> nqr; // a quadratic nonresidue in Fp2
static Fp2_model<n, modulus> nqr_to_t; // nqr^t
static my_Fp Frobenius_coeffs_c1[2]; // non_residue^((modulus^i-1)/2) for i=0,1
my_Fp c0, c1;
Fp2_model() {};
Fp2_model(const my_Fp& c0, const my_Fp& c1) : c0(c0), c1(c1) {};
void clear() { c0.clear(); c1.clear(); }
//void print() const { printf("c0/c1:\n"); c0.print(); c1.print(); }
static Fp2_model<n, modulus> zero();
static Fp2_model<n, modulus> one();
static Fp2_model<n, modulus> random_element();
bool is_zero() const { return c0.is_zero() && c1.is_zero(); }
bool operator==(const Fp2_model &other) const;
bool operator!=(const Fp2_model &other) const;
Fp2_model operator+(const Fp2_model &other) const;
Fp2_model operator-(const Fp2_model &other) const;
Fp2_model operator*(const Fp2_model &other) const;
Fp2_model operator-() const;
Fp2_model squared() const; // default is squared_complex
Fp2_model inverse() const;
Fp2_model Frobenius_map(unsigned long power) const;
Fp2_model sqrt() const; // HAS TO BE A SQUARE (else does not terminate)
Fp2_model squared_karatsuba() const;
Fp2_model squared_complex() const;
template<mp_size_t m>
Fp2_model operator^(const bigint<m> &other) const;
static size_t size_in_bits() { return 2*my_Fp::size_in_bits(); }
static bigint<n> base_field_char() { return modulus; }
// friend std::ostream& operator<< <n, modulus>(std::ostream &out, const Fp2_model<n, modulus> &el);
// friend std::istream& operator>> <n, modulus>(std::istream &in, Fp2_model<n, modulus> &el);
};
/*template<mp_size_t n, const bigint<n>& modulus>
std::ostream& operator<<(std::ostream& out, const std::vector<Fp2_model<n, modulus> > &v);
template<mp_size_t n, const bigint<n>& modulus>
std::istream& operator>>(std::istream& in, std::vector<Fp2_model<n, modulus> > &v); */
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n, modulus> operator*(const Fp_model<n, modulus> &lhs, const Fp2_model<n, modulus> &rhs);
template<mp_size_t n, const bigint<n>& modulus>
bigint<2*n> Fp2_model<n, modulus>::euler;
template<mp_size_t n, const bigint<n>& modulus>
size_t Fp2_model<n, modulus>::s;
template<mp_size_t n, const bigint<n>& modulus>
bigint<2*n> Fp2_model<n, modulus>::t;
template<mp_size_t n, const bigint<n>& modulus>
bigint<2*n> Fp2_model<n, modulus>::t_minus_1_over_2;
template<mp_size_t n, const bigint<n>& modulus>
Fp_model<n, modulus> Fp2_model<n, modulus>::non_residue;
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n, modulus> Fp2_model<n, modulus>::nqr;
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n, modulus> Fp2_model<n, modulus>::nqr_to_t;
template<mp_size_t n, const bigint<n>& modulus>
Fp_model<n, modulus> Fp2_model<n, modulus>::Frobenius_coeffs_c1[2];
} // libff
#include <libff/algebra/fields/fp2.tcc>
#endif // FP2_HPP_
/** @file
*****************************************************************************
Implementation of arithmetic in the finite field F[p^2].
*****************************************************************************
* @author This file is part of libff, developed by SCIPR Lab
* and contributors (see AUTHORS).
* @copyright MIT license (see LICENSE file)
*****************************************************************************/
#ifndef FP2_TCC_
#define FP2_TCC_
#include <libff/algebra/fields/field_utils.hpp>
namespace libff {
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::zero()
{
return Fp2_model<n, modulus>(my_Fp::zero(), my_Fp::zero());
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::one()
{
return Fp2_model<n, modulus>(my_Fp::one(), my_Fp::zero());
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::random_element()
{
Fp2_model<n, modulus> r;
r.c0 = my_Fp::random_element();
r.c1 = my_Fp::random_element();
return r;
}
template<mp_size_t n, const bigint<n>& modulus>
bool Fp2_model<n,modulus>::operator==(const Fp2_model<n,modulus> &other) const
{
return (this->c0 == other.c0 && this->c1 == other.c1);
}
template<mp_size_t n, const bigint<n>& modulus>
bool Fp2_model<n,modulus>::operator!=(const Fp2_model<n,modulus> &other) const
{
return !(operator==(other));
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::operator+(const Fp2_model<n,modulus> &other) const
{
return Fp2_model<n,modulus>(this->c0 + other.c0,
this->c1 + other.c1);
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::operator-(const Fp2_model<n,modulus> &other) const
{
return Fp2_model<n,modulus>(this->c0 - other.c0,
this->c1 - other.c1);
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n, modulus> operator*(const Fp_model<n, modulus> &lhs, const Fp2_model<n, modulus> &rhs)
{
return Fp2_model<n,modulus>(lhs*rhs.c0,
lhs*rhs.c1);
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::operator*(const Fp2_model<n,modulus> &other) const
{
/* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Karatsuba) */
const my_Fp
&A = other.c0, &B = other.c1,
&a = this->c0, &b = this->c1;
const my_Fp aA = a * A;
const my_Fp bB = b * B;
return Fp2_model<n,modulus>(aA + non_residue * bB,
(a + b)*(A+B) - aA - bB);
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::operator-() const
{
return Fp2_model<n,modulus>(-this->c0,
-this->c1);
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::squared() const
{
return squared_complex();
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::squared_karatsuba() const
{
/* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Karatsuba squaring) */
const my_Fp &a = this->c0, &b = this->c1;
const my_Fp asq = a.squared();
const my_Fp bsq = b.squared();
return Fp2_model<n,modulus>(asq + non_residue * bsq,
(a + b).squared() - asq - bsq);
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::squared_complex() const
{
/* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Complex squaring) */
const my_Fp &a = this->c0, &b = this->c1;
const my_Fp ab = a * b;
return Fp2_model<n,modulus>((a + b) * (a + non_residue * b) - ab - non_residue * ab,
ab + ab);
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::inverse() const
{
const my_Fp &a = this->c0, &b = this->c1;
/* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves"; Algorithm 8 */
const my_Fp t0 = a.squared();
const my_Fp t1 = b.squared();
const my_Fp t2 = t0 - non_residue * t1;
const my_Fp t3 = t2.inverse();
const my_Fp c0 = a * t3;
const my_Fp c1 = - (b * t3);
return Fp2_model<n,modulus>(c0, c1);
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::Frobenius_map(unsigned long power) const
{
return Fp2_model<n,modulus>(c0,
Frobenius_coeffs_c1[power % 2] * c1);
}
template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::sqrt() const
{
Fp2_model<n,modulus> one = Fp2_model<n,modulus>::one();
size_t v = Fp2_model<n,modulus>::s;
Fp2_model<n,modulus> z = Fp2_model<n,modulus>::nqr_to_t;
Fp2_model<n,modulus> w = (*this)^Fp2_model<n,modulus>::t_minus_1_over_2;
Fp2_model<n,modulus> x = (*this) * w;
Fp2_model<n,modulus> b = x * w; // b = (*this)^t
#if DEBUG
// check if square with euler's criterion
Fp2_model<n,modulus> check = b;
for (size_t i = 0; i < v-1; ++i)
{
check = check.squared();
}
if (check != one)
{
assert(0);
}
#endif
// compute square root with Tonelli--Shanks
// (does not terminate if not a square!)
while (b != one)
{
size_t m = 0;
Fp2_model<n,modulus> b2m = b;
while (b2m != one)
{
/* invariant: b2m = b^(2^m) after entering this loop */
b2m = b2m.squared();
m += 1;
}
int j = v-m-1;
w = z;
while (j > 0)
{
w = w.squared();
--j;
} // w = z^2^(v-m-1)
z = w.squared();
b = b * z;
x = x * w;
v = m;
}
return x;
}
template<mp_size_t n, const bigint<n>& modulus>
template<mp_size_t m>
Fp2_model<n,modulus> Fp2_model<n,modulus>::operator^(const bigint<m> &pow) const
{
return power<Fp2_model<n, modulus>, m>(*this, pow);
}
/*template<mp_size_t n, const bigint<n>& modulus>
std::ostream& operator<<(std::ostream &out, const Fp2_model<n, modulus> &el)
{
out << el.c0 << OUTPUT_SEPARATOR << el.c1;
return out;
}
template<mp_size_t n, const bigint<n>& modulus>
std::istream& operator>>(std::istream &in, Fp2_model<n, modulus> &el)
{
in >> el.c0 >> el.c1;
return in;
}
template<mp_size_t n, const bigint<n>& modulus>
std::ostream& operator<<(std::ostream& out, const std::vector<Fp2_model<n, modulus> > &v)
{
out << v.size() << "\n";
for (const Fp2_model<n, modulus>& t : v)
{
out << t << OUTPUT_NEWLINE;
}
return out;
}
template<mp_size_t n, const bigint<n>& modulus>
std::istream& operator>>(std::istream& in, std::vector<Fp2_model<n, modulus> > &v)
{
v.clear();
size_t s;
in >> s;
char b;
in.read(&b, 1);
v.reserve(s);
for (size_t i = 0; i < s; ++i)
{
Fp2_model<n, modulus> el;
in >> el;
v.emplace_back(el);
}
return in;
}*/
} // libff
#endif // FP2_TCC_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment