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

View file

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

View file

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

View file

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

View file

@ -49,7 +49,6 @@ using HeliosScalar = fcmp_rust::HeliosScalar;
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
struct HeliosT final struct HeliosT final
{ {
using Generators = fcmp_rust::HeliosGenerators;
using Scalar = HeliosScalar; using Scalar = HeliosScalar;
using Point = fcmp_rust::HeliosPoint; using Point = fcmp_rust::HeliosPoint;
using Chunk = fcmp_rust::HeliosScalarSlice; using Chunk = fcmp_rust::HeliosScalarSlice;
@ -58,7 +57,6 @@ struct HeliosT final
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
struct SeleneT final struct SeleneT final
{ {
using Generators = fcmp_rust::SeleneGenerators;
using Scalar = SeleneScalar; using Scalar = SeleneScalar;
using Point = fcmp_rust::SelenePoint; using Point = fcmp_rust::SelenePoint;
using Chunk = fcmp_rust::SeleneScalarSlice; using Chunk = fcmp_rust::SeleneScalarSlice;
@ -72,8 +70,7 @@ class Curve
{ {
//constructor //constructor
public: public:
Curve(const typename C::Generators &generators, const typename C::Point &hash_init_point): Curve(const typename C::Point &hash_init_point):
m_generators{generators},
m_hash_init_point{hash_init_point} m_hash_init_point{hash_init_point}
{}; {};
@ -98,8 +95,6 @@ public:
//member variables //member variables
public: public:
// TODO: make these static constants
const typename C::Generators &m_generators;
const typename C::Point &m_hash_init_point; const typename C::Point &m_hash_init_point;
}; };
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
@ -107,7 +102,6 @@ class Helios final : public Curve<HeliosT>
{ {
//typedefs //typedefs
public: public:
using Generators = HeliosT::Generators;
using Scalar = HeliosT::Scalar; using Scalar = HeliosT::Scalar;
using Point = HeliosT::Point; using Point = HeliosT::Point;
using Chunk = HeliosT::Chunk; using Chunk = HeliosT::Chunk;
@ -115,8 +109,8 @@ public:
//constructor //constructor
public: public:
Helios(const Generators &generators, const Point &hash_init_point) Helios()
: Curve<HeliosT>(generators, hash_init_point) : Curve<HeliosT>(fcmp_rust::helios_hash_init_point())
{}; {};
//member functions //member functions
@ -142,7 +136,6 @@ class Selene final : public Curve<SeleneT>
{ {
//typedefs //typedefs
public: public:
using Generators = SeleneT::Generators;
using Scalar = SeleneT::Scalar; using Scalar = SeleneT::Scalar;
using Point = SeleneT::Point; using Point = SeleneT::Point;
using Chunk = SeleneT::Chunk; using Chunk = SeleneT::Chunk;
@ -150,8 +143,8 @@ public:
//constructor //constructor
public: public:
Selene(const Generators &generators, const Point &hash_init_point) Selene()
: Curve<SeleneT>(generators, hash_init_point) : Curve<SeleneT>(fcmp_rust::selene_hash_init_point())
{}; {};
//member functions //member functions
@ -187,13 +180,6 @@ void extend_scalars_from_cycle_points(const C_POINTS &curve,
const std::vector<typename C_POINTS::Point> &points, const std::vector<typename C_POINTS::Point> &points,
std::vector<typename C_SCALARS::Scalar> &scalars_out); 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 tower_cycle
}//namespace fcmp }//namespace fcmp

View file

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

View file

@ -569,28 +569,32 @@ static void grow_tree(CurveTreesV1 &curve_trees,
ASSERT_TRUE(curve_trees_accessor.validate_tree(tree_inout)); ASSERT_TRUE(curve_trees_accessor.validate_tree(tree_inout));
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
static void grow_tree_test(Helios &helios, //----------------------------------------------------------------------------------------------------------------------
Selene &selene, // Test
const std::size_t helios_width, //----------------------------------------------------------------------------------------------------------------------
const std::size_t selene_width) 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( auto curve_trees = CurveTreesV1(
helios, helios,
selene, selene,
helios_width, HELIOS_CHUNK_WIDTH,
selene_width); SELENE_CHUNK_WIDTH);
CurveTreesUnitTest curve_trees_accessor{curve_trees}; CurveTreesUnitTest curve_trees_accessor{curve_trees};
CHECK_AND_ASSERT_THROW_MES(helios_width > 1, "helios width must be > 1"); CHECK_AND_ASSERT_THROW_MES(HELIOS_CHUNK_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(SELENE_CHUNK_WIDTH > 1, "selene width must be > 1");
// Number of leaves for which x number of layers is required // 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_1_LAYER = SELENE_CHUNK_WIDTH;
const std::size_t NEED_2_LAYERS = NEED_1_LAYER * helios_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_width; const std::size_t NEED_3_LAYERS = NEED_2_LAYERS * SELENE_CHUNK_WIDTH;
const std::vector<std::size_t> N_LEAVES{ const std::vector<std::size_t> N_LEAVES{
// Basic tests // 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);
}

View file

@ -78,17 +78,7 @@ private:
const std::vector<CurveTreesV1::LeafTuple> generate_random_leaves(const CurveTreesV1 &curve_trees, const std::vector<CurveTreesV1::LeafTuple> generate_random_leaves(const CurveTreesV1 &curve_trees,
const std::size_t num_leaves); 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 // https://github.com/kayabaNerve/fcmp-plus-plus/blob
// /b2742e86f3d18155fd34dd1ed69cb8f79b900fce/crypto/fcmps/src/tests.rs#L81-L82 // /b2742e86f3d18155fd34dd1ed69cb8f79b900fce/crypto/fcmps/src/tests.rs#L81-L82
const std::size_t HELIOS_CHUNK_WIDTH = 38; const std::size_t HELIOS_CHUNK_WIDTH = 38;
const std::size_t SELENE_CHUNK_WIDTH = 18; 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();