Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8 bits range proofs behaviour with numbers larger than u8 #8

Open
grumbach opened this issue Aug 10, 2021 · 1 comment
Open

8 bits range proofs behaviour with numbers larger than u8 #8

grumbach opened this issue Aug 10, 2021 · 1 comment

Comments

@grumbach
Copy link

grumbach commented Aug 10, 2021

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);
		}
	}
}
@MatthiasMi
Copy link

Hi,
maybe it is not too late to shed some light on this:

The code above adds 2 commitments, both with the value of 200 (yet, I'd suggest not using the same blinding twice), using 8 bits as size parametrizing the proof-system such that 8 bits are used to create intermediate variables --- in other words it can handle inputs <2^8, as it proves statements about the first 8 bit-positions of the inputs.

The actual data type representing a commitment is Scalar, which can hold up to 255-bit integers.

Now, the computation of 200 + 200 does not overflow the large data type, and not surprisingly you find 400 as the correct answer using the enumeration method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants