Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Commit d383d23

Browse files
authored
fix: endianness (Fq) | lookup (word v keccak) | dev load (#755)
1 parent 3a8f950 commit d383d23

File tree

4 files changed

+88
-33
lines changed

4 files changed

+88
-33
lines changed

bus-mapping/src/circuit_input_builder.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,14 @@ pub fn keccak_inputs(block: &Block, code_db: &CodeDB) -> Result<Vec<Vec<u8>>, Er
633633
"keccak total len after txs: {}",
634634
keccak_inputs.iter().map(|i| i.len()).sum::<usize>()
635635
);
636+
// Ecrecover
637+
keccak_inputs.extend_from_slice(&keccak_inputs_sign_verify(
638+
&block.precompile_events.get_ecrecover_events(),
639+
));
640+
log::debug!(
641+
"keccak total len after ecrecover: {}",
642+
keccak_inputs.iter().map(|i| i.len()).sum::<usize>()
643+
);
636644
// PI circuit
637645
keccak_inputs.extend(keccak_inputs_pi_circuit(
638646
block.chain_id,

bus-mapping/src/evm/opcodes/precompiles/ecrecover.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use eth_types::{
22
sign_types::{recover_pk, SignData},
3-
Bytes, ToBigEndian,
3+
Bytes, ToBigEndian, ToLittleEndian,
44
};
55
use halo2_proofs::halo2curves::secp256k1::Fq;
66

@@ -33,13 +33,13 @@ pub(crate) fn opt_data(
3333
) {
3434
let sign_data = SignData {
3535
signature: (
36-
Fq::from_bytes(&aux_data.sig_r.to_be_bytes()).unwrap(),
37-
Fq::from_bytes(&aux_data.sig_s.to_be_bytes()).unwrap(),
36+
Fq::from_bytes(&aux_data.sig_r.to_le_bytes()).unwrap(),
37+
Fq::from_bytes(&aux_data.sig_s.to_le_bytes()).unwrap(),
3838
sig_v,
3939
),
4040
pk: recovered_pk,
4141
msg: Bytes::default(),
42-
msg_hash: Fq::from_bytes(&aux_data.msg_hash.to_be_bytes()).unwrap(),
42+
msg_hash: Fq::from_bytes(&aux_data.msg_hash.to_le_bytes()).unwrap(),
4343
};
4444
assert_eq!(aux_data.recovered_addr, sign_data.get_addr());
4545
(

zkevm-circuits/src/evm_circuit/execution/precompiles/ecrecover.rs

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
use array_init::array_init;
12
use bus_mapping::precompile::PrecompileAuxData;
23

34
use eth_types::{evm_types::GasCost, Field, ToLittleEndian, ToScalar};
45
use gadgets::util::{select, Expr};
56
use halo2_proofs::{circuit::Value, plonk::Error};
7+
use itertools::Itertools;
68

79
use crate::{
810
evm_circuit::{
911
execution::ExecutionGadget,
10-
param::N_BYTES_ACCOUNT_ADDRESS,
12+
param::{N_BYTES_ACCOUNT_ADDRESS, N_BYTES_WORD},
1113
step::ExecutionState,
1214
util::{
1315
common_gadget::RestoreContextGadget,
@@ -22,13 +24,17 @@ use crate::{
2224
#[derive(Clone, Debug)]
2325
pub struct EcrecoverGadget<F> {
2426
recovered: Cell<F>,
25-
msg_hash_rlc: Cell<F>,
26-
sig_v_rlc: Cell<F>,
27-
sig_r_rlc: Cell<F>,
28-
sig_s_rlc: Cell<F>,
29-
recovered_addr_rlc: RandomLinearCombination<F, N_BYTES_ACCOUNT_ADDRESS>,
27+
msg_hash_keccak_rlc: Cell<F>,
28+
sig_v_keccak_rlc: Cell<F>,
29+
sig_r_keccak_rlc: Cell<F>,
30+
sig_s_keccak_rlc: Cell<F>,
31+
recovered_addr_keccak_rlc: RandomLinearCombination<F, N_BYTES_ACCOUNT_ADDRESS>,
3032
gas_cost: Cell<F>,
3133

34+
msg_hash: [Cell<F>; N_BYTES_WORD],
35+
sig_r: [Cell<F>; N_BYTES_WORD],
36+
sig_s: [Cell<F>; N_BYTES_WORD],
37+
3238
is_success: Cell<F>,
3339
callee_address: Cell<F>,
3440
caller_id: Cell<F>,
@@ -45,7 +51,14 @@ impl<F: Field> ExecutionGadget<F> for EcrecoverGadget<F> {
4551
const NAME: &'static str = "ECRECOVER";
4652

4753
fn configure(cb: &mut EVMConstraintBuilder<F>) -> Self {
48-
let (recovered, msg_hash_rlc, sig_v_rlc, sig_r_rlc, sig_s_rlc, recovered_addr_rlc) = (
54+
let (
55+
recovered,
56+
msg_hash_keccak_rlc,
57+
sig_v_keccak_rlc,
58+
sig_r_keccak_rlc,
59+
sig_s_keccak_rlc,
60+
recovered_addr_keccak_rlc,
61+
) = (
4962
cb.query_bool(),
5063
cb.query_cell_phase2(),
5164
cb.query_cell_phase2(),
@@ -60,21 +73,41 @@ impl<F: Field> ExecutionGadget<F> for EcrecoverGadget<F> {
6073
GasCost::PRECOMPILE_ECRECOVER_BASE.expr(),
6174
);
6275

76+
let msg_hash = array_init(|_| cb.query_byte());
77+
let sig_r = array_init(|_| cb.query_byte());
78+
let sig_s = array_init(|_| cb.query_byte());
79+
80+
cb.require_equal(
81+
"msg hash cells assigned incorrectly",
82+
msg_hash_keccak_rlc.expr(),
83+
cb.keccak_rlc(msg_hash.clone().map(|x| x.expr())),
84+
);
85+
cb.require_equal(
86+
"sig_r cells assigned incorrectly",
87+
sig_r_keccak_rlc.expr(),
88+
cb.keccak_rlc(sig_r.clone().map(|x| x.expr())),
89+
);
90+
cb.require_equal(
91+
"sig_s cells assigned incorrectly",
92+
sig_s_keccak_rlc.expr(),
93+
cb.keccak_rlc(sig_s.clone().map(|x| x.expr())),
94+
);
95+
6396
cb.condition(recovered.expr(), |cb| {
6497
// if address was recovered, the sig_v (recovery ID) was correct.
6598
cb.require_zero(
6699
"sig_v == 27 or 28",
67-
(sig_v_rlc.expr() - 27.expr()) * (sig_v_rlc.expr() - 28.expr()),
100+
(sig_v_keccak_rlc.expr() - 27.expr()) * (sig_v_keccak_rlc.expr() - 28.expr()),
68101
);
69102

70103
// lookup to the sign_verify table
71104
// || v | r | s | msg_hash | recovered_addr ||
72105
cb.sig_table_lookup(
73-
msg_hash_rlc.expr(),
74-
sig_v_rlc.expr() - 27.expr(),
75-
sig_r_rlc.expr(),
76-
sig_s_rlc.expr(),
77-
from_bytes::expr(&recovered_addr_rlc.cells),
106+
cb.word_rlc(msg_hash.clone().map(|x| x.expr())),
107+
sig_v_keccak_rlc.expr() - 27.expr(),
108+
cb.word_rlc(sig_r.clone().map(|x| x.expr())),
109+
cb.word_rlc(sig_s.clone().map(|x| x.expr())),
110+
from_bytes::expr(&recovered_addr_keccak_rlc.cells),
78111
);
79112
});
80113

@@ -108,13 +141,17 @@ impl<F: Field> ExecutionGadget<F> for EcrecoverGadget<F> {
108141

109142
Self {
110143
recovered,
111-
msg_hash_rlc,
112-
sig_v_rlc,
113-
sig_r_rlc,
114-
sig_s_rlc,
115-
recovered_addr_rlc,
144+
msg_hash_keccak_rlc,
145+
sig_v_keccak_rlc,
146+
sig_r_keccak_rlc,
147+
sig_s_keccak_rlc,
148+
recovered_addr_keccak_rlc,
116149
gas_cost,
117150

151+
msg_hash,
152+
sig_r,
153+
sig_s,
154+
118155
is_success,
119156
callee_address,
120157
caller_id,
@@ -139,39 +176,48 @@ impl<F: Field> ExecutionGadget<F> for EcrecoverGadget<F> {
139176
let recovered = !aux_data.recovered_addr.is_zero();
140177
self.recovered
141178
.assign(region, offset, Value::known(F::from(recovered as u64)))?;
142-
self.msg_hash_rlc.assign(
179+
self.msg_hash_keccak_rlc.assign(
143180
region,
144181
offset,
145182
region
146183
.challenges()
147184
.keccak_input()
148185
.map(|r| rlc::value(&aux_data.msg_hash.to_le_bytes(), r)),
149186
)?;
150-
self.sig_v_rlc.assign(
187+
self.sig_v_keccak_rlc.assign(
151188
region,
152189
offset,
153190
region
154191
.challenges()
155192
.keccak_input()
156193
.map(|r| rlc::value(&aux_data.sig_v.to_le_bytes(), r)),
157194
)?;
158-
self.sig_r_rlc.assign(
195+
self.sig_r_keccak_rlc.assign(
159196
region,
160197
offset,
161198
region
162199
.challenges()
163200
.keccak_input()
164201
.map(|r| rlc::value(&aux_data.sig_r.to_le_bytes(), r)),
165202
)?;
166-
self.sig_s_rlc.assign(
203+
self.sig_s_keccak_rlc.assign(
167204
region,
168205
offset,
169206
region
170207
.challenges()
171208
.keccak_input()
172209
.map(|r| rlc::value(&aux_data.sig_s.to_le_bytes(), r)),
173210
)?;
174-
self.recovered_addr_rlc.assign(
211+
for (cells, value) in [
212+
(&self.msg_hash, aux_data.msg_hash),
213+
(&self.sig_r, aux_data.sig_r),
214+
(&self.sig_s, aux_data.sig_s),
215+
] {
216+
for (cell, &byte_value) in cells.iter().zip_eq(value.to_le_bytes().iter()) {
217+
cell.assign(region, offset, Value::known(F::from(byte_value as u64)))?;
218+
}
219+
}
220+
self.recovered_addr_keccak_rlc.assign(
175221
region,
176222
offset,
177223
Some({

zkevm-circuits/src/table.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2234,22 +2234,23 @@ impl SigTable {
22342234
|mut region| {
22352235
let signatures: Vec<SignData> = block.get_sign_data(false);
22362236

2237+
let evm_word = challenges.evm_word();
22372238
for (offset, sign_data) in signatures.iter().enumerate() {
2238-
let msg_hash_rlc = challenges.keccak_input().map(|challenge| {
2239+
let msg_hash_rlc = evm_word.map(|challenge| {
22392240
rlc::value(
2240-
sign_data.msg_hash.to_bytes().iter().rev().collect_vec(),
2241+
sign_data.msg_hash.to_bytes().iter().collect_vec(),
22412242
challenge,
22422243
)
22432244
});
2244-
let sig_r_rlc = challenges.keccak_input().map(|challenge| {
2245+
let sig_r_rlc = evm_word.map(|challenge| {
22452246
rlc::value(
2246-
sign_data.signature.0.to_bytes().iter().rev().collect_vec(),
2247+
sign_data.signature.0.to_bytes().iter().collect_vec(),
22472248
challenge,
22482249
)
22492250
});
2250-
let sig_s_rlc = challenges.keccak_input().map(|challenge| {
2251+
let sig_s_rlc = evm_word.map(|challenge| {
22512252
rlc::value(
2252-
sign_data.signature.1.to_bytes().iter().rev().collect_vec(),
2253+
sign_data.signature.1.to_bytes().iter().collect_vec(),
22532254
challenge,
22542255
)
22552256
});

0 commit comments

Comments
 (0)