forked from lthn/blockchain
crypto: zarcanum signature generation partially done (work in progress)
This commit is contained in:
parent
49e78fdbae
commit
7a1a4b0058
6 changed files with 186 additions and 7 deletions
|
|
@ -4,19 +4,25 @@
|
|||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
//
|
||||
// Note: This file originates from tests/functional_tests/crypto_tests.cpp
|
||||
#include "epee/include/misc_log_ex.h"
|
||||
#include "zarcanum.h"
|
||||
#include "crypto/range_proofs.h"
|
||||
#include "../currency_core/crypto_config.h" // TODO: move it to the crypto
|
||||
|
||||
namespace crypto
|
||||
{
|
||||
const scalar_t c_zarcanum_z_coeff_s = c_scalar_2p64;
|
||||
const scalar_t c_zarcanum_z_coeff_s = { 0, 1, 0, 0 }; // c_scalar_2p64
|
||||
const mp::uint256_t c_zarcanum_z_coeff_mp = c_zarcanum_z_coeff_s.as_boost_mp_type<mp::uint256_t>();
|
||||
|
||||
mp::uint256_t zarcanum_precalculate_l_div_z_D(const mp::uint128_t& pos_difficulty)
|
||||
{
|
||||
//LOG_PRINT_GREEN_L0(ENDL << "floor( l / (z * D) ) = " << c_scalar_L.as_boost_mp_type<mp::uint256_t>() / (c_zarcanum_z_coeff_mp * pos_difficulty));
|
||||
return c_scalar_L.as_boost_mp_type<mp::uint256_t>() / (c_zarcanum_z_coeff_mp * pos_difficulty); // == floor( l / (z * D) )
|
||||
}
|
||||
|
||||
mp::uint256_t zarcanum_precalculate_z_l_div_z_D(const mp::uint128_t& pos_difficulty)
|
||||
{
|
||||
//LOG_PRINT_GREEN_L0(ENDL << "z * floor( l / (z * D) ) = " << c_zarcanum_z_coeff_mp * (c_scalar_L.as_boost_mp_type<mp::uint256_t>() / (c_zarcanum_z_coeff_mp * pos_difficulty)));
|
||||
return c_zarcanum_z_coeff_mp * (c_scalar_L.as_boost_mp_type<mp::uint256_t>() / (c_zarcanum_z_coeff_mp * pos_difficulty)); // == z * floor( l / (z * D) )
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +33,127 @@ namespace crypto
|
|||
lhs = lhs_s.as_boost_mp_type<mp::uint256_t>();
|
||||
rhs = static_cast<mp::uint512_t>(z_l_div_z_D) * stake_amount; // == floor( l / (z * D) ) * z * a
|
||||
|
||||
//LOG_PRINT_GREEN_L0(ENDL <<
|
||||
// "z_l_div_z_D = " << z_l_div_z_D << ENDL <<
|
||||
// "stake_amount = " << stake_amount << ENDL <<
|
||||
// "lhs = " << lhs << ENDL <<
|
||||
// "rhs = " << rhs);
|
||||
|
||||
return lhs < rhs; // h * (f + q + f') mod l < floor( l / (z * D) ) * z * a
|
||||
}
|
||||
|
||||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("zarcanum_generate_proof: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
bool zarcanum_generate_proof(const hash& kernel_hash, const public_key& commitment_1div8, const scalar_t& blinding_mask, const scalar_t& secret_q,
|
||||
const scalar_t& last_pow_block_id_hashed, uint64_t stake_amount, zarcanum_proof& result, uint8_t* p_err)
|
||||
{
|
||||
const scalar_t a = stake_amount;
|
||||
const scalar_t h = scalar_t(kernel_hash);
|
||||
const scalar_t f_plus_q = blinding_mask + secret_q;
|
||||
const scalar_t f_plus_q_plus_fp = f_plus_q + last_pow_block_id_hashed;
|
||||
const scalar_t lhs = h * f_plus_q_plus_fp; // == h * (f + q + f') mod l
|
||||
const mp::uint256_t d_mp = lhs.as_boost_mp_type<mp::uint256_t>() / (c_zarcanum_z_coeff_mp * stake_amount) + 1;
|
||||
result.d = scalar_t(d_mp);
|
||||
|
||||
const scalar_t dz = result.d * c_zarcanum_z_coeff_s;
|
||||
|
||||
const scalar_t ba = dz * a - lhs; // b_a = dza - h(f + q + f')
|
||||
|
||||
const scalar_t bf = dz * f_plus_q - h * a; // b_f = dz(f + q) - ha
|
||||
|
||||
const scalar_t x0 = scalar_t::random(), x1 = scalar_t::random(), x2 = scalar_t::random();
|
||||
|
||||
const scalar_t bx = x2 - h * x1 + dz * x0; // b_x = x'' - hx' + dzx
|
||||
|
||||
point_t C = x0 * c_point_X + a * c_point_H + f_plus_q * c_point_G;
|
||||
point_t C_prime = x1 * c_point_X + f_plus_q * c_point_H + a * c_point_G;
|
||||
point_t E = bx * c_point_X + ba * c_point_H + bf * c_point_G;
|
||||
|
||||
result.C = C.to_public_key();
|
||||
result.C_prime = C_prime.to_public_key();
|
||||
result.E = E.to_public_key();
|
||||
|
||||
// three proofs with a shared Fiat-Shamir challenge c
|
||||
// 1) linear composition proof for the fact, that C + C' = lin(X, H + G) = (x + x') X + (a + f + q) (H + G)
|
||||
// 2) linear composition proof for the fact, that C - C' = lin(X, H - G) = (x - x') X + (a - f - q) (H - G)
|
||||
// 3) Schnorr proof for the fact, that hC' - dzC + E + f'hH = lin(X) = x'' X
|
||||
|
||||
point_t F = h * C_prime - dz * C + E + last_pow_block_id_hashed * h * c_point_H;
|
||||
|
||||
scalar_t r0 = scalar_t::random();
|
||||
scalar_t r1 = scalar_t::random();
|
||||
scalar_t r2 = scalar_t::random();
|
||||
scalar_t r3 = scalar_t::random();
|
||||
scalar_t r4 = scalar_t::random();
|
||||
|
||||
point_t R_01 = r0 * c_point_X + r1 * c_point_H_plus_G;
|
||||
point_t R_23 = r2 * c_point_X + r3 * c_point_H_minus_G;
|
||||
point_t R_4 = r4 * c_point_G;
|
||||
|
||||
hash_helper_t::hs_t hash_calc(3);
|
||||
hash_calc.add_32_chars(CRYPTO_HDS_ZARCANUM_PROOF_HASH);
|
||||
hash_calc.add_point(R_01);
|
||||
hash_calc.add_point(R_23);
|
||||
hash_calc.add_point(R_4);
|
||||
hash_calc.add_point(C + C_prime);
|
||||
hash_calc.add_point(C - C_prime);
|
||||
hash_calc.add_point(F);
|
||||
result.c = hash_calc.calc_hash();
|
||||
|
||||
result.y0 = r0 + result.c * (x0 + x1); // y_0 = r_0 + c (x + x')
|
||||
result.y1 = r1 + result.c * (a + f_plus_q); // y_1 = r_1 + c (a + f + q)
|
||||
result.y2 = r2 + result.c * (x0 - x1); // y_2 = r_2 + c (x - x')
|
||||
result.y3 = r3 + result.c * (a - f_plus_q); // y_3 = r_3 + c (a - f - q)
|
||||
result.y4 = r4 + result.c * x2; // y_4 = r_4 + c x''
|
||||
|
||||
// range proof for E
|
||||
const scalar_vec_t values = { a }; // H component
|
||||
const scalar_vec_t masks = { bf }; // G component
|
||||
const scalar_vec_t masks2 = { bx }; // X component
|
||||
const std::vector<const public_key*> commitments_1div8 = { &commitment_1div8 };
|
||||
|
||||
if (!bppe_gen<bpp_crypto_trait_zano<>>(values, masks, masks2, commitments_1div8, result.E_range_proof, p_err))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// = four-layers ring signature data outline =
|
||||
// (j in [0, ring_size-1])
|
||||
// layer 0 ring
|
||||
// se.outputs[j].stealth_address;
|
||||
// layer 0 secret (with respect to G)
|
||||
// in_contexts[i].in_ephemeral.sec;
|
||||
// layer 0 linkability
|
||||
// in.k_image;
|
||||
//
|
||||
// layer 1 ring
|
||||
// crypto::point_t(se.outputs[j].amount_commitment) - pseudo_out_amount_commitment;
|
||||
// layer 1 secret (with respect to G)
|
||||
// se.real_out_amount_blinding_mask - blinding_mask;
|
||||
//
|
||||
// additional layers for Zarcanum:
|
||||
//
|
||||
// layer 2 ring
|
||||
// C - A[j] - Q[j]
|
||||
// layer 2 secret (with respect to X)
|
||||
// x0
|
||||
//
|
||||
// layer 3 ring
|
||||
// Q[j]
|
||||
// layer 3 secret (with respect to G)
|
||||
// secret_q
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zarcanum_verify_proof(const hash& kernel_hash, const public_key& commitment_1div8, const scalar_t& last_pow_block_id_hashed, const zarcanum_proof& proof, uint8_t* p_err /* = nullptr */)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace crypto
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
// Note: This file originates from tests/functional_tests/crypto_tests.cpp
|
||||
#pragma once
|
||||
#include "crypto-sugar.h"
|
||||
#include "crypto/range_proof_bppe.h"
|
||||
#include "crypto/clsag.h"
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
namespace crypto
|
||||
|
|
@ -22,4 +24,31 @@ namespace crypto
|
|||
const scalar_t& last_pow_block_id_hashed, const mp::uint256_t& z_l_div_z_D_, uint64_t stake_amount, mp::uint256_t& lhs, mp::uint512_t& rhs);
|
||||
|
||||
|
||||
struct zarcanum_proof
|
||||
{
|
||||
scalar_t d = 0;
|
||||
public_key C;
|
||||
public_key C_prime;
|
||||
public_key E;
|
||||
|
||||
scalar_t c; // shared Fiat-Shamir challenge for the following three proofs
|
||||
scalar_t y0; // 1st linear composition proof
|
||||
scalar_t y1; // ( C + C' = lin(X, H + G) )
|
||||
scalar_t y2; // 2nd linear composition proof
|
||||
scalar_t y3; // ( C - C' = lin(X, H - G) )
|
||||
scalar_t y4; // Schnorr proof (F = lin(X))
|
||||
|
||||
bppe_signature E_range_proof;
|
||||
CLSAG_GGXG_signature ring_sig;
|
||||
};
|
||||
|
||||
bool zarcanum_generate_proof(const hash& kernel_hash, const public_key& stake_commitment_1div8, const scalar_t& last_pow_block_id_hashed,
|
||||
const scalar_t& blinding_mask, const scalar_t& secret_q, uint64_t stake_amount,
|
||||
uint64_t secret_index,
|
||||
zarcanum_proof& result, uint8_t* p_err = nullptr);
|
||||
|
||||
|
||||
|
||||
bool zarcanum_verify_proof(const hash& kernel_hash, const public_key& commitment_1div8, const scalar_t& last_pow_block_id_hashed, const zarcanum_proof& proof, uint8_t* p_err = nullptr);
|
||||
|
||||
} // namespace crypto
|
||||
|
|
|
|||
|
|
@ -22,3 +22,4 @@
|
|||
|
||||
#define CRYPTO_HDS_ZARCANUM_LAST_POW_HASH "ZANO_HDS_ZARCANUM_LAST_POW_HASH"
|
||||
#define CRYPTO_HDS_ZARCANUM_SECRET_Q "ZANO_HDS_ZARCANUM_SECRET_Q_____"
|
||||
#define CRYPTO_HDS_ZARCANUM_PROOF_HASH "ZANO_HDS_ZARCANUM_PROOF_HASH___"
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "crypto/crypto.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "crypto/range_proofs.h"
|
||||
#include "crypto/zarcanum.h"
|
||||
#include "misc_language.h"
|
||||
#include "block_flags.h"
|
||||
#include "etc_custom_serialization.h"
|
||||
|
|
@ -482,6 +483,22 @@ namespace currency
|
|||
END_BOOST_SERIALIZATION()
|
||||
};
|
||||
|
||||
|
||||
struct zarcanum_sig : public crypto::zarcanum_proof
|
||||
{
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELD(d)
|
||||
FIELD(C)
|
||||
// TODO
|
||||
END_SERIALIZE()
|
||||
|
||||
BEGIN_BOOST_SERIALIZATION()
|
||||
BOOST_SERIALIZE(d)
|
||||
BOOST_SERIALIZE(C)
|
||||
// TODO
|
||||
END_BOOST_SERIALIZATION()
|
||||
};
|
||||
|
||||
//#pragma pack(pop)
|
||||
|
||||
typedef boost::variant<txin_gen, txin_to_key, txin_multisig, txin_htlc, txin_zc_input> txin_v;
|
||||
|
|
@ -803,8 +820,7 @@ namespace currency
|
|||
END_BOOST_SERIALIZATION()
|
||||
};
|
||||
|
||||
|
||||
typedef boost::variant<NLSAG_sig, void_sig, ZC_sig> signature_v;
|
||||
typedef boost::variant<NLSAG_sig, void_sig, ZC_sig, zarcanum_sig> signature_v;
|
||||
|
||||
|
||||
|
||||
|
|
@ -1077,10 +1093,11 @@ SET_VARIANT_TAGS(crypto::bppe_signature_serialized, 41, "bppe_signature_serializ
|
|||
SET_VARIANT_TAGS(currency::NLSAG_sig, 42, "NLSAG_sig");
|
||||
SET_VARIANT_TAGS(currency::ZC_sig, 43, "ZC_sig");
|
||||
SET_VARIANT_TAGS(currency::void_sig, 44, "void_sig");
|
||||
SET_VARIANT_TAGS(currency::zc_outs_range_proof, 45, "zc_outs_range_proof");
|
||||
SET_VARIANT_TAGS(currency::zc_balance_proof, 46, "zc_balance_proof");
|
||||
SET_VARIANT_TAGS(currency::zarcanum_sig, 45, "zarcanum_sig");
|
||||
SET_VARIANT_TAGS(currency::zc_outs_range_proof, 46, "zc_outs_range_proof");
|
||||
SET_VARIANT_TAGS(currency::zc_balance_proof, 47, "zc_balance_proof");
|
||||
|
||||
SET_VARIANT_TAGS(currency::open_asset_id, 47, "asset_id");
|
||||
SET_VARIANT_TAGS(currency::open_asset_id, 48, "asset_id");
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3901,7 +3901,12 @@ namespace currency
|
|||
//@#@ TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool operator ==(const currency::zarcanum_sig& a, const currency::zarcanum_sig& b)
|
||||
{
|
||||
//@#@ TODO
|
||||
return false;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
bool verify_multiple_zc_outs_range_proofs(const std::vector<zc_outs_range_proofs_with_commitments>& range_proofs)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ namespace currency
|
|||
bool operator ==(const currency::NLSAG_sig& a, const currency::NLSAG_sig& b);
|
||||
bool operator ==(const currency::void_sig& a, const currency::void_sig& b);
|
||||
bool operator ==(const currency::ZC_sig& a, const currency::ZC_sig& b);
|
||||
bool operator ==(const currency::zarcanum_sig& a, const currency::zarcanum_sig& b);
|
||||
|
||||
typedef boost::multiprecision::uint128_t uint128_tl;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue