Skip to content

Commit ac8183d

Browse files
committed
docs: add range proof relation example
1 parent 0a42455 commit ac8183d

File tree

2 files changed

+93
-2
lines changed

2 files changed

+93
-2
lines changed

src/duplex_sponge/shake.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,4 @@ impl DuplexSpongeInterface for ShakeDuplexSponge {
2626
self.0.clone().finalize_xof_into(&mut output);
2727
output
2828
}
29-
3029
}

src/tests/test_relations.rs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rand::RngCore;
55

66
use crate::codec::Shake128DuplexSponge;
77
use crate::fiat_shamir::Nizk;
8-
use crate::linear_relation::CanonicalLinearRelation;
8+
use crate::linear_relation::{CanonicalLinearRelation, Sum};
99

1010
use crate::linear_relation::{LinearRelation, VariableMultiScalarMul};
1111

@@ -200,6 +200,97 @@ pub fn pedersen_commitment_dleq<G: PrimeGroup, R: RngCore>(
200200
(instance, witness_vec)
201201
}
202202

203+
/// Test that a Pedersen commitment is between 0 and 1337.
204+
#[allow(non_snake_case)]
205+
pub fn test_range<G: PrimeGroup, R: RngCore>(
206+
mut rng: &mut R,
207+
) -> (CanonicalLinearRelation<G>, Vec<G::Scalar>) {
208+
let G = G::generator();
209+
let H = G::random(&mut rng);
210+
211+
let bases = [1, 2, 4, 8, 16, 32, 64, 128, 256, 313, 512];
212+
const BITS: usize = 11;
213+
214+
let mut instance = LinearRelation::new();
215+
let [var_G, var_H] = instance.allocate_elements();
216+
let [var_x, var_r] = instance.allocate_scalars();
217+
let vars_b = instance.allocate_scalars::<BITS>();
218+
let vars_s = instance.allocate_scalars::<BITS>();
219+
let var_s2 = instance.allocate_scalars::<BITS>();
220+
221+
let var_C = instance.allocate_eq(var_x * var_G + var_r * var_H);
222+
let mut var_Ds = Vec::new();
223+
for i in 0..BITS {
224+
let var_D_i = instance.allocate_eq(vars_b[i] * var_G + vars_s[i] * var_H);
225+
instance.append_equation(var_D_i, vars_b[i] * var_D_i + var_s2[i] * var_H);
226+
var_Ds.push(var_D_i);
227+
}
228+
instance.append_equation(
229+
var_C,
230+
(0..BITS)
231+
.map(|i| var_Ds[i] * vars_b[i] * G::Scalar::from(bases[i]))
232+
.sum::<Sum<_>>(),
233+
);
234+
235+
let r = G::Scalar::random(&mut rng);
236+
let x = G::Scalar::from(822);
237+
let b = [
238+
G::Scalar::ZERO,
239+
G::Scalar::ONE,
240+
G::Scalar::ONE,
241+
G::Scalar::ZERO,
242+
G::Scalar::ONE,
243+
G::Scalar::ONE,
244+
G::Scalar::ZERO,
245+
G::Scalar::ZERO,
246+
G::Scalar::ONE,
247+
G::Scalar::ZERO,
248+
G::Scalar::ONE,
249+
];
250+
// set the randomness for the bit decomposition
251+
let mut s = (0..BITS)
252+
.map(|_| G::Scalar::random(&mut rng))
253+
.collect::<Vec<_>>();
254+
let partial_sum = (0..BITS - 1)
255+
.map(|i| b[i] * G::Scalar::from(bases[i]) * s[i])
256+
.sum::<G::Scalar>();
257+
s[BITS - 1] = r - partial_sum;
258+
s[BITS - 1] *= (b[BITS - 1] * G::Scalar::from(bases[BITS - 1]))
259+
.invert()
260+
.unwrap();
261+
let s2 = (0..BITS)
262+
.map(|i| (G::Scalar::ONE - b[i]) * s[i])
263+
.collect::<Vec<_>>();
264+
let witness = [x, r]
265+
.iter()
266+
.chain(&b)
267+
.chain(&s)
268+
.chain(&s2)
269+
.copied()
270+
.collect::<Vec<_>>();
271+
272+
println!("test_range: witness length = {}", witness.len());
273+
274+
instance.set_elements([(var_G, G), (var_H, H)]);
275+
instance.set_element(var_C, G * x + H * r);
276+
for i in 0..BITS {
277+
instance.set_element(var_Ds[i], G * b[i] + H * s[i]);
278+
}
279+
assert!(
280+
instance.canonical().is_ok(),
281+
"{}",
282+
instance.canonical().err().unwrap()
283+
);
284+
285+
let canonical = instance.canonical().unwrap();
286+
println!(
287+
"test_range: relation has {} scalar variables",
288+
canonical.num_scalars
289+
);
290+
291+
(canonical, witness)
292+
}
293+
203294
/// LinearMap for knowledge of an opening for use in a BBS commitment.
204295
// BBS message length is 3
205296
#[allow(non_snake_case)]
@@ -454,6 +545,7 @@ fn test_relations() {
454545
("twisted_pedersen_commitment", &twisted_pedersen_commitment),
455546
("pedersen_commitment_dleq", &pedersen_commitment_dleq),
456547
("bbs_blind_commitment", &bbs_blind_commitment),
548+
("test_range", &test_range),
457549
("weird_linear_combination", &weird_linear_combination),
458550
("simple_subtractions", &simple_subtractions),
459551
("subtractions_with_shift", &subtractions_with_shift),

0 commit comments

Comments
 (0)