@@ -11,7 +11,7 @@ use crate::{
11
11
util:: {
12
12
common_gadget:: RestoreContextGadget ,
13
13
constraint_builder:: { ConstrainBuilderCommon , EVMConstraintBuilder } ,
14
- from_bytes, rlc, CachedRegion , Cell , RandomLinearCombination ,
14
+ from_bytes, rlc, CachedRegion , Cell , RandomLinearCombination , Word ,
15
15
} ,
16
16
} ,
17
17
table:: CallContextFieldTag ,
@@ -21,10 +21,13 @@ use crate::{
21
21
#[ derive( Clone , Debug ) ]
22
22
pub struct EcrecoverGadget < F > {
23
23
recovered : Cell < F > ,
24
- msg_hash_rlc : Cell < F > ,
25
24
sig_v_rlc : Cell < F > ,
25
+ sig_r_word : Word < F > ,
26
+ sig_s_word : Word < F > ,
27
+ msg_hash_word : Word < F > ,
26
28
sig_r_rlc : Cell < F > ,
27
29
sig_s_rlc : Cell < F > ,
30
+ msg_hash_rlc : Cell < F > ,
28
31
recovered_addr_rlc : RandomLinearCombination < F , N_BYTES_ACCOUNT_ADDRESS > ,
29
32
30
33
is_success : Cell < F > ,
@@ -51,6 +54,24 @@ impl<F: Field> ExecutionGadget<F> for EcrecoverGadget<F> {
51
54
cb. query_cell_phase2 ( ) ,
52
55
cb. query_keccak_rlc ( ) ,
53
56
) ;
57
+ let msg_hash_word: RandomLinearCombination < F , 32 > = cb. query_word_rlc ( ) ;
58
+ let sig_s_word: RandomLinearCombination < F , 32 > = cb. query_word_rlc ( ) ;
59
+ let sig_r_word: RandomLinearCombination < F , 32 > = cb. query_word_rlc ( ) ;
60
+ cb. require_equal (
61
+ "msg_hash_rlc" ,
62
+ msg_hash_rlc. expr ( ) ,
63
+ cb. keccak_rlc ( msg_hash_word. cells . clone ( ) . map ( |x| x. expr ( ) ) ) ,
64
+ ) ;
65
+ cb. require_equal (
66
+ "sig_r_rlc" ,
67
+ sig_r_rlc. expr ( ) ,
68
+ cb. keccak_rlc ( sig_r_word. cells . clone ( ) . map ( |x| x. expr ( ) ) ) ,
69
+ ) ;
70
+ cb. require_equal (
71
+ "sig_s_rlc" ,
72
+ sig_s_rlc. expr ( ) ,
73
+ cb. keccak_rlc ( sig_s_word. cells . clone ( ) . map ( |x| x. expr ( ) ) ) ,
74
+ ) ;
54
75
55
76
cb. condition ( recovered. expr ( ) , |cb| {
56
77
// if address was recovered, the sig_v (recovery ID) was correct.
@@ -61,11 +82,12 @@ impl<F: Field> ExecutionGadget<F> for EcrecoverGadget<F> {
61
82
62
83
// lookup to the sign_verify table
63
84
// || v | r | s | msg_hash | recovered_addr ||
85
+
64
86
cb. sig_table_lookup (
65
- msg_hash_rlc . expr ( ) ,
87
+ cb . word_rlc ( msg_hash_word . cells . clone ( ) . map ( |x| x . expr ( ) ) ) ,
66
88
sig_v_rlc. expr ( ) - 27 . expr ( ) ,
67
- sig_r_rlc . expr ( ) ,
68
- sig_s_rlc . expr ( ) ,
89
+ cb . word_rlc ( sig_r_word . cells . clone ( ) . map ( |x| x . expr ( ) ) ) ,
90
+ cb . word_rlc ( sig_s_word . cells . clone ( ) . map ( |x| x . expr ( ) ) ) ,
69
91
from_bytes:: expr ( & recovered_addr_rlc. cells ) ,
70
92
) ;
71
93
} ) ;
@@ -100,9 +122,12 @@ impl<F: Field> ExecutionGadget<F> for EcrecoverGadget<F> {
100
122
101
123
Self {
102
124
recovered,
125
+ msg_hash_word,
103
126
msg_hash_rlc,
104
127
sig_v_rlc,
128
+ sig_r_word,
105
129
sig_r_rlc,
130
+ sig_s_word,
106
131
sig_s_rlc,
107
132
recovered_addr_rlc,
108
133
is_success,
@@ -129,6 +154,8 @@ impl<F: Field> ExecutionGadget<F> for EcrecoverGadget<F> {
129
154
let recovered = !aux_data. recovered_addr . is_zero ( ) ;
130
155
self . recovered
131
156
. assign ( region, offset, Value :: known ( F :: from ( recovered as u64 ) ) ) ?;
157
+ self . msg_hash_word
158
+ . assign ( region, offset, Some ( aux_data. msg_hash . to_le_bytes ( ) ) ) ?;
132
159
self . msg_hash_rlc . assign (
133
160
region,
134
161
offset,
@@ -145,6 +172,10 @@ impl<F: Field> ExecutionGadget<F> for EcrecoverGadget<F> {
145
172
. keccak_input ( )
146
173
. map ( |r| rlc:: value ( & aux_data. sig_v . to_le_bytes ( ) , r) ) ,
147
174
) ?;
175
+ self . sig_r_word
176
+ . assign ( region, offset, Some ( aux_data. sig_r . to_le_bytes ( ) ) ) ?;
177
+ self . sig_s_word
178
+ . assign ( region, offset, Some ( aux_data. sig_s . to_le_bytes ( ) ) ) ?;
148
179
self . sig_r_rlc . assign (
149
180
region,
150
181
offset,
0 commit comments