Extract CryptoNote crypto sources from upstream (fa1608cf). Build as static libcryptonote.a via CMake with compat stubs for external dependencies (warnings, logging, varint, profiling). 37 upstream files, 10 compat stubs, 680KB static library. Co-Authored-By: Charon <charon@lethean.io>
159 lines
5.1 KiB
C++
Executable file
159 lines
5.1 KiB
C++
Executable file
// 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.
|
||
//
|
||
// SPDX‑License‑Identifier: 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"
|