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
use ;
use BasicBlockBuilder;
use crate::;
/// Given a stack in the following initial configuration [b0, b1, a0, a1, ...] where a = (a0, a1)
/// and b = (b0, b1) represent elements in the extension field of degree 2, this series
/// of operations outputs the result c = (c0, c1) where c0 = a0 + b0 and c1 = a1 + b1.
///
/// This operation takes 5 VM cycles.
/// Given a stack in the following initial configuration [b0, b1, a0, a1, ...] where a = (a0, a1)
/// and b = (b0, b1) represent elements in the extension field of degree 2, this series
/// of operations outputs the result c = (c0, c1) where c0 = a0 - b0 and c1 = a1 - b1.
///
/// This operation takes 7 VM cycles.
/// Given a stack with initial configuration given by [b0, b1, a0, a1, ...] where a = (a0, a1)
/// and b = (b0, b1) represent elements in the extension field of degree 2, this series
/// of operations outputs the product c = (c0, c1)
/// c0 = a0*b0 + 7*a1*b1 and c1 = a0*b1 + a1*b0.
///
/// This operation takes 3 VM cycles.
/// Given a stack in the following initial configuration [b0, b1, a0, a1, ...] where a = (a0, a1)
/// and b = (b0, b1) represent elements in the extension field of degree 2, this series
/// of operations outputs the result c = (c0, c1) where c = a * b^-1.
///
/// This operation takes 11 VM cycles.
/// Given a stack with initial configuration given by [a0, a1, ...] where a = (a0, a1)
/// represents elements in the extension field of degree 2, the procedure outputs
/// the negative of a, i.e. [-a0, -a1, ...].
///
/// This operation takes 4 VM cycles.
/// Given an invertible quadratic extension field element on the stack, this routine computes
/// multiplicative inverse of that element, using non-deterministic technique
/// (i.e. it takes help of advice provider).
/// To ensure that non-deterministic computation resulted in correct value, it multiplies input
/// operand with computed output, over quadratic extension field which must produce multiplicative
/// identity (1, 0) of quadratic extension field. In case input operand is additive identity which
/// can't be inverted, program execution fails, as advice provider won't calculate multiplicative
/// inverse in that case.
///
/// Expected input stack
///
/// [a0, a1, ...] | a = (a0, a1) ∈ Quadratic extension field over F_p, p = 2^64 - 2^32 + 1
///
/// Expected output stack
///
/// [a'0, a'1, ...] | a' = (a'0, a'1) ∈ Quadratic extension field over F_p, p = 2^64 - 2^32 + 1
///
/// Following is what is checked after reading result of computation, performed outside of VM
///
/// a = (a0, a1)
/// a' = (a'0, a'1) ( = a ^ -1 )
///
/// b = a * a' ( mod Q ) | Q = irreducible polynomial x^2 - 7 over F_p, p = 2^64 - 2^32 + 1
/// assert b = (1, 0) | (1, 0) is the multiplicative identity of extension field.
///
/// This operation takes 8 VM cycles.