Mapping blinding crypto to fc ecc api

This commit is contained in:
Daniel Larimer 2015-06-10 18:34:19 -04:00
parent 969768cdd5
commit a824aa04a9
4 changed files with 207 additions and 12 deletions

View file

@ -289,6 +289,9 @@ ENDIF()
add_executable( api tests/api.cpp )
target_link_libraries( api fc )
#add_executable( blind tests/blind.cpp )
#target_link_libraries( blind fc ${ECC_LIB} )
include_directories( vendor/websocketpp )
add_executable( ntp_test ntp_test.cpp )

View file

@ -141,34 +141,33 @@ namespace fc {
struct range_proof_info
{
uint8_t exp;
uint8_t mantissa;
int exp;
int mantissa;
uint64_t min_value;
uint64_t max_value;
std::vector<char> proof;
};
commitment_type blind( const blind_factor_type& blind, uint64_t value );
commitment_type blind_sum( const std::vector<blind_factor_type>& blinds, uint32_t non_neg );
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 std::vector<char>& proof );
bool verify_range( uint64_t& min_val, uint64_t& max_val, const commitment_type& commit, const std::vector<char>& proof );
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,
uint8_t base10_exp,
int8_t base10_exp,
uint8_t min_bits,
uint64_t actual_value
);
bool verify_range_rewind( blind_factor_type& blind_out,
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,
uint64_t& min_val,
uint64_t& max_val,
commitment_type commit,
const std::vector<char>& proof );
range_proof_info range_get_info( const std::vector<char>& proof );
@ -218,4 +217,4 @@ namespace fc {
FC_REFLECT_TYPENAME( fc::ecc::private_key )
FC_REFLECT_TYPENAME( fc::ecc::public_key )
FC_REFLECT( fc::ecc::range_proof_info, (exp)(mantissa)(min_value)(max_value)(proof) )
FC_REFLECT( fc::ecc::range_proof_info, (exp)(mantissa)(min_value)(max_value) )

View file

@ -16,13 +16,14 @@ namespace fc { namespace ecc {
namespace detail
{
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;
}
void _init_lib() {
static const secp256k1_context_t* ctx = _get_context();
static int init_o = init_openssl();
(void)ctx;
}
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( 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;
}
} }

90
tests/blind.cpp Normal file
View file

@ -0,0 +1,90 @@
#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 C1 = fc::ecc::blind( B1, 1 );
auto C2 = fc::ecc::blind( B2, 2 );
auto c3 = fc::ecc::blind( b3, 3 );
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 ) );
{
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;
}