1
0
Fork 0
forked from lthn/blockchain
blockchain/src/crypto/range_proofs.h
2025-09-30 16:48:13 +01:00

159 lines
5.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Boolberry developers
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; the MIT terms are therefore
// considered “grandfathered” under the EUPL for this code.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#pragma once
#include "epee/include/misc_log_ex.h"
#include "crypto-sugar.h"
namespace crypto
{
// returns x + x^2 + x^3 + ... + x^(2^f)
// == x * (x + 1) * (x^2 + 1) * (x^4 + 1) * ...(x^(f+1) + 1)
inline scalar_t sum_of_powers(scalar_t x, size_t f)
{
scalar_t result = x;
for (size_t i = 0; i < f; ++i)
{
result.assign_muladd(result, x, result);
x *= x;
}
return result;
}
// returns least significant bit uing de Bruijn sequence
// http://graphics.stanford.edu/~seander/bithacks.html
inline uint8_t calc_lsb_32(uint32_t v)
{
static const uint8_t multiply_de_bruijn_bit_position[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
return multiply_de_bruijn_bit_position[((uint32_t)((v & -(int32_t)v) * 0x077CB531U)) >> 27];
}
////////////////////////////////////////
// crypto trait for Zano
////////////////////////////////////////
struct bpp_ct_generators_HGX
{
// NOTE! This notation follows the original BP+ whitepaper, see mapping to Zano's generators in range_proofs.cpp
static const point_t& bpp_G;
static const point_t& bpp_H;
static const point_t& bpp_H2;
};
struct bpp_ct_generators_UGX
{
// NOTE! This notation follows the original BP+ whitepaper, see mapping to Zano's generators in range_proofs.cpp
static const point_t& bpp_G;
static const point_t& bpp_H;
static const point_t& bpp_H2;
};
template<typename gen_trait_t, size_t N = 64, size_t values_max = 32>
struct bpp_crypto_trait_zano : gen_trait_t
{
static constexpr size_t c_bpp_n = N; // the upper bound for the witness's range
static constexpr size_t c_bpp_values_max = values_max; // maximum number of elements in BP+ proof, i.e. max allowed BP+ outputs
static constexpr size_t c_bpp_log2_n = constexpr_ceil_log2(c_bpp_n);
static constexpr size_t c_bpp_mn_max = c_bpp_n * c_bpp_values_max;
static void calc_pedersen_commitment(const scalar_t& value, const scalar_t& mask, point_t& commitment)
{
// commitment = value * bpp_G + mask * bpp_H
commitment = operator*(value, bpp_G) + mask * bpp_H;
}
static void calc_pedersen_commitment_2(const scalar_t& value, const scalar_t& mask1, const scalar_t& mask2, point_t& commitment)
{
// commitment = value * bpp_G + mask1 * bpp_H * mask2 * bpp_H2
commitment = operator*(value, bpp_G) + mask1 * bpp_H + mask2 * bpp_H2;
}
static const scalar_t& get_initial_transcript()
{
static scalar_t value = hash_helper_t::hs("Lethean BP+ initial transcript");
return value;
}
// assumes hsc is cleared
static void update_transcript(hash_helper_t::hs_t& hsc, scalar_t& e, const std::vector<point_t>& points)
{
hsc.add_scalar(e);
hsc.add_points_array(points);
e = hsc.calc_hash();
}
// assumes hsc is cleared
static void update_transcript(hash_helper_t::hs_t& hsc, scalar_t& e, const std::vector<const public_key*>& pub_keys)
{
hsc.add_scalar(e);
for(auto p : pub_keys)
hsc.add_pub_key(*p);
e = hsc.calc_hash();
}
// TODO: refactor with proper OOB handling
static const point_t& get_generator(bool select_H, size_t index)
{
if (index >= c_bpp_mn_max)
return c_point_0; // out of bound
static std::vector<point_t> generators(2 * c_bpp_mn_max);
static bool calculated = false;
if (!calculated)
{
scalar_t hash_buf[2] = { hash_helper_t::hs("Lethean BP+ generator"), 0 };
for (size_t i = 0; i < 2 * c_bpp_mn_max; ++i)
{
hash_buf[1].m_u64[0] = i;
ge_bytes_hash_to_ec(&generators[i].m_p3, &hash_buf, sizeof hash_buf);
}
calculated = true;
}
return generators[2 * index + (select_H ? 1 : 0)];
}
static const scalar_t& get_2_to_the_power_of_N_minus_1()
{
static scalar_t result = scalar_t::power_of_2(c_bpp_n) - 1;
return result;
}
using gen_trait_t::bpp_G;
using gen_trait_t::bpp_H;
using gen_trait_t::bpp_H2;
}; // struct bpp_crypto_trait_zano
typedef bpp_crypto_trait_zano<bpp_ct_generators_UGX, 64, 32> bpp_crypto_trait_ZC_out;
typedef bpp_crypto_trait_zano<bpp_ct_generators_HGX, 128, 16> bpp_crypto_trait_Zarcanum;
} // namespace crypto
#include "epee/include/profile_tools.h" // <- remove this, sowle
#include "msm.h"
#include "range_proof_bpp.h"
#include "range_proof_bppe.h"