Implement Bulletproofs in Rust (#69)

* Initial attempt at Bulletproofs

I don't know why this doesn't work. The generators and hash_cache lines
up without issue. AFAICT, the inner product proof is valid as well, as
are all included formulas.

* Add yinvpow asserts

* Clean code

* Correct bad imports

* Fix the definition of TWO_N

Bulletproofs work now :D

* Tidy up a bit

* fmt + clippy

* Compile a variety of XMR dependencies with optimizations, even under dev

The Rust bulletproof implementation is 8% slower than C right now, under 
release. This is acceptable, even if suboptimal. Under debug, they take 
a quarter of a second to two seconds though, depending on the amount of 
outputs, which justifies this move.

* Remove unnecessary deref in BPs
This commit is contained in:
Luke Parker
2022-07-26 02:05:15 -05:00
committed by GitHub
parent 3711e13009
commit ee29f6d6d8
9 changed files with 382 additions and 45 deletions

View File

@@ -7,12 +7,11 @@ use dalek_ff_group::field::FieldElement;
use crate::hash;
pub fn hash_to_point(point: EdwardsPoint) -> EdwardsPoint {
let mut bytes = point.compress().to_bytes();
pub(crate) fn raw_hash_to_point(mut bytes: [u8; 32]) -> EdwardsPoint {
unsafe {
#[link(name = "wrapper")]
extern "C" {
fn c_hash_to_point(point: *const u8);
fn c_hash_to_point(key: *const u8);
}
c_hash_to_point(bytes.as_mut_ptr());
@@ -24,11 +23,11 @@ pub fn hash_to_point(point: EdwardsPoint) -> EdwardsPoint {
// for all branches, there still could be *some* discrepancy somewhere. There's no reason to use it
// unless we're trying to purge that section of the C static library, which we aren't right now
#[allow(dead_code)]
pub(crate) fn rust_hash_to_point(key: EdwardsPoint) -> EdwardsPoint {
pub(crate) fn rust_hash_to_point(bytes: [u8; 32]) -> EdwardsPoint {
#[allow(non_snake_case)]
let A = FieldElement::from(486662u64);
let v = FieldElement::from_square(hash(&key.compress().to_bytes())).double();
let v = FieldElement::from_square(hash(&bytes)).double();
let w = v + FieldElement::one();
let x = w.square() + (-A.square() * v);
@@ -65,3 +64,7 @@ pub(crate) fn rust_hash_to_point(key: EdwardsPoint) -> EdwardsPoint {
CompressedEdwardsY(bytes).decompress().unwrap().mul_by_cofactor()
}
pub fn hash_to_point(key: EdwardsPoint) -> EdwardsPoint {
raw_hash_to_point(key.compress().to_bytes())
}