add random number / field element generation support

This commit is contained in:
Balazs Komuves 2026-01-29 22:03:52 +01:00
parent 0c4b1934f3
commit b46a6dde66
No known key found for this signature in database
GPG Key ID: F63B7AEF18435562
5 changed files with 110 additions and 6 deletions

View File

@ -1,8 +1,12 @@
#![allow(unused)]
#![feature(random)]
use std::time::Instant;
use std::ops::{RangeFull};
use std::random::{Distribution,DefaultRandomSource,random};
use rust_poseidon_bn254_pure::bn254::bigint::*;
use rust_poseidon_bn254_pure::bn254::constant::*;
use rust_poseidon_bn254_pure::bn254::montgomery::*;
@ -153,6 +157,7 @@ fn main() {
//----------------------------------------------------------------------------
/*
println!("");
println!("sanity checking comparison with the prime");
let one : Big = BigInt::from_u32(1);
@ -166,9 +171,11 @@ fn main() {
BigInt::is_lt_prime(a) ,
BigInt::is_lt_prime(b) ,
BigInt::is_lt_prime(c) );
*/
//----------------------------------------------------------------------------
/*
{
println!("");
println!("conversion to/from bytes");
@ -188,14 +195,25 @@ fn main() {
println!("b = {}",b);
println!("be = {:?}",ys);
}
*/
//----------------------------------------------------------------------------
/*
println!("");
println!("underlying repr = {:?} ", MONT1);
println!("in hex = {}", MONT1);
println!("in hex = {}", Mont::to_hex_string (MONT1));
println!("in dec = {}", Mont::to_decimal_string(MONT1));
*/
//----------------------------------------------------------------------------
println!("");
println!("20 random field elements");
for i in 0..20 {
let x: Felt = random(..);
println!(" - {} {} {}", x, Felt::to_bigint(x) < FIELD_PRIME , Felt::is_valid(x) );
}
//----------------------------------------------------------------------------
// expected results:
//
@ -204,6 +222,8 @@ fn main() {
// compress3 = 6542985608222806190361240322586112750744169038454362455181422643027100751666
// compress4 = 18821383157269793795438455681495246036402687001665670618754263018637548127333
println!("");
let out1 = poseidon::hash1( Felt::from_u32(1) );
println!("compress(1) = {}", Felt::to_decimal_string(out1) );

View File

@ -1,4 +1,5 @@
//
// big integers, represented as little-endian arrays of u32-s
//
@ -10,7 +11,9 @@
use std::fmt;
use std::cmp::{Ordering,min};
use std::ops::{Add,Sub};
use std::ops::{Add,Sub,RangeFull};
use std::random::{RandomSource,Distribution};
use unroll::unroll_for_loops;
@ -87,6 +90,15 @@ impl<const N: usize> From<u32> for BigInt<N> {
fn from(x: u32) -> Self { Self::from_u32(x) }
}
//------------------------------------------------------------------------------
// random trait
impl<const N: usize> Distribution<BigInt<N>> for RangeFull {
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> BigInt<N> {
BigInt::sample(source)
}
}
//------------------------------------------------------------------------------
// internal implementations
@ -176,6 +188,10 @@ impl<const N: usize> BigInt<N> {
str::from_utf8(&digits).unwrap().to_string()
}
pub fn to_hex_string(input: BigInt<N>) -> String {
format!("{}", input)
}
//------------------------------------
pub fn truncate1(big: BigInt<{N+1}>) -> BigInt<N> {
@ -380,6 +396,17 @@ impl<const N: usize> BigInt<N> {
BigInt::multiply(big,big)
}
//------------------------------------
// random
pub fn sample(source: &mut (impl RandomSource + ?Sized)) -> BigInt<N> {
let mut xs: [u32; N] = [0; N];
for i in 0..N {
xs[i] = RangeFull.sample(source);
}
BigInt::make(xs)
}
}
// -----------------------------------------------------------------------------
@ -447,6 +474,27 @@ impl BigInt256 {
}
}
//------------------------------------
// ramndom
fn sample_masked(source: &mut (impl RandomSource + ?Sized)) -> BigInt256 {
let mut xs: [u32; 8] = [0; 8];
for i in 0..8 {
xs[i] = RangeFull.sample(source);
}
xs[7] = xs[7] & 0x_3FFF_FFFF;
BigInt::make(xs)
}
// rejection sampling
pub fn sample_mod_prime(source: &mut (impl RandomSource + ?Sized)) -> BigInt256 {
let mut x: BigInt256 = BigInt256::sample_masked(source);
while( !BigInt256::is_lt_prime(x) ) {
x = BigInt256::sample_masked(source);
}
x
}
}

View File

@ -10,7 +10,9 @@
#![allow(non_snake_case)]
use std::fmt;
use std::ops::{Neg,Add,Sub,Mul};
use std::ops::{Neg,Add,Sub,Mul,RangeFull};
use std::random::{RandomSource,Distribution};
use crate::bn254::bigint::*;
use crate::bn254::constant::*;
@ -90,6 +92,15 @@ impl From<u32> for Felt {
fn from(x: u32) -> Self { Self::from_u32(x) }
}
//------------------------------------------------------------------------------
// random trait
impl Distribution<Felt> for RangeFull {
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> Felt {
Felt(BigInt::sample_mod_prime(source))
}
}
//------------------------------------------------------------------------------
// internal implementations
@ -122,6 +133,10 @@ impl Felt {
BigInt::to_decimal_string(input.0)
}
pub fn to_hex_string(input: Felt) -> String {
BigInt::to_hex_string(input.0)
}
//------------------------------------
// conversion to/from bytes

View File

@ -7,7 +7,9 @@
#![allow(non_snake_case)]
use std::fmt;
use std::ops::{Neg,Add,Sub,Mul};
use std::ops::{Neg,Add,Sub,Mul,RangeFull};
use std::random::{RandomSource,Distribution};
use unroll::unroll_for_loops;
@ -81,6 +83,15 @@ impl From<u32> for Mont {
fn from(x: u32) -> Self { Self::convert_from_u32(x) }
}
//------------------------------------------------------------------------------
// random trait
impl Distribution<Mont> for RangeFull {
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> Mont {
Mont(BigInt::sample_mod_prime(source))
}
}
//------------------------------------------------------------------------------
// internal implementations
@ -125,10 +136,17 @@ impl Mont {
Mont(big)
}
//------------------------------------
// to string
pub fn to_decimal_string(input: Mont) -> String {
BigInt::to_decimal_string(Mont::convert_to_big(input))
}
pub fn to_hex_string(input: Mont) -> String {
BigInt::to_hex_string(Mont::convert_to_big(input))
}
//------------------------------------
#[inline(always)]

View File

@ -1,7 +1,10 @@
#![allow(incomplete_features)]
#![feature(bigint_helper_methods)]
#![feature(generic_const_exprs)]
#![feature(random)]
#![feature(trait_alias)]
pub mod bn254;
pub mod poseidon;