bulletproofs icon indicating copy to clipboard operation
bulletproofs copied to clipboard

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

Open grumbach opened this issue 4 years ago • 1 comments

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);
		}
	}
}

grumbach avatar Aug 17 '21 12:08 grumbach

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.

rickwebiii avatar Sep 07 '22 05:09 rickwebiii