1
+ use std:: collections:: HashMap ;
1
2
use triton_vm:: prelude:: * ;
2
3
3
4
use crate :: data_type:: DataType ;
4
5
use crate :: library:: Library ;
5
6
use crate :: traits:: basic_snippet:: BasicSnippet ;
6
-
7
+ use crate :: traits:: basic_snippet:: Reviewer ;
8
+ use crate :: traits:: basic_snippet:: SignOffFingerprint ;
9
+
10
+ /// Take an [extension field element](XFieldElement) to the fourth power.
11
+ ///
12
+ /// ### Behavior
13
+ ///
14
+ /// ```text
15
+ /// BEFORE: _ [arg; 3]
16
+ /// AFTER: _ [result; 3]
17
+ /// ```
18
+ ///
19
+ /// ### Preconditions
20
+ ///
21
+ /// None.
22
+ ///
23
+ /// ### Postconditions
24
+ ///
25
+ /// - the result is the argument raised to the fourth power
7
26
pub struct ToTheFourth ;
8
27
9
28
impl BasicSnippet for ToTheFourth {
@@ -19,10 +38,9 @@ impl BasicSnippet for ToTheFourth {
19
38
"tasmlib_arithmetic_xfe_to_the_fourth" . to_owned ( )
20
39
}
21
40
22
- fn code ( & self , _library : & mut Library ) -> Vec < LabelledInstruction > {
23
- let entrypoint = self . entrypoint ( ) ;
41
+ fn code ( & self , _: & mut Library ) -> Vec < LabelledInstruction > {
24
42
triton_asm ! (
25
- { entrypoint} :
43
+ { self . entrypoint( ) } :
26
44
dup 2
27
45
dup 2
28
46
dup 2
@@ -36,68 +54,59 @@ impl BasicSnippet for ToTheFourth {
36
54
return
37
55
)
38
56
}
57
+
58
+ fn sign_offs ( & self ) -> HashMap < Reviewer , SignOffFingerprint > {
59
+ let mut sign_offs = HashMap :: new ( ) ;
60
+ sign_offs. insert ( Reviewer ( "ferdinand" ) , 0x7277edad6da06ec . into ( ) ) ;
61
+ sign_offs
62
+ }
39
63
}
40
64
41
65
#[ cfg( test) ]
42
66
mod tests {
43
- use itertools:: Itertools ;
44
- use num:: One ;
45
- use num:: Zero ;
46
67
use rand:: prelude:: * ;
47
68
use triton_vm:: twenty_first:: math:: traits:: ModPowU32 ;
48
- use triton_vm:: twenty_first:: math:: x_field_element:: EXTENSION_DEGREE ;
49
69
50
70
use super :: * ;
51
71
use crate :: arithmetic:: xfe:: mod_pow_u32_generic:: XfeModPowU32Generic ;
72
+ use crate :: pop_encodable;
73
+ use crate :: push_encodable;
52
74
use crate :: snippet_bencher:: BenchmarkCase ;
53
75
use crate :: test_helpers:: test_rust_equivalence_given_complete_state;
54
76
use crate :: traits:: closure:: Closure ;
55
77
use crate :: traits:: closure:: ShadowedClosure ;
56
78
use crate :: traits:: rust_shadow:: RustShadow ;
57
79
58
80
impl ToTheFourth {
59
- fn setup_init_stack ( & self , input_value : XFieldElement ) -> Vec < BFieldElement > {
60
- [
61
- self . init_stack_for_isolated_run ( ) ,
62
- input_value. encode ( ) . into_iter ( ) . rev ( ) . collect_vec ( ) ,
63
- ]
64
- . concat ( )
81
+ fn setup_init_stack ( & self , arg : XFieldElement ) -> Vec < BFieldElement > {
82
+ let mut stack = self . init_stack_for_isolated_run ( ) ;
83
+ push_encodable ( & mut stack, & arg) ;
84
+
85
+ stack
65
86
}
66
87
}
67
88
68
89
impl Closure for ToTheFourth {
69
90
fn rust_shadow ( & self , stack : & mut Vec < BFieldElement > ) {
70
- let input = XFieldElement :: new ( [
71
- stack. pop ( ) . unwrap ( ) ,
72
- stack. pop ( ) . unwrap ( ) ,
73
- stack. pop ( ) . unwrap ( ) ,
74
- ] ) ;
75
- let result = input. mod_pow_u32 ( 4 ) ;
76
- for word in result. encode ( ) . into_iter ( ) . rev ( ) {
77
- stack. push ( word)
78
- }
91
+ let arg = pop_encodable :: < XFieldElement > ( stack) ;
92
+ push_encodable ( stack, & arg. mod_pow_u32 ( 4 ) ) ;
79
93
}
80
94
81
95
fn pseudorandom_initial_state (
82
96
& self ,
83
97
seed : [ u8 ; 32 ] ,
84
- _bench_case : Option < BenchmarkCase > ,
98
+ _ : Option < BenchmarkCase > ,
85
99
) -> Vec < BFieldElement > {
86
- let mut rng = StdRng :: from_seed ( seed) ;
87
- let random_input: XFieldElement = rng. gen ( ) ;
88
-
89
- self . setup_init_stack ( random_input)
100
+ self . setup_init_stack ( StdRng :: from_seed ( seed) . gen ( ) )
90
101
}
91
102
92
103
fn corner_case_initial_states ( & self ) -> Vec < Vec < BFieldElement > > {
93
- let zero = self . setup_init_stack ( XFieldElement :: zero ( ) ) ;
94
- let one = self . setup_init_stack ( XFieldElement :: one ( ) ) ;
95
-
96
- let max_bfe = BFieldElement :: new ( BFieldElement :: MAX ) ;
97
- let max_max_max =
98
- self . setup_init_stack ( XFieldElement :: new ( [ max_bfe; EXTENSION_DEGREE ] ) ) ;
104
+ let bfe_max = BFieldElement :: MAX ;
105
+ let xfe_max = xfe ! ( [ bfe_max, bfe_max, bfe_max] ) ;
99
106
100
- vec ! [ zero, one, max_max_max]
107
+ xfe_array ! [ 0 , 1 , xfe_max]
108
+ . map ( |arg| self . setup_init_stack ( arg) )
109
+ . to_vec ( )
101
110
}
102
111
}
103
112
@@ -108,42 +117,29 @@ mod tests {
108
117
109
118
#[ test]
110
119
fn compare_to_generic_pow_u32 ( ) {
111
- // Run `to_the_fourth` snippet
112
- let input: XFieldElement = random ( ) ;
113
- let init_stack_to_fourth = [
114
- ToTheFourth . init_stack_for_isolated_run ( ) ,
115
- input. coefficients . into_iter ( ) . rev ( ) . collect_vec ( ) ,
116
- ]
117
- . concat ( ) ;
120
+ let input = random ( ) ;
121
+
118
122
let final_state_from_to_fourth = test_rust_equivalence_given_complete_state (
119
123
& ShadowedClosure :: new ( ToTheFourth ) ,
120
- & init_stack_to_fourth ,
124
+ & ToTheFourth . setup_init_stack ( input ) ,
121
125
& [ ] ,
122
126
& NonDeterminism :: default ( ) ,
123
127
& None ,
124
128
None ,
125
129
) ;
126
130
127
- // Run snippet for generic pow
128
- let init_stack_to_generic = [
129
- XfeModPowU32Generic . init_stack_for_isolated_run ( ) ,
130
- vec ! [ BFieldElement :: new( 4 ) ] ,
131
- input. coefficients . into_iter ( ) . rev ( ) . collect_vec ( ) ,
132
- ]
133
- . concat ( ) ;
134
131
let final_state_from_generic = test_rust_equivalence_given_complete_state (
135
132
& ShadowedClosure :: new ( XfeModPowU32Generic ) ,
136
- & init_stack_to_generic ,
133
+ & XfeModPowU32Generic . prepare_state ( input , 4 ) ,
137
134
& [ ] ,
138
135
& NonDeterminism :: default ( ) ,
139
136
& None ,
140
137
None ,
141
138
) ;
142
139
143
- // Assert that height agrees, and the top-3 elements agree
144
140
assert_eq ! (
145
- final_state_from_generic. op_stack. stack . len( ) ,
146
- final_state_from_to_fourth. op_stack. stack . len( )
141
+ final_state_from_generic. op_stack. len( ) ,
142
+ final_state_from_to_fourth. op_stack. len( ) ,
147
143
) ;
148
144
assert_eq ! (
149
145
final_state_from_generic. op_stack. stack[ 16 ..=18 ] ,
0 commit comments