forked from lthn/blockchain
1) zarcanum math moved to separate file; 2) fixed an error in rhs calculation; 3) 2^64 constant + test
This commit is contained in:
parent
c2771a075e
commit
af9c53794e
7 changed files with 73 additions and 9 deletions
|
|
@ -13,6 +13,7 @@ namespace crypto
|
|||
const point_g_t c_point_G;
|
||||
|
||||
const scalar_t c_scalar_1 = { 1 };
|
||||
const scalar_t c_scalar_2p64 = { 0, 1, 0, 0 };
|
||||
const scalar_t c_scalar_L = { 0x5812631a5cf5d3ed, 0x14def9dea2f79cd6, 0x0, 0x1000000000000000 };
|
||||
const scalar_t c_scalar_Lm1 = { 0x5812631a5cf5d3ec, 0x14def9dea2f79cd6, 0x0, 0x1000000000000000 };
|
||||
const scalar_t c_scalar_P = { 0xffffffffffffffed, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff };
|
||||
|
|
|
|||
|
|
@ -456,6 +456,7 @@ namespace crypto
|
|||
//
|
||||
|
||||
extern const scalar_t c_scalar_1;
|
||||
extern const scalar_t c_scalar_2p64;
|
||||
extern const scalar_t c_scalar_L;
|
||||
extern const scalar_t c_scalar_Lm1;
|
||||
extern const scalar_t c_scalar_P;
|
||||
|
|
|
|||
33
src/crypto/zarcanum.cpp
Normal file
33
src/crypto/zarcanum.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2022 Zano Project
|
||||
// Copyright (c) 2022 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
//
|
||||
// Note: This file originates from tests/functional_tests/crypto_tests.cpp
|
||||
#include "zarcanum.h"
|
||||
namespace crypto
|
||||
{
|
||||
const scalar_t c_zarcanum_z_coeff_s = 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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) )
|
||||
}
|
||||
|
||||
bool zarcanum_check_main_pos_inequality(const hash& kernel_hash, const scalar_t& blinding_mask, const scalar_t& secret_q,
|
||||
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::uint256_t& rhs)
|
||||
{
|
||||
scalar_t lhs_s = scalar_t(kernel_hash) * (blinding_mask + secret_q + last_pow_block_id_hashed); // == h * (f + q + f') mod l
|
||||
lhs = lhs_s.as_boost_mp_type<mp::uint256_t>();
|
||||
rhs = z_l_div_z_D * stake_amount; // == floor( l / (z * D) ) * z * a
|
||||
|
||||
return lhs < rhs; // h * (f + q + f') mod l < floor( l / (z * D) ) * z * a
|
||||
}
|
||||
|
||||
} // namespace crypto
|
||||
25
src/crypto/zarcanum.h
Normal file
25
src/crypto/zarcanum.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2022 Zano Project
|
||||
// Copyright (c) 2022 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
//
|
||||
// Note: This file originates from tests/functional_tests/crypto_tests.cpp
|
||||
#pragma once
|
||||
#include "crypto-sugar.h"
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
namespace crypto
|
||||
{
|
||||
namespace mp = boost::multiprecision;
|
||||
|
||||
extern const mp::uint256_t c_zarcanum_z_coeff_mp;
|
||||
extern const scalar_t c_zarcanum_z_coeff_s;
|
||||
|
||||
mp::uint256_t zarcanum_precalculate_l_div_z_D(const mp::uint128_t& pos_difficulty);
|
||||
mp::uint256_t zarcanum_precalculate_z_l_div_z_D(const mp::uint128_t& pos_difficulty);
|
||||
|
||||
bool zarcanum_check_main_pos_inequality(const hash& kernel_hash, const scalar_t& blinding_mask, const scalar_t& secret_q,
|
||||
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::uint256_t& rhs);
|
||||
|
||||
|
||||
} // namespace crypto
|
||||
|
|
@ -38,6 +38,7 @@ using namespace epee;
|
|||
#include "storages/levin_abstract_invoke2.h"
|
||||
#include "common/variant_helper.h"
|
||||
#include "currency_core/crypto_config.h"
|
||||
#include "crypto/zarcanum.h"
|
||||
|
||||
using namespace currency;
|
||||
|
||||
|
|
@ -3636,7 +3637,7 @@ bool wallet2::fill_mining_context(mining_context& ctx)
|
|||
// Zarcanum (PoS with hidden amounts)
|
||||
ctx.zarcanum = true;
|
||||
ctx.last_pow_block_id_hashed = crypto::hash_helper_t::hs(CRYPTO_HDS_ZARCANUM_LAST_POW_HASH, ctx.sk.stake_modifier.last_pow_id);
|
||||
ctx.l_div_z_D = crypto::c_scalar_L.as_boost_mp_type<boost::multiprecision::uint256_t>() / (ctx.basic_diff);
|
||||
ctx.z_l_div_z_D = crypto::zarcanum_precalculate_z_l_div_z_D(ctx.basic_diff);
|
||||
}
|
||||
|
||||
ctx.last_block_hash = pos_details_resp.last_block_hash;
|
||||
|
|
@ -3718,12 +3719,13 @@ bool wallet2::do_pos_mining_iteration(mining_context& context, size_t transfer_i
|
|||
|
||||
if (context.zarcanum && td.is_zc())
|
||||
{
|
||||
PROFILE_FUNC("check_zarcanum");
|
||||
crypto::scalar_t lhs_s = crypto::scalar_t(kernel_hash) * (*td.m_opt_blinding_mask + context.secret_q + context.last_pow_block_id_hashed); // == h * (f + q + f') mod l
|
||||
boost::multiprecision::uint256_t lhs = lhs_s.as_boost_mp_type<boost::multiprecision::uint256_t>();
|
||||
boost::multiprecision::uint256_t rhs = context.l_div_z_D * stake_amount; // == floor( l / (z * D) ) * a
|
||||
|
||||
if (lhs < rhs)
|
||||
crypto::mp::uint256_t lhs, rhs;
|
||||
{
|
||||
PROFILE_FUNC("check_zarcanum");
|
||||
found = crypto::zarcanum_check_main_pos_inequality(kernel_hash, *td.m_opt_blinding_mask, context.secret_q, context.last_pow_block_id_hashed, context.z_l_div_z_D, stake_amount, lhs, rhs);
|
||||
++context.iterations_processed;
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
found = true;
|
||||
LOG_PRINT_GREEN("Found Zarcanum kernel: amount: " << currency::print_money_brief(stake_amount) << ", gindex: " << td.m_global_output_index << ENDL
|
||||
|
|
@ -3736,7 +3738,6 @@ bool wallet2::do_pos_mining_iteration(mining_context& context, size_t transfer_i
|
|||
, LOG_LEVEL_0);
|
||||
|
||||
}
|
||||
++context.iterations_processed;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ namespace tools
|
|||
|
||||
crypto::scalar_t last_pow_block_id_hashed; // Zarcanum notation: f'
|
||||
crypto::scalar_t secret_q; // Zarcanum notation: q
|
||||
boost::multiprecision::uint256_t l_div_z_D; // Zarcanum notation: floor( l / (z * D) ) (max possible value: 2^252 / (2^64 * 1) ~= 2^188, or 2^252 / (1 * 1) = 2^252)
|
||||
boost::multiprecision::uint256_t z_l_div_z_D; // Zarcanum notation: z * floor( l / (z * D) ) (max possible value: 2^64 * 2^252 / (2^64 * 1) ~= 2^252, or 2^252 / (1 * 1) = 2^252)
|
||||
|
||||
currency::wide_difficulty_type basic_diff;
|
||||
currency::stake_kernel sk;
|
||||
|
|
|
|||
|
|
@ -863,6 +863,9 @@ TEST(crypto, scalar_basics)
|
|||
mp::uint256_t mp_p_mod_l = c_scalar_P.as_boost_mp_type<mp::uint256_t>() % c_scalar_L.as_boost_mp_type<mp::uint256_t>();
|
||||
ASSERT_EQ(p, scalar_t(mp_p_mod_l));
|
||||
|
||||
ASSERT_EQ(c_scalar_2p64 - c_scalar_1, scalar_t(UINT64_MAX));
|
||||
ASSERT_EQ(c_scalar_2p64, scalar_t(UINT64_MAX) + c_scalar_1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue