This repository has been archived by the owner on Jun 24, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlookup_1bit.rs
125 lines (113 loc) · 4.01 KB
/
lookup_1bit.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use math::PrimeField;
use scheme::r1cs::{ConstraintSynthesizer, ConstraintSystem, SynthesisError};
use crate::Vec;
struct Lookup1bitDemo<E: PrimeField> {
in_bit: Option<E>,
in_constants: Vec<Option<E>>,
}
impl<E: PrimeField> ConstraintSynthesizer<E> for Lookup1bitDemo<E> {
fn generate_constraints<CS: ConstraintSystem<E>>(
self,
cs: &mut CS,
) -> Result<(), SynthesisError> {
assert!(self.in_constants.len() == 2);
// assert!(self.in_bit == Some(E::zero()) || self.in_bit == Some(E::one()));
let index = match self.in_bit {
Some(a_value) => {
let mut tmp: usize = 0;
if a_value == E::one() {
tmp += 1;
}
Some(tmp)
}
_ => None,
};
let res: Option<E>;
if index.is_some() {
res = self.in_constants[index.unwrap()];
} else {
res = None;
}
let res_var = cs
.alloc(
|| "res_var",
|| res.ok_or(SynthesisError::AssignmentMissing),
)
.unwrap();
let in_constants_var0 = cs
.alloc(
|| "in_constants_var_0",
|| self.in_constants[0].ok_or(SynthesisError::AssignmentMissing),
)
.unwrap();
// 构建约束(c[0] + b*c[1] - b*c[0])*1 = r
/* 这里有问题。
1. self.in_constants和self.in_bit中的成员变量位None的时候,如何避免对None.unwrap()。
解决方法:使用is_some()函数对值进行校验
2. 注意所有alloc的变量都必须在约束系统中进行出现。
*/
let tmp_var = cs.alloc(
|| "tmp_var=b*c[1]",
|| {
if self.in_bit.is_some() && self.in_constants[1].is_some() {
let mut tmp = self.in_bit.unwrap();
tmp.mul_assign(&self.in_constants[1].unwrap());
Ok(tmp)
} else {
Err(SynthesisError::AssignmentMissing)
}
},
)?;
let tmp1_var = cs.alloc(
|| "tmp1_var=b*c[0]",
|| {
if self.in_bit.is_some() && self.in_constants[0].is_some() {
let mut in_constants_one_value = E::one();
in_constants_one_value = -in_constants_one_value;
let mut tmp = self.in_bit.unwrap();
tmp.mul_assign(&self.in_constants[0].unwrap());
tmp.mul_assign(&in_constants_one_value);
Ok(tmp)
} else {
Err(SynthesisError::AssignmentMissing)
}
},
)?;
cs.enforce(
|| format!("lookup_1bit_gadget"),
|lc| lc + in_constants_var0 + tmp_var + tmp1_var,
|lc| lc + CS::one(),
|lc| lc + res_var,
);
Ok(())
}
}
#[test]
fn test_lookup1bit_demo() {
use curve::bn_256::{Bn_256, Fr};
use math::test_rng;
use scheme::groth16::{
create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof,
};
let mut rng = &mut test_rng();
println!("Creating parameters...");
let params = {
let c = Lookup1bitDemo::<Fr> {
in_bit: None,
in_constants: vec![None; 2],
};
generate_random_parameters::<Bn_256, _, _>(c, &mut rng).unwrap()
};
let pvk = prepare_verifying_key(¶ms.vk);
println!("Creating proofs...");
let mut in_constants_value: Vec<Option<Fr>> = Vec::with_capacity(2);
// Fr::from_str("9") 返回的是Option变量
in_constants_value.push(Some(Fr::from(9u32)));
in_constants_value.push(Some(Fr::from(10u32)));
let c1 = Lookup1bitDemo::<Fr> {
in_bit: Some(Fr::from(1u32)),
in_constants: in_constants_value.clone(),
};
let proof = create_random_proof(c1, ¶ms, rng).unwrap();
assert!(verify_proof(&pvk, &proof, &[]).unwrap());
}