Present Rust library contains the implementation of Bulletproofs++ over secp256k1 curve that includes: weight norm linear argument protocol, arithmetic circuit protocol and reciprocal range proofs. Also, contains the `u64`

range proof protocol as a primary use-case for reciprocal range proofs.

Implemented solution has 2G points advantage over existing BP and BP+ protocols on proving of one 64-bit value and this advantage will increase for more values per proof.

Protocol | G | F |
---|---|---|

BP | 16 | 5 |

BP+ | 15 | 3 |

Our BP++ | 13 | 3 |

This implementation uses Merlin transcript for challenges generation as was recommended by Bulletproofs protocol authors.

All `Proof`

data models has corresponding `SerializeProof`

models where serde `Serialize`

and `Deserialize`

was implemented.

Use tests to run the provided example:

```
use k256::elliptic_curve::{Group, rand_core::OsRng};
use k256::ProjectivePoint;
use bp_pp::range_proof;
use bp_pp::range_proof::u64_proof::G_VEC_FULL_SZ;
use bp_pp::range_proof::u64_proof::H_VEC_FULL_SZ;
use bp_pp::range_proof::reciprocal::{SerializableProof, self};
fn main() {
let mut rand = OsRng::default();
let x = 123456u64; // private value to create proof for.
let s = k256::Scalar::generate_biased(&mut rand); // blinding value
// Base points
let g = k256::ProjectivePoint::random(&mut rand);
let g_vec = (0..G_VEC_FULL_SZ).map(|_| k256::ProjectivePoint::random(&mut rand)).collect::<Vec<ProjectivePoint>>();
let h_vec = (0..H_VEC_FULL_SZ).map(|_| k256::ProjectivePoint::random(&mut rand)).collect::<Vec<ProjectivePoint>>();
let public = range_proof::u64_proof::U64RangeProofProtocol {
g,
g_vec,
h_vec,
};
// transcript will be used for challenge generation - to move from interactive to non-interactive protocol.
// transcript should be the new instance but with same label for prover and verifier.
let mut pt = merlin::Transcript::new(b"u64 range proof");
let proof = public.prove(x, &s, &mut pt, &mut rand);
// value commitment: `commitment = x*g + s*h_vec[0]`
let commitment = public.commit_value(x, &s);
println!("{}", serde_json::to_string_pretty(&reciprocal::SerializableProof::from(&proof)).unwrap());
let mut vt = merlin::Transcript::new(b"u64 range proof");
assert!(public.verify(&commitment, proof, &mut vt));
}
```