Merge branch 'github_master'
This commit is contained in:
commit
18e80eca23
6 changed files with 243 additions and 183 deletions
|
|
@ -24,7 +24,7 @@ SET( DEFAULT_LIBRARY_INSTALL_DIR lib/ )
|
||||||
SET( DEFAULT_EXECUTABLE_INSTALL_DIR bin/ )
|
SET( DEFAULT_EXECUTABLE_INSTALL_DIR bin/ )
|
||||||
SET( CMAKE_DEBUG_POSTFIX _debug )
|
SET( CMAKE_DEBUG_POSTFIX _debug )
|
||||||
SET( BUILD_SHARED_LIBS NO )
|
SET( BUILD_SHARED_LIBS NO )
|
||||||
SET( ECC_IMPL openssl CACHE STRING "openssl or secp256k1 or mixed" )
|
SET( ECC_IMPL secp256k1 CACHE STRING "secp256k1 or openssl or mixed" )
|
||||||
|
|
||||||
set(platformBitness 32)
|
set(platformBitness 32)
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
|
@ -169,7 +169,6 @@ set( fc_sources
|
||||||
src/crypto/rand.cpp
|
src/crypto/rand.cpp
|
||||||
src/crypto/salsa20.cpp
|
src/crypto/salsa20.cpp
|
||||||
#src/crypto/scrypt.cpp
|
#src/crypto/scrypt.cpp
|
||||||
src/crypto/romix.cpp
|
|
||||||
src/network/tcp_socket.cpp
|
src/network/tcp_socket.cpp
|
||||||
src/network/udp_socket.cpp
|
src/network/udp_socket.cpp
|
||||||
src/network/udt_socket.cpp
|
src/network/udt_socket.cpp
|
||||||
|
|
@ -289,6 +288,9 @@ ENDIF()
|
||||||
add_executable( api tests/api.cpp )
|
add_executable( api tests/api.cpp )
|
||||||
target_link_libraries( api fc )
|
target_link_libraries( api fc )
|
||||||
|
|
||||||
|
#add_executable( blind tests/blind.cpp )
|
||||||
|
#target_link_libraries( blind fc )
|
||||||
|
|
||||||
include_directories( vendor/websocketpp )
|
include_directories( vendor/websocketpp )
|
||||||
|
|
||||||
add_executable( ntp_test ntp_test.cpp )
|
add_executable( ntp_test ntp_test.cpp )
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,14 @@ namespace fc {
|
||||||
class private_key_impl;
|
class private_key_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef fc::sha256 blind_factor_type;
|
||||||
|
typedef fc::array<char,33> commitment_type;
|
||||||
typedef fc::array<char,33> public_key_data;
|
typedef fc::array<char,33> public_key_data;
|
||||||
typedef fc::sha256 private_key_secret;
|
typedef fc::sha256 private_key_secret;
|
||||||
typedef fc::array<char,65> public_key_point_data; ///< the full non-compressed version of the ECC point
|
typedef fc::array<char,65> public_key_point_data; ///< the full non-compressed version of the ECC point
|
||||||
typedef fc::array<char,72> signature;
|
typedef fc::array<char,72> signature;
|
||||||
typedef fc::array<unsigned char,65> compact_signature;
|
typedef fc::array<unsigned char,65> compact_signature;
|
||||||
|
typedef std::vector<char> range_proof_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class public_key
|
* @class public_key
|
||||||
|
|
@ -134,6 +137,44 @@ namespace fc {
|
||||||
static fc::sha256 get_secret( const EC_KEY * const k );
|
static fc::sha256 get_secret( const EC_KEY * const k );
|
||||||
fc::fwd<detail::private_key_impl,32> my;
|
fc::fwd<detail::private_key_impl,32> my;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct range_proof_info
|
||||||
|
{
|
||||||
|
int exp;
|
||||||
|
int mantissa;
|
||||||
|
uint64_t min_value;
|
||||||
|
uint64_t max_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
commitment_type blind( const blind_factor_type& blind, uint64_t value );
|
||||||
|
blind_factor_type blind_sum( const std::vector<blind_factor_type>& blinds, uint32_t non_neg );
|
||||||
|
/** verifies taht commnits + neg_commits + excess == 0 */
|
||||||
|
bool verify_sum( const std::vector<commitment_type>& commits, const std::vector<commitment_type>& neg_commits, int64_t excess );
|
||||||
|
bool verify_range( uint64_t& min_val, uint64_t& max_val, const commitment_type& commit, const range_proof_type& proof );
|
||||||
|
|
||||||
|
range_proof_type range_proof_sign( uint64_t min_value,
|
||||||
|
const commitment_type& commit,
|
||||||
|
const blind_factor_type& commit_blind,
|
||||||
|
const blind_factor_type& nonce,
|
||||||
|
int8_t base10_exp,
|
||||||
|
uint8_t min_bits,
|
||||||
|
uint64_t actual_value
|
||||||
|
);
|
||||||
|
|
||||||
|
bool verify_range_proof_rewind( blind_factor_type& blind_out,
|
||||||
|
uint64_t& value_out,
|
||||||
|
string& message_out,
|
||||||
|
const blind_factor_type& nonce,
|
||||||
|
uint64_t& min_val,
|
||||||
|
uint64_t& max_val,
|
||||||
|
commitment_type commit,
|
||||||
|
const range_proof_type& proof );
|
||||||
|
range_proof_info range_get_info( const range_proof_type& proof );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace ecc
|
} // namespace ecc
|
||||||
void to_variant( const ecc::private_key& var, variant& vo );
|
void to_variant( const ecc::private_key& var, variant& vo );
|
||||||
void from_variant( const variant& var, ecc::private_key& vo );
|
void from_variant( const variant& var, ecc::private_key& vo );
|
||||||
|
|
@ -177,3 +218,4 @@ namespace fc {
|
||||||
|
|
||||||
FC_REFLECT_TYPENAME( fc::ecc::private_key )
|
FC_REFLECT_TYPENAME( fc::ecc::private_key )
|
||||||
FC_REFLECT_TYPENAME( fc::ecc::public_key )
|
FC_REFLECT_TYPENAME( fc::ecc::public_key )
|
||||||
|
FC_REFLECT( fc::ecc::range_proof_info, (exp)(mantissa)(min_value)(max_value) )
|
||||||
|
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
// Most of this file has been ported from EncryptionUtils.cpp from BitcoinArmory:
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// //
|
|
||||||
// Copyright(C) 2011-2013, Armory Technologies, Inc. //
|
|
||||||
// Distributed under the GNU Affero General Public License (AGPL v3) //
|
|
||||||
// See LICENSE or http://www.gnu.org/licenses/agpl.html //
|
|
||||||
// //
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// For the KDF:
|
|
||||||
//
|
|
||||||
// This technique is described in Colin Percival's paper on memory-hard
|
|
||||||
// key-derivation functions, used to create "scrypt":
|
|
||||||
//
|
|
||||||
// http://www.tarsnap.com/scrypt/scrypt.pdf
|
|
||||||
//
|
|
||||||
// The goal is to create a key-derivation function that can force a memory
|
|
||||||
// requirement on the thread applying the KDF. By picking a sequence-length
|
|
||||||
// of 1,000,000, each thread will require 32 MB of memory to compute the keys,
|
|
||||||
// which completely disarms GPUs of their massive parallelization capabilities
|
|
||||||
// (for maximum parallelization, the kernel must use less than 1-2 MB/thread)
|
|
||||||
//
|
|
||||||
// Even with less than 1,000,000 hashes, as long as it requires more than 64
|
|
||||||
// kB of memory, a GPU will have to store the computed lookup tables in global
|
|
||||||
// memory, which is extremely slow for random lookup. As a result, GPUs are
|
|
||||||
// no better (and possibly much worse) than a CPU for brute-forcing the passwd
|
|
||||||
//
|
|
||||||
// This KDF is actually the ROMIX algorithm described on page 6 of Colin's
|
|
||||||
// paper. This was chosen because it is the simplest technique that provably
|
|
||||||
// achieves the goal of being secure, and memory-hard.
|
|
||||||
//
|
|
||||||
// The computeKdfParams method well test the speed of the system it is running
|
|
||||||
// on, and try to pick the largest memory-size the system can compute in less
|
|
||||||
// than 0.25s (or specified target).
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// NOTE: If you are getting an error about invalid argument types, from python,
|
|
||||||
// it is usually because you passed in a BinaryData/Python-string instead
|
|
||||||
// of a SecureBinaryData object
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace fc {
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// A memory-bound key-derivation function -- uses a variation of Colin
|
|
||||||
// Percival's ROMix algorithm: http://www.tarsnap.com/scrypt/scrypt.pdf
|
|
||||||
//
|
|
||||||
// The computeKdfParams method takes in a target time, T, for computation
|
|
||||||
// on the computer executing the test. The final KDF should take somewhere
|
|
||||||
// between T/2 and T seconds.
|
|
||||||
class romix
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
romix(uint32_t memReqts, uint32_t numIter, std::string salt);
|
|
||||||
|
|
||||||
std::string deriveKey_OneIter(std::string const & password);
|
|
||||||
std::string deriveKey(std::string const & password);
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint32_t hashOutputBytes_;
|
|
||||||
uint32_t kdfOutputBytes_; // size of final key data
|
|
||||||
|
|
||||||
uint32_t memoryReqtBytes_;
|
|
||||||
uint32_t sequenceCount_;
|
|
||||||
std::string salt_; // prob not necessary amidst numIter, memReqts
|
|
||||||
// but I guess it can't hurt
|
|
||||||
|
|
||||||
uint32_t numIterations_; // We set the ROMIX params for a given memory
|
|
||||||
// req't. Then run it numIter times to meet
|
|
||||||
// the computation-time req't
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -16,13 +16,14 @@ namespace fc { namespace ecc {
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
const secp256k1_context_t* _get_context() {
|
const secp256k1_context_t* _get_context() {
|
||||||
static secp256k1_context_t* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN);
|
static secp256k1_context_t* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_RANGEPROOF | SECP256K1_CONTEXT_COMMIT );
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _init_lib() {
|
void _init_lib() {
|
||||||
static const secp256k1_context_t* ctx = _get_context();
|
static const secp256k1_context_t* ctx = _get_context();
|
||||||
static int init_o = init_openssl();
|
static int init_o = init_openssl();
|
||||||
|
(void)ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
class public_key_impl
|
class public_key_impl
|
||||||
|
|
@ -149,4 +150,106 @@ namespace fc { namespace ecc {
|
||||||
FC_ASSERT( secp256k1_ecdsa_recover_compact( detail::_get_context(), (unsigned char*) digest.data(), (unsigned char*) c.begin() + 1, (unsigned char*) my->_key.begin(), (int*) &pk_len, 1, (*c.begin() - 27) & 3 ) );
|
FC_ASSERT( secp256k1_ecdsa_recover_compact( detail::_get_context(), (unsigned char*) digest.data(), (unsigned char*) c.begin() + 1, (unsigned char*) my->_key.begin(), (int*) &pk_len, 1, (*c.begin() - 27) & 3 ) );
|
||||||
FC_ASSERT( pk_len == my->_key.size() );
|
FC_ASSERT( pk_len == my->_key.size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
commitment_type blind( const blind_factor_type& blind, uint64_t value )
|
||||||
|
{
|
||||||
|
commitment_type result;
|
||||||
|
FC_ASSERT( secp256k1_pedersen_commit( detail::_get_context(), (unsigned char*)&result, (unsigned char*)&blind, value ) );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
blind_factor_type blind_sum( const std::vector<blind_factor_type>& blinds_in, uint32_t non_neg )
|
||||||
|
{
|
||||||
|
blind_factor_type result;
|
||||||
|
std::vector<const unsigned char*> blinds(blinds_in.size());
|
||||||
|
for( uint32_t i = 0; i < blinds_in.size(); ++i ) blinds[i] = (const unsigned char*)&blinds_in[i];
|
||||||
|
FC_ASSERT( secp256k1_pedersen_blind_sum( detail::_get_context(), (unsigned char*)&result, blinds.data(), blinds_in.size(), non_neg ) );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** verifies taht commnits + neg_commits + excess == 0 */
|
||||||
|
bool verify_sum( const std::vector<commitment_type>& commits_in, const std::vector<commitment_type>& neg_commits_in, int64_t excess )
|
||||||
|
{
|
||||||
|
std::vector<const unsigned char*> commits(commits_in.size());
|
||||||
|
for( uint32_t i = 0; i < commits_in.size(); ++i ) commits[i] = (const unsigned char*)&commits_in[i];
|
||||||
|
std::vector<const unsigned char*> neg_commits(neg_commits_in.size());
|
||||||
|
for( uint32_t i = 0; i < neg_commits_in.size(); ++i ) neg_commits[i] = (const unsigned char*)&neg_commits_in[i];
|
||||||
|
|
||||||
|
return secp256k1_pedersen_verify_tally( detail::_get_context(), commits.data(), commits.size(), neg_commits.data(), neg_commits.size(), excess );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool verify_range( uint64_t& min_val, uint64_t& max_val, const commitment_type& commit, const std::vector<char>& proof )
|
||||||
|
{
|
||||||
|
return secp256k1_rangeproof_verify( detail::_get_context(), &min_val, &max_val, (const unsigned char*)&commit, (const unsigned char*)proof.data(), proof.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> range_proof_sign( uint64_t min_value,
|
||||||
|
const commitment_type& commit,
|
||||||
|
const blind_factor_type& commit_blind,
|
||||||
|
const blind_factor_type& nonce,
|
||||||
|
int8_t base10_exp,
|
||||||
|
uint8_t min_bits,
|
||||||
|
uint64_t actual_value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int proof_len = 5134;
|
||||||
|
std::vector<char> proof(proof_len);
|
||||||
|
|
||||||
|
FC_ASSERT( secp256k1_rangeproof_sign( detail::_get_context(),
|
||||||
|
(unsigned char*)proof.data(),
|
||||||
|
&proof_len, min_value,
|
||||||
|
(const unsigned char*)&commit,
|
||||||
|
(const unsigned char*)&commit_blind,
|
||||||
|
(const unsigned char*)&nonce,
|
||||||
|
base10_exp, min_bits, actual_value ) );
|
||||||
|
proof.resize(proof_len);
|
||||||
|
return proof;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool verify_range_proof_rewind( blind_factor_type& blind_out,
|
||||||
|
uint64_t& value_out,
|
||||||
|
string& message_out,
|
||||||
|
const blind_factor_type& nonce,
|
||||||
|
uint64_t& min_val,
|
||||||
|
uint64_t& max_val,
|
||||||
|
commitment_type commit,
|
||||||
|
const std::vector<char>& proof )
|
||||||
|
{
|
||||||
|
char msg[4096];
|
||||||
|
int mlen = 0;
|
||||||
|
FC_ASSERT( secp256k1_rangeproof_rewind( detail::_get_context(),
|
||||||
|
(unsigned char*)&blind_out,
|
||||||
|
&value_out,
|
||||||
|
(unsigned char*)msg,
|
||||||
|
&mlen,
|
||||||
|
(const unsigned char*)&nonce,
|
||||||
|
&min_val,
|
||||||
|
&max_val,
|
||||||
|
(const unsigned char*)&commit,
|
||||||
|
(const unsigned char*)proof.data(),
|
||||||
|
proof.size() ) );
|
||||||
|
|
||||||
|
message_out = std::string( msg, mlen );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
range_proof_info range_get_info( const std::vector<char>& proof )
|
||||||
|
{
|
||||||
|
range_proof_info result;
|
||||||
|
FC_ASSERT( secp256k1_rangeproof_info( detail::_get_context(),
|
||||||
|
(int*)&result.exp,
|
||||||
|
(int*)&result.mantissa,
|
||||||
|
(uint64_t*)&result.min_value,
|
||||||
|
(uint64_t*)&result.max_value,
|
||||||
|
(const unsigned char*)proof.data(),
|
||||||
|
(int)proof.size() ) );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
// Most of this file has been ported from EncryptionUtils.cpp from BitcoinArmory:
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// //
|
|
||||||
// Copyright(C) 2011-2013, Armory Technologies, Inc. //
|
|
||||||
// Distributed under the GNU Affero General Public License (AGPL v3) //
|
|
||||||
// See LICENSE or http://www.gnu.org/licenses/agpl.html //
|
|
||||||
// //
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <fc/crypto/sha256.hpp>
|
|
||||||
#include <fc/crypto/sha512.hpp>
|
|
||||||
#include <fc/crypto/romix.hpp>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
namespace fc
|
|
||||||
{
|
|
||||||
romix::romix( uint32_t memReqts, uint32_t numIter, std::string salt ) :
|
|
||||||
hashOutputBytes_( 64 ),
|
|
||||||
kdfOutputBytes_( 32 )
|
|
||||||
{
|
|
||||||
memoryReqtBytes_ = memReqts;
|
|
||||||
sequenceCount_ = memoryReqtBytes_ / hashOutputBytes_;
|
|
||||||
numIterations_ = numIter;
|
|
||||||
salt_ = salt;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string romix::deriveKey_OneIter( std::string const & password )
|
|
||||||
{
|
|
||||||
static fc::sha512 sha512;
|
|
||||||
|
|
||||||
// Concatenate the salt/IV to the password
|
|
||||||
std::string saltedPassword = password + salt_;
|
|
||||||
|
|
||||||
// Prepare the lookup table
|
|
||||||
char *lookupTable_ = new char[memoryReqtBytes_];
|
|
||||||
uint32_t const HSZ = hashOutputBytes_;
|
|
||||||
|
|
||||||
// First hash to seed the lookup table, input is variable length anyway
|
|
||||||
fc::sha512 hash = sha512.hash(saltedPassword);
|
|
||||||
memcpy(lookupTable_, &hash, HSZ);
|
|
||||||
|
|
||||||
// Compute <sequenceCount_> consecutive hashes of the passphrase
|
|
||||||
// Every iteration is stored in the next 64-bytes in the Lookup table
|
|
||||||
for( uint32_t nByte = 0; nByte < memoryReqtBytes_ - HSZ; nByte += HSZ )
|
|
||||||
{
|
|
||||||
// Compute hash of slot i, put result in slot i+1
|
|
||||||
fc::sha512 hash = sha512.hash(lookupTable_ + nByte, HSZ);
|
|
||||||
memcpy(lookupTable_ + nByte + HSZ, &hash, HSZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
// LookupTable should be complete, now start lookup sequence.
|
|
||||||
// Start with the last hash from the previous step
|
|
||||||
std::string X(lookupTable_ + memoryReqtBytes_ - HSZ, HSZ);
|
|
||||||
std::string Y(HSZ, '0');
|
|
||||||
|
|
||||||
// We "integerize" a hash value by taking the last 4 bytes of
|
|
||||||
// as a u_int32_t, and take modulo sequenceCount
|
|
||||||
uint64_t* X64ptr = (uint64_t*)(X.data());
|
|
||||||
uint64_t* Y64ptr = (uint64_t*)(Y.data());
|
|
||||||
uint64_t* V64ptr = NULL;
|
|
||||||
uint32_t newIndex;
|
|
||||||
uint32_t const nXorOps = HSZ / sizeof(uint64_t);
|
|
||||||
|
|
||||||
// Pure ROMix would use sequenceCount_ for the number of lookups.
|
|
||||||
// We divide by 2 to reduce computation time RELATIVE to the memory usage
|
|
||||||
// This still provides suffient LUT operations, but allows us to use more
|
|
||||||
// memory in the same amount of time (and this is the justification for
|
|
||||||
// the scrypt algorithm -- it is basically ROMix, modified for more
|
|
||||||
// flexibility in controlling compute-time vs memory-usage).
|
|
||||||
uint32_t const nLookups = sequenceCount_ / 2;
|
|
||||||
for(uint32_t nSeq=0; nSeq<nLookups; nSeq++)
|
|
||||||
{
|
|
||||||
// Interpret last 4 bytes of last result (mod seqCt) as next LUT index
|
|
||||||
newIndex = *(uint32_t*)(X.data()+HSZ-4) % sequenceCount_;
|
|
||||||
|
|
||||||
// V represents the hash result at <newIndex>
|
|
||||||
V64ptr = (uint64_t*)(lookupTable_ + HSZ * newIndex);
|
|
||||||
|
|
||||||
// xor X with V, and store the result in X
|
|
||||||
for(uint32_t i = 0; i < nXorOps; i++)
|
|
||||||
*(Y64ptr + i) = *(X64ptr + i) ^ *(V64ptr + i);
|
|
||||||
|
|
||||||
// Hash the xor'd data to get the next index for lookup
|
|
||||||
fc::sha512 hash = sha512.hash(Y.data(), HSZ);
|
|
||||||
X.assign(hash.data(), HSZ);
|
|
||||||
}
|
|
||||||
// Truncate the final result to get the final key
|
|
||||||
delete lookupTable_;
|
|
||||||
return X.substr(0, kdfOutputBytes_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string romix::deriveKey( std::string const & password )
|
|
||||||
{
|
|
||||||
std::string masterKey(password);
|
|
||||||
for(uint32_t i=0; i<numIterations_; i++)
|
|
||||||
masterKey = deriveKey_OneIter(masterKey);
|
|
||||||
|
|
||||||
return masterKey;
|
|
||||||
}
|
|
||||||
} // namespace fc
|
|
||||||
93
tests/blind.cpp
Normal file
93
tests/blind.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
#include <fc/crypto/elliptic.hpp>
|
||||||
|
#include <fc/log/logger.hpp>
|
||||||
|
#include <fc/io/raw.hpp>
|
||||||
|
#include <fc/variant.hpp>
|
||||||
|
#include <fc/reflect/variant.hpp>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include </Users/dlarimer/Downloads/secp256k1-zkp/src/libsecp256k1-config.h>
|
||||||
|
#include </Users/dlarimer/Downloads/secp256k1-zkp/src/scalar.h>
|
||||||
|
#include <secp256k1.h>
|
||||||
|
}
|
||||||
|
//struct secp256k1_scalar_t { uint64_t v[4]; };
|
||||||
|
//extern "C" { void secp256k1_scalar_get_b32(unsigned char *bin, const struct secp256k1_scalar_t* a); }
|
||||||
|
|
||||||
|
int main( int argc, char** argv )
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
auto InB1 = fc::sha256::hash("InB1");
|
||||||
|
auto InB2 = fc::sha256::hash("InB2");
|
||||||
|
auto OutB1 = fc::sha256::hash("OutB1");
|
||||||
|
|
||||||
|
|
||||||
|
auto InC1 = fc::ecc::blind(InB1,25);
|
||||||
|
auto InC2 = fc::ecc::blind(InB2,75);
|
||||||
|
|
||||||
|
auto OutC1 = fc::ecc::blind(OutB1,40);
|
||||||
|
|
||||||
|
auto OutB2 = fc::ecc::blind_sum( {InB1,InB2,OutB1}, 2 );
|
||||||
|
auto OutC2 = fc::ecc::blind( OutB2, 60 );
|
||||||
|
|
||||||
|
FC_ASSERT( fc::ecc::verify_sum( {InC1,InC2}, {OutC1,OutC2}, 0 ) );
|
||||||
|
auto nonce = fc::sha256::hash("nonce");
|
||||||
|
|
||||||
|
auto proof = fc::ecc::range_proof_sign( 0, OutC1, OutB1, nonce, 0, 0, 40 );
|
||||||
|
wdump( (proof.size()));
|
||||||
|
|
||||||
|
auto result = fc::ecc::range_get_info( proof );
|
||||||
|
wdump((result));
|
||||||
|
FC_ASSERT( result.max_value >= 60 );
|
||||||
|
FC_ASSERT( result.min_value >= 0 );
|
||||||
|
|
||||||
|
|
||||||
|
auto B1 = fc::sha256::hash("B1");
|
||||||
|
auto B2 = fc::sha256::hash("B2");
|
||||||
|
auto b3 = fc::sha256::hash("b3");
|
||||||
|
auto B4 = fc::sha256::hash("B4");
|
||||||
|
auto C1 = fc::ecc::blind( B1, 1 );
|
||||||
|
auto C2 = fc::ecc::blind( B2, 2 );
|
||||||
|
auto c3 = fc::ecc::blind( b3, 3 );
|
||||||
|
auto C4 = fc::ecc::blind( B4, -1 );
|
||||||
|
|
||||||
|
auto B3 = fc::ecc::blind_sum( {B1,B2}, 2 );
|
||||||
|
auto C3 = fc::ecc::blind( B3, 3 );
|
||||||
|
|
||||||
|
|
||||||
|
auto B2m1 = fc::ecc::blind_sum( {B2,B1}, 1 );
|
||||||
|
auto C2m1 = fc::ecc::blind( B2m1, 1 );
|
||||||
|
|
||||||
|
FC_ASSERT( fc::ecc::verify_sum( {C1,C2}, {C3}, 0 ) );
|
||||||
|
FC_ASSERT( fc::ecc::verify_sum( {C3}, {C1,C2}, 0 ) );
|
||||||
|
FC_ASSERT( fc::ecc::verify_sum( {C3}, {C1,C2}, 0 ) );
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
auto B1 = fc::sha256::hash("B1");
|
||||||
|
auto B2 = fc::sha256::hash("B2");
|
||||||
|
auto B3 = fc::sha256::hash("B3");
|
||||||
|
|
||||||
|
//secp256k1_scalar_get_b32((unsigned char*)&B1, (const secp256k1_scalar_t*)&B2);
|
||||||
|
//B1 = fc::variant("b2e5da56ef9f2a34d3e22fd12634bc99261e95c87b9960bf94ed3d27b30").as<fc::sha256>();
|
||||||
|
|
||||||
|
auto C1 = fc::ecc::blind( B1, INT64_MAX );
|
||||||
|
auto C2 = fc::ecc::blind( B1, 0 );
|
||||||
|
auto C3 = fc::ecc::blind( B1, 1 );
|
||||||
|
|
||||||
|
FC_ASSERT( fc::ecc::verify_sum( {C2}, {C3}, -1 ) );
|
||||||
|
FC_ASSERT( fc::ecc::verify_sum( {C1}, {C1}, 0 ) );
|
||||||
|
FC_ASSERT( fc::ecc::verify_sum( {C2}, {C2}, 0 ) );
|
||||||
|
FC_ASSERT( fc::ecc::verify_sum( {C3}, {C2}, 1 ) );
|
||||||
|
FC_ASSERT( fc::ecc::verify_sum( {C1}, {C2}, INT64_MAX ) );
|
||||||
|
FC_ASSERT( fc::ecc::verify_sum( {C2}, {C1}, -INT64_MAX ) );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( const fc::exception& e )
|
||||||
|
{
|
||||||
|
edump((e.to_detail_string()));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue