Use statics on the Rust side for generators

This commit is contained in:
Luke Parker 2024-05-23 21:16:25 -04:00 committed by j-berman
parent 42f6ef273d
commit c792b21535
7 changed files with 53 additions and 137 deletions

@ -72,17 +72,6 @@ struct SelenePoint {
// ----- End deps C bindings -----
template<typename T = void>
struct Box;
struct HeliosGenerators {
void* generators;
};
struct SeleneGenerators {
void* generators;
};
template<typename T>
struct CResult {
T value;
@ -100,14 +89,9 @@ using HeliosScalarSlice = Slice<HeliosScalar>;
using SeleneScalarSlice = Slice<SeleneScalar>;
extern "C" {
HeliosPoint helios_hash_init_point();
HeliosGenerators random_helios_generators(uintptr_t n);
SeleneGenerators random_selene_generators(uintptr_t n);
HeliosPoint random_helios_hash_init_point();
SelenePoint random_selene_hash_init_point();
SelenePoint selene_hash_init_point();
uint8_t *helios_scalar_to_bytes(HeliosScalar helios_scalar);
@ -127,14 +111,12 @@ HeliosScalar helios_zero_scalar();
SeleneScalar selene_zero_scalar();
CResult<HeliosPoint> hash_grow_helios(const HeliosGenerators *helios_generators,
HeliosPoint existing_hash,
CResult<HeliosPoint> hash_grow_helios(HeliosPoint existing_hash,
uintptr_t offset,
HeliosScalarSlice prior_children,
HeliosScalarSlice new_children);
CResult<SelenePoint> hash_grow_selene(const SeleneGenerators *selene_generators,
SelenePoint existing_hash,
CResult<SelenePoint> hash_grow_selene(SelenePoint existing_hash,
uintptr_t offset,
SeleneScalarSlice prior_children,
SeleneScalarSlice new_children);

@ -1,4 +1,4 @@
use std::io;
use std::{io, sync::OnceLock};
use rand_core::OsRng;
@ -21,39 +21,36 @@ use full_chain_membership_proofs::tree::hash_grow;
// TODO: Use a macro to de-duplicate some of of this code
#[repr(C)]
pub struct HeliosGenerators {
generators: Box<Generators<RecommendedTranscript, Helios>>,
pub const HELIOS_GENERATORS_LENGTH: usize = 128;
pub const SELENE_GENERATORS_LENGTH: usize = 256;
static HELIOS_GENERATORS: OnceLock<Generators<RecommendedTranscript, Helios>> = OnceLock::new();
static SELENE_GENERATORS: OnceLock<Generators<RecommendedTranscript, Selene>> = OnceLock::new();
static HELIOS_HASH_INIT: OnceLock<HeliosPoint> = OnceLock::new();
static SELENE_HASH_INIT: OnceLock<SelenePoint> = OnceLock::new();
// TODO: Don't use random generators
fn helios_generators() -> &'static Generators<RecommendedTranscript, Helios> {
HELIOS_GENERATORS.get_or_init(|| {
generalized_bulletproofs::tests::generators::<Helios>(HELIOS_GENERATORS_LENGTH)
})
}
#[repr(C)]
pub struct SeleneGenerators {
generators: Box<Generators<RecommendedTranscript, Selene>>,
fn selene_generators() -> &'static Generators<RecommendedTranscript, Selene> {
SELENE_GENERATORS.get_or_init(|| {
generalized_bulletproofs::tests::generators::<Selene>(SELENE_GENERATORS_LENGTH)
})
}
#[no_mangle]
pub extern "C" fn random_helios_generators(n: usize) -> HeliosGenerators {
let helios_generators = generalized_bulletproofs::tests::generators::<Helios>(n);
HeliosGenerators {
generators: Box::new(helios_generators),
}
pub extern "C" fn helios_hash_init_point() -> HeliosPoint {
*HELIOS_HASH_INIT.get_or_init(|| HeliosPoint::random(&mut OsRng))
}
#[no_mangle]
pub extern "C" fn random_selene_generators(n: usize) -> SeleneGenerators {
let selene_generators = generalized_bulletproofs::tests::generators::<Selene>(n);
SeleneGenerators {
generators: Box::new(selene_generators),
}
}
#[no_mangle]
pub extern "C" fn random_helios_hash_init_point() -> HeliosPoint {
HeliosPoint::random(&mut OsRng)
}
#[no_mangle]
pub extern "C" fn random_selene_hash_init_point() -> SelenePoint {
SelenePoint::random(&mut OsRng)
pub extern "C" fn selene_hash_init_point() -> SelenePoint {
*SELENE_HASH_INIT.get_or_init(|| SelenePoint::random(&mut OsRng))
}
fn c_u8_32(bytes: [u8; 32]) -> *const u8 {
@ -154,14 +151,13 @@ impl<T, E> CResult<T, E> {
#[no_mangle]
pub extern "C" fn hash_grow_helios(
helios_generators: &HeliosGenerators,
existing_hash: HeliosPoint,
offset: usize,
prior_children: HeliosScalarSlice,
new_children: HeliosScalarSlice,
) -> CResult<HeliosPoint, io::Error> {
let hash = hash_grow(
&helios_generators.generators,
helios_generators(),
existing_hash,
offset,
prior_children.into(),
@ -180,14 +176,13 @@ pub extern "C" fn hash_grow_helios(
#[no_mangle]
pub extern "C" fn hash_grow_selene(
selene_generators: &SeleneGenerators,
existing_hash: SelenePoint,
offset: usize,
prior_children: SeleneScalarSlice,
new_children: SeleneScalarSlice,
) -> CResult<SelenePoint, io::Error> {
let hash = hash_grow(
&selene_generators.generators,
selene_generators(),
existing_hash,
offset,
prior_children.into(),

@ -52,7 +52,6 @@ Helios::Point Helios::hash_grow(
const Helios::Chunk &new_children) const
{
auto res = fcmp_rust::hash_grow_helios(
&m_generators,
existing_hash,
offset,
prior_children,
@ -70,7 +69,6 @@ Selene::Point Selene::hash_grow(
const Selene::Chunk &new_children) const
{
auto res = fcmp_rust::hash_grow_selene(
&m_generators,
existing_hash,
offset,
prior_children,
@ -199,26 +197,6 @@ template void extend_scalars_from_cycle_points<Selene, Helios>(const Selene &cur
const std::vector<Selene::Point> &points,
std::vector<Helios::Scalar> &scalars_out);
//----------------------------------------------------------------------------------------------------------------------
Helios::Generators random_helios_generators(std::size_t n)
{
return fcmp_rust::random_helios_generators(n);
}
//----------------------------------------------------------------------------------------------------------------------
Selene::Generators random_selene_generators(std::size_t n)
{
return fcmp_rust::random_selene_generators(n);
}
//----------------------------------------------------------------------------------------------------------------------
Helios::Point random_helios_hash_init_point()
{
return fcmp_rust::random_helios_hash_init_point();
}
//----------------------------------------------------------------------------------------------------------------------
Selene::Point random_selene_hash_init_point()
{
return fcmp_rust::random_selene_hash_init_point();
}
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
} //namespace tower_cycle
} //namespace fcmp

@ -49,7 +49,6 @@ using HeliosScalar = fcmp_rust::HeliosScalar;
//----------------------------------------------------------------------------------------------------------------------
struct HeliosT final
{
using Generators = fcmp_rust::HeliosGenerators;
using Scalar = HeliosScalar;
using Point = fcmp_rust::HeliosPoint;
using Chunk = fcmp_rust::HeliosScalarSlice;
@ -58,7 +57,6 @@ struct HeliosT final
//----------------------------------------------------------------------------------------------------------------------
struct SeleneT final
{
using Generators = fcmp_rust::SeleneGenerators;
using Scalar = SeleneScalar;
using Point = fcmp_rust::SelenePoint;
using Chunk = fcmp_rust::SeleneScalarSlice;
@ -72,8 +70,7 @@ class Curve
{
//constructor
public:
Curve(const typename C::Generators &generators, const typename C::Point &hash_init_point):
m_generators{generators},
Curve(const typename C::Point &hash_init_point):
m_hash_init_point{hash_init_point}
{};
@ -98,8 +95,6 @@ public:
//member variables
public:
// TODO: make these static constants
const typename C::Generators &m_generators;
const typename C::Point &m_hash_init_point;
};
//----------------------------------------------------------------------------------------------------------------------
@ -107,7 +102,6 @@ class Helios final : public Curve<HeliosT>
{
//typedefs
public:
using Generators = HeliosT::Generators;
using Scalar = HeliosT::Scalar;
using Point = HeliosT::Point;
using Chunk = HeliosT::Chunk;
@ -115,8 +109,8 @@ public:
//constructor
public:
Helios(const Generators &generators, const Point &hash_init_point)
: Curve<HeliosT>(generators, hash_init_point)
Helios()
: Curve<HeliosT>(fcmp_rust::helios_hash_init_point())
{};
//member functions
@ -142,7 +136,6 @@ class Selene final : public Curve<SeleneT>
{
//typedefs
public:
using Generators = SeleneT::Generators;
using Scalar = SeleneT::Scalar;
using Point = SeleneT::Point;
using Chunk = SeleneT::Chunk;
@ -150,8 +143,8 @@ public:
//constructor
public:
Selene(const Generators &generators, const Point &hash_init_point)
: Curve<SeleneT>(generators, hash_init_point)
Selene()
: Curve<SeleneT>(fcmp_rust::selene_hash_init_point())
{};
//member functions
@ -187,13 +180,6 @@ void extend_scalars_from_cycle_points(const C_POINTS &curve,
const std::vector<typename C_POINTS::Point> &points,
std::vector<typename C_SCALARS::Scalar> &scalars_out);
//----------------------------------------------------------------------------------------------------------------------
// TODO: use static constants and get rid of the below functions (WARNING: number of generators must be >= curve's
// width, and also need to account for selene leaf layer 3x)
Helios::Generators random_helios_generators(std::size_t n);
Selene::Generators random_selene_generators(std::size_t n);
Helios::Point random_helios_hash_init_point();
Selene::Point random_selene_hash_init_point();
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
}//namespace tower_cycle
}//namespace fcmp

@ -356,12 +356,8 @@ TYPED_TEST(BlockchainDBTest, GrowCurveTrees)
db_wtxn_guard guard(this->m_db);
CHECK_AND_ASSERT_THROW_MES(HELIOS_GENERATORS_LEN >= HELIOS_CHUNK_WIDTH, "helios generators < chunk width");
CHECK_AND_ASSERT_THROW_MES(SELENE_GENERATORS_LEN >= (SELENE_CHUNK_WIDTH * CurveTreesV1::LEAF_TUPLE_SIZE),
"selene generators < max chunk width");
Helios helios(HELIOS_GENERATORS, HELIOS_HASH_INIT_POINT);
Selene selene(SELENE_GENERATORS, SELENE_HASH_INIT_POINT);
Helios helios;
Selene selene;
auto curve_trees = CurveTreesV1(
helios,

@ -569,28 +569,32 @@ static void grow_tree(CurveTreesV1 &curve_trees,
ASSERT_TRUE(curve_trees_accessor.validate_tree(tree_inout));
}
//----------------------------------------------------------------------------------------------------------------------
static void grow_tree_test(Helios &helios,
Selene &selene,
const std::size_t helios_width,
const std::size_t selene_width)
//----------------------------------------------------------------------------------------------------------------------
// Test
//----------------------------------------------------------------------------------------------------------------------
TEST(curve_trees, grow_tree)
{
LOG_PRINT_L1("Test grow tree with helios chunk width " << helios_width << ", selene chunk width " << selene_width);
Helios helios;
Selene selene;
LOG_PRINT_L1("Test grow tree with helios chunk width " << HELIOS_CHUNK_WIDTH
<< ", selene chunk width " << SELENE_CHUNK_WIDTH);
auto curve_trees = CurveTreesV1(
helios,
selene,
helios_width,
selene_width);
HELIOS_CHUNK_WIDTH,
SELENE_CHUNK_WIDTH);
CurveTreesUnitTest curve_trees_accessor{curve_trees};
CHECK_AND_ASSERT_THROW_MES(helios_width > 1, "helios width must be > 1");
CHECK_AND_ASSERT_THROW_MES(selene_width > 1, "selene width must be > 1");
CHECK_AND_ASSERT_THROW_MES(HELIOS_CHUNK_WIDTH > 1, "helios width must be > 1");
CHECK_AND_ASSERT_THROW_MES(SELENE_CHUNK_WIDTH > 1, "selene width must be > 1");
// Number of leaves for which x number of layers is required
const std::size_t NEED_1_LAYER = selene_width;
const std::size_t NEED_2_LAYERS = NEED_1_LAYER * helios_width;
const std::size_t NEED_3_LAYERS = NEED_2_LAYERS * selene_width;
const std::size_t NEED_1_LAYER = SELENE_CHUNK_WIDTH;
const std::size_t NEED_2_LAYERS = NEED_1_LAYER * HELIOS_CHUNK_WIDTH;
const std::size_t NEED_3_LAYERS = NEED_2_LAYERS * SELENE_CHUNK_WIDTH;
const std::vector<std::size_t> N_LEAVES{
// Basic tests
@ -647,18 +651,3 @@ static void grow_tree_test(Helios &helios,
}
}
}
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
// Test
//----------------------------------------------------------------------------------------------------------------------
TEST(curve_trees, grow_tree)
{
CHECK_AND_ASSERT_THROW_MES(HELIOS_GENERATORS_LEN >= HELIOS_CHUNK_WIDTH, "helios generators < chunk width");
CHECK_AND_ASSERT_THROW_MES(SELENE_GENERATORS_LEN >= (SELENE_CHUNK_WIDTH * CurveTreesV1::LEAF_TUPLE_SIZE),
"selene generators < max chunk width");
Helios helios(HELIOS_GENERATORS, HELIOS_HASH_INIT_POINT);
Selene selene(SELENE_GENERATORS, SELENE_HASH_INIT_POINT);
grow_tree_test(helios, selene, HELIOS_CHUNK_WIDTH, SELENE_CHUNK_WIDTH);
}

@ -78,17 +78,7 @@ private:
const std::vector<CurveTreesV1::LeafTuple> generate_random_leaves(const CurveTreesV1 &curve_trees,
const std::size_t num_leaves);
// TODO: use static constant generators and hash init points
const std::size_t HELIOS_GENERATORS_LEN = 128;
const std::size_t SELENE_GENERATORS_LEN = 256;
// https://github.com/kayabaNerve/fcmp-plus-plus/blob
// /b2742e86f3d18155fd34dd1ed69cb8f79b900fce/crypto/fcmps/src/tests.rs#L81-L82
const std::size_t HELIOS_CHUNK_WIDTH = 38;
const std::size_t SELENE_CHUNK_WIDTH = 18;
const Helios::Generators HELIOS_GENERATORS = fcmp::tower_cycle::random_helios_generators(HELIOS_GENERATORS_LEN);
const Selene::Generators SELENE_GENERATORS = fcmp::tower_cycle::random_selene_generators(SELENE_GENERATORS_LEN);
const Helios::Point HELIOS_HASH_INIT_POINT = fcmp::tower_cycle::random_helios_hash_init_point();
const Selene::Point SELENE_HASH_INIT_POINT = fcmp::tower_cycle::random_selene_hash_init_point();