dalek-cryptography / bulletproofs

A pure-Rust implementation of Bulletproofs using Ristretto.
MIT License
1.02k stars 216 forks source link

[Question] 8 bits range proofs behaviour with numbers larger than u8 #344

Open grumbach opened 2 years ago

grumbach commented 2 years ago

The code below adds 2 commitments with the value of 200 using 8 bits as size. 200 + 200 should overflow a u8, this code tries to find what value matches this commitment. Surprisingly (or not), the output I get is 400 which sounds ok since it's 200 + 200 but it is not an u8. Did I understand the 8 bits size wrong?

use rand::rngs::OsRng;
use curve25519_dalek_ng::scalar::Scalar;
use merlin::Transcript;
use bulletproofs::{BulletproofGens, PedersenGens, RangeProof};
use curve25519_dalek_ng::ristretto::RistrettoPoint;

fn main() {
    let nbits = 8;
    let ped_commits = PedersenGens::default();
    let bullet_gens = BulletproofGens::new(nbits, 1);
    let mut csprng: OsRng = OsRng::default();
    let blinding_factor = Scalar::random(&mut csprng);
    let mut prover_ts = Transcript::new("Test".as_bytes());
    let mut prover_ts2 = Transcript::new("Test".as_bytes());

    let (_proof, commitment) = RangeProof::prove_single( &bullet_gens,&ped_commits,&mut prover_ts,200,&blinding_factor, nbits,).expect("Oops!");
        let (_proof2, commitment2) = RangeProof::prove_single( &bullet_gens,&ped_commits,&mut prover_ts2,200,&blinding_factor, nbits,).expect("Oops!");

    // sum for c1 c2
    let vec_in = vec![commitment, commitment2];
    let res:RistrettoPoint = vec_in.iter()
        .map(|v|v.decompress().unwrap())
        .sum::<RistrettoPoint>();

    // brute force
        let bf_sum_inputs = blinding_factor + blinding_factor;
    for i in 0..u64::MAX {
        // proof for c3
        let mut prover_ts3 = Transcript::new("Test".as_bytes());
        let (_proof3, commitment3) = RangeProof::prove_single( &bullet_gens,&ped_commits,&mut prover_ts3,i,&bf_sum_inputs, nbits,).expect("Oops!");

        // sum for c3
        let vec_out = vec![commitment3];
        let res2:RistrettoPoint = vec_out.iter()
            .map(|v|v.decompress().unwrap())
            .sum::<RistrettoPoint>();

        // eq check
        if res == res2 {
            println!("Eq {}", i);
            break;
        } else {
            //println!("{}", i);
        }
    }
}
rickwebiii commented 1 year ago

Where do you expect a u8 to come into play? You've just proven 200 < 2^8 and attempted to prove 400 < 2^8. The commitments are EC points, not u8 values. You should be able to create a commitment to 400 with no problems.

Does proof3 verify correctly (it shouldn't)? Also, I'm not sure why there isn't a precondition check in prove_* to return an error if the thing you're trying to prove isn't true.