forked from facebook/winterfell
-
Notifications
You must be signed in to change notification settings - Fork 0
/
air.rs
94 lines (84 loc) · 3.43 KB
/
air.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
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
use winterfell::{
math::{fields::f128::BaseElement, FieldElement},
Air, AirContext, Assertion, EvaluationFrame, ProofOptions, TraceInfo,
TransitionConstraintDegree,
};
use super::TRACE_WIDTH;
use crate::utils::are_equal;
// FIBONACCI AIR
// ================================================================================================
pub struct MulFib8Air {
context: AirContext<BaseElement>,
result: BaseElement,
}
impl Air for MulFib8Air {
type BaseField = BaseElement;
type PublicInputs = BaseElement;
type GkrProof = ();
type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
fn new(trace_info: TraceInfo, pub_inputs: Self::BaseField, options: ProofOptions) -> Self {
let degrees = vec![
TransitionConstraintDegree::new(2),
TransitionConstraintDegree::new(2),
TransitionConstraintDegree::new(2),
TransitionConstraintDegree::new(2),
TransitionConstraintDegree::new(2),
TransitionConstraintDegree::new(2),
TransitionConstraintDegree::new(2),
TransitionConstraintDegree::new(2),
];
assert_eq!(TRACE_WIDTH, trace_info.width());
MulFib8Air {
context: AirContext::new(trace_info, degrees, 3, options),
result: pub_inputs,
}
}
fn context(&self) -> &AirContext<Self::BaseField> {
&self.context
}
fn evaluate_transition<E: FieldElement + From<Self::BaseField>>(
&self,
frame: &EvaluationFrame<E>,
_periodic_values: &[E],
result: &mut [E],
) {
let current = frame.current();
let next = frame.next();
// expected state width is 2 field elements
debug_assert_eq!(TRACE_WIDTH, current.len());
debug_assert_eq!(TRACE_WIDTH, next.len());
// constraints of multiplicative Fibonacci (with 8 registers) which state that:
// s_{0, i+1} = s_{6, i} * s_{7, i}
// s_{1, i+1} = s_{7, i} * s_{0, i+1}
// s_{2, i+1} = s_{0, i+1} * s_{1, i+1}
// s_{3, i+1} = s_{1, i+1} * s_{2, i+1}
// s_{4, i+1} = s_{2, i+1} * s_{3, i+1}
// s_{5, i+1} = s_{3, i+1} * s_{4, i+1}
// s_{6, i+1} = s_{4, i+1} * s_{5, i+1}
// s_{7, i+1} = s_{5, i+1} * s_{6, i+1}
result[0] = are_equal(next[0], current[6] * current[7]);
result[1] = are_equal(next[1], current[7] * next[0]);
result[2] = are_equal(next[2], next[0] * next[1]);
result[3] = are_equal(next[3], next[1] * next[2]);
result[4] = are_equal(next[4], next[2] * next[3]);
result[5] = are_equal(next[5], next[3] * next[4]);
result[6] = are_equal(next[6], next[4] * next[5]);
result[7] = are_equal(next[7], next[5] * next[6]);
}
fn get_assertions(&self) -> Vec<Assertion<Self::BaseField>> {
// a valid multiplicative Fibonacci sequence should start with 1, 2 and terminate
// with the expected result
let last_step = self.trace_length() - 1;
vec![
Assertion::single(0, 0, BaseElement::new(1)),
Assertion::single(1, 0, BaseElement::new(2)),
Assertion::single(6, last_step, self.result),
]
}
}