-
Notifications
You must be signed in to change notification settings - Fork 1
/
verifier.rs
184 lines (173 loc) · 5.62 KB
/
verifier.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
use crate::channel::Channel;
use crate::field::{Field, FieldElement};
use crate::merkle_tree::MerkleTree;
///
/// panics for invalid proof.
pub fn verify_proof(
num_of_queries: usize,
maximum_random_int: u64,
blow_up_factor: usize,
field: Field,
fri_domains: &[Vec<FieldElement>],
compressed_proof: &[Vec<u8>],
) {
let mut channel = Channel::new();
// merkle root of trace polynomial LDE
let f_merkle_root = compressed_proof[0].clone();
channel.send(f_merkle_root.clone());
// get random values for calculating composition polynomial
let _alpha_0 = channel.receive_random_field_element(field);
let _alpha_1 = channel.receive_random_field_element(field);
let _alpha_2 = channel.receive_random_field_element(field);
let cp_merkle_root = compressed_proof[1].clone();
channel.send(cp_merkle_root.clone());
// commit to fri
let mut fri_merkle_roots = Vec::new();
let mut betas = Vec::new();
for i in 0..10 {
let beta = channel.receive_random_field_element(field);
betas.push(beta);
let fri_root = compressed_proof[2 + i].clone();
channel.send(fri_root.clone());
fri_merkle_roots.push(fri_root);
}
let last_layer_free_term = compressed_proof[12].clone();
channel.send(last_layer_free_term.clone());
let mut base_idx = 13;
// decommit fri
for i in 0..num_of_queries {
let idx = channel.receive_random_int(0, maximum_random_int, true) as usize;
// verifiy the queries too.
verify_queries(
base_idx + i,
idx,
blow_up_factor,
field,
&fri_merkle_roots,
&fri_domains,
compressed_proof,
&betas,
&mut channel,
);
base_idx += 46;
}
}
pub fn verify_fri_layers(
base_idx: usize,
idx: usize,
field: Field,
fri_merkle_roots: &[Vec<u8>],
fri_domains: &[Vec<FieldElement>],
compressed_proof: &[Vec<u8>],
betas: &[FieldElement],
channel: &mut Channel,
) {
let lengths = vec![8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16];
for i in 0..10 {
// verify the fri layers
let length = lengths[i];
let elem_idx = idx % length;
let elem = compressed_proof[base_idx + 4 * i].clone();
channel.send(elem.clone());
let elem_proof = compressed_proof[base_idx + 4 * i + 1].clone();
channel.send(elem_proof.clone());
let merkle_root = if i == 0 {
compressed_proof[1].clone()
} else {
fri_merkle_roots[i - 1].clone()
};
if i != 0 {
// checking fri polynomials consistency.
let prev_elem =
FieldElement::from_bytes(&compressed_proof[base_idx + 4 * (i - 1)].clone());
let prev_sibling =
FieldElement::from_bytes(&compressed_proof[base_idx + 4 * (i - 1) + 2].clone());
let two = FieldElement::new(2, field);
let computed_elem = (prev_elem + prev_sibling) / two
+ (betas[i - 1] * (prev_elem - prev_sibling)
/ (two * fri_domains[i - 1][idx % lengths[i - 1]]));
assert!(computed_elem.0 == FieldElement::from_bytes(&elem).0);
}
assert!(MerkleTree::validate(
merkle_root.clone(),
elem_proof,
elem_idx,
elem.clone(),
length,
));
let sibling_idx = (idx + length / 2) % length;
let sibling = compressed_proof[base_idx + 4 * i + 2].clone();
channel.send(sibling.clone());
let sibling_proof = compressed_proof[base_idx + 4 * i + 3].clone();
channel.send(sibling_proof.clone());
assert!(MerkleTree::validate(
merkle_root,
sibling_proof,
sibling_idx,
sibling.clone(),
length,
));
}
let last_elem = compressed_proof[base_idx + 40].clone();
channel.send(last_elem);
}
pub fn verify_queries(
base_idx: usize,
idx: usize,
blow_up_factor: usize,
field: Field,
fri_merkle_roots: &[Vec<u8>],
fri_domains: &[Vec<FieldElement>],
compressed_proof: &[Vec<u8>],
betas: &[FieldElement],
channel: &mut Channel,
) {
let len = 8192;
let f_merkle_root = compressed_proof[0].clone();
// verifiy the queries too.
let f_x = compressed_proof[base_idx].clone();
channel.send(f_x.clone());
let f_x_auth = compressed_proof[base_idx + 1].clone();
channel.send(f_x_auth.clone());
assert!(MerkleTree::validate(
f_merkle_root.clone(),
f_x_auth,
idx,
f_x,
len
));
let f_gx = compressed_proof[base_idx + 2].clone();
channel.send(f_gx.clone());
let f_gx_auth = compressed_proof[base_idx + 3].clone();
channel.send(f_gx_auth.clone());
assert!(MerkleTree::validate(
f_merkle_root.clone(),
f_gx_auth,
idx + blow_up_factor,
f_gx,
len
));
let f_g2x = compressed_proof[base_idx + 4].clone();
channel.send(f_g2x.clone());
let f_g2x_auth = compressed_proof[base_idx + 5].clone();
channel.send(f_g2x_auth.clone());
assert!(MerkleTree::validate(
f_merkle_root.clone(),
f_g2x_auth,
idx + 2 * blow_up_factor,
f_g2x,
len
));
// can we actually able to relate cp and f_g2x,f_gx, f_x?
// it looks like we need to generate p1, p2 and p3 for relating cp and f_g2x, f_gx, f_x -> so, verifier could not do that.
verify_fri_layers(
base_idx + 6,
idx,
field,
fri_merkle_roots,
fri_domains,
compressed_proof,
betas,
channel,
);
}