mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 04:39:24 +00:00
* Add in an implementation of BP+ based off the paper, intended for clarity and review This was done as part of my work on FCMPs from Monero, and is copied from https://github.com/kayabaNerve/full-chain-membership-proofs * Remove crate structure of BP+ * Remove arithmetic circuit code * Remove AC/VC generators code * Remove generator transcript Monero uses non-transcripted static generators. * Further trimming of generators * Remove the single range proof It's unused by Monero and accordingly unhelpful. * Work on getting BP+ to compile in its new env * Correct BP+ folder name * Further tweaks to get closer to compiling * Remove the ScalarMatrix file It's only used for AC proofs * Compiles, with tests passing * Lock BP+ to Ed25519 instead of the generic Ciphersuite * Resolve most warnings in BP+ * Make existing bulletproofs test easier to read * Further strip generators * Swap G/H as Monero did * Replace RangeCommitment with Commitment * Hard-code BP+ h to Ed25519's generator * Use pub(crate) for BP+, not pub * Replace initial_transcript with hash_plus * Rename hash_plus to initial_transcript * Finish integrating the FCMP BP+ impl * Move BP+ folder * Correct no-std support * Rename "long_n" to eta * Add note on non-prime order dfg points
93 lines
2.2 KiB
Rust
93 lines
2.2 KiB
Rust
#![allow(non_snake_case)]
|
|
|
|
use group::Group;
|
|
use dalek_ff_group::{Scalar, EdwardsPoint};
|
|
|
|
mod scalar_vector;
|
|
pub(crate) use scalar_vector::{ScalarVector, weighted_inner_product};
|
|
mod point_vector;
|
|
pub(crate) use point_vector::PointVector;
|
|
|
|
pub(crate) mod transcript;
|
|
pub(crate) mod weighted_inner_product;
|
|
pub(crate) use weighted_inner_product::*;
|
|
pub(crate) mod aggregate_range_proof;
|
|
pub(crate) use aggregate_range_proof::*;
|
|
|
|
pub(crate) fn padded_pow_of_2(i: usize) -> usize {
|
|
let mut next_pow_of_2 = 1;
|
|
while next_pow_of_2 < i {
|
|
next_pow_of_2 <<= 1;
|
|
}
|
|
next_pow_of_2
|
|
}
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
|
pub(crate) enum GeneratorsList {
|
|
GBold1,
|
|
HBold1,
|
|
}
|
|
|
|
// TODO: Table these
|
|
#[derive(Clone, Debug)]
|
|
pub(crate) struct Generators {
|
|
g: EdwardsPoint,
|
|
|
|
g_bold1: &'static [EdwardsPoint],
|
|
h_bold1: &'static [EdwardsPoint],
|
|
}
|
|
|
|
mod generators {
|
|
use std_shims::sync::OnceLock;
|
|
use monero_generators::Generators;
|
|
include!(concat!(env!("OUT_DIR"), "/generators_plus.rs"));
|
|
}
|
|
|
|
impl Generators {
|
|
#[allow(clippy::new_without_default)]
|
|
pub(crate) fn new() -> Self {
|
|
let gens = generators::GENERATORS();
|
|
Generators { g: dalek_ff_group::EdwardsPoint(crate::H()), g_bold1: &gens.G, h_bold1: &gens.H }
|
|
}
|
|
|
|
pub(crate) fn len(&self) -> usize {
|
|
self.g_bold1.len()
|
|
}
|
|
|
|
pub(crate) fn g(&self) -> EdwardsPoint {
|
|
self.g
|
|
}
|
|
|
|
pub(crate) fn h(&self) -> EdwardsPoint {
|
|
EdwardsPoint::generator()
|
|
}
|
|
|
|
pub(crate) fn generator(&self, list: GeneratorsList, i: usize) -> EdwardsPoint {
|
|
match list {
|
|
GeneratorsList::GBold1 => self.g_bold1[i],
|
|
GeneratorsList::HBold1 => self.h_bold1[i],
|
|
}
|
|
}
|
|
|
|
pub(crate) fn reduce(&self, generators: usize) -> Self {
|
|
// Round to the nearest power of 2
|
|
let generators = padded_pow_of_2(generators);
|
|
assert!(generators <= self.g_bold1.len());
|
|
|
|
Generators {
|
|
g: self.g,
|
|
g_bold1: &self.g_bold1[.. generators],
|
|
h_bold1: &self.h_bold1[.. generators],
|
|
}
|
|
}
|
|
}
|
|
|
|
// Returns the little-endian decomposition.
|
|
fn u64_decompose(value: u64) -> ScalarVector {
|
|
let mut bits = ScalarVector::new(64);
|
|
for bit in 0 .. 64 {
|
|
bits[bit] = Scalar::from((value >> bit) & 1);
|
|
}
|
|
bits
|
|
}
|