Further documentation, start shoring up API boundaries of existing crates

This commit is contained in:
Luke Parker
2024-06-14 11:47:57 -04:00
parent 784a273747
commit 9c217913e6
16 changed files with 195 additions and 116 deletions

View File

@@ -24,7 +24,10 @@ fn keccak256(data: &[u8]) -> [u8; 32] {
}
static H_CELL: OnceLock<DalekPoint> = OnceLock::new();
/// Monero's alternate generator `H`, used for amounts in Pedersen commitments.
/// Monero's `H` generator.
///
/// Contrary to convention (`G` for values, `H` for randomness), `H` is used by Monero for amounts
/// within Pedersen commitments.
#[allow(non_snake_case)]
pub fn H() -> DalekPoint {
*H_CELL.get_or_init(|| {
@@ -33,7 +36,9 @@ pub fn H() -> DalekPoint {
}
static H_POW_2_CELL: OnceLock<[DalekPoint; 64]> = OnceLock::new();
/// Monero's alternate generator `H`, multiplied by 2**i for i in 1 ..= 64.
/// Monero's `H` generator, multiplied by 2**i for i in 1 ..= 64.
///
/// This table is useful when working with amounts, which are u64s.
#[allow(non_snake_case)]
pub fn H_pow_2() -> &'static [DalekPoint; 64] {
H_POW_2_CELL.get_or_init(|| {
@@ -45,8 +50,11 @@ pub fn H_pow_2() -> &'static [DalekPoint; 64] {
})
}
// The maximum amount of commitments proven for within a single range proof.
const MAX_M: usize = 16;
// The amount of bits the value within a commitment may use.
const N: usize = 64;
// The maximum amount of bits used within a single range proof.
const MAX_MN: usize = MAX_M * N;
/// Container struct for Bulletproofs(+) generators.
@@ -57,18 +65,24 @@ pub struct Generators {
}
/// Generate generators as needed for Bulletproofs(+), as Monero does.
///
/// Consumers should not call this function ad-hoc, yet call it within a build script or use a
/// once-initialized static.
pub fn bulletproofs_generators(dst: &'static [u8]) -> Generators {
let mut preimage = H().compress().to_bytes().to_vec();
preimage.extend(dst);
let mut res = Generators { G: Vec::with_capacity(MAX_MN), H: Vec::with_capacity(MAX_MN) };
for i in 0 .. MAX_MN {
// We generate a pair of generators per iteration
let i = 2 * i;
let mut even = H().compress().to_bytes().to_vec();
even.extend(dst);
let mut odd = even.clone();
write_varint::<Vec<u8>, u64>(&i.try_into().unwrap(), &mut even).unwrap();
write_varint::<Vec<u8>, u64>(&(i + 1).try_into().unwrap(), &mut odd).unwrap();
let mut even = preimage.clone();
write_varint(&i, &mut even).unwrap();
res.H.push(EdwardsPoint(hash_to_point(keccak256(&even))));
let mut odd = preimage.clone();
write_varint(&(i + 1), &mut odd).unwrap();
res.G.push(EdwardsPoint(hash_to_point(keccak256(&odd))));
}
res