Skip to content

Commit 8cac694

Browse files
committed
check & assign is_valid
1 parent fa2c940 commit 8cac694

File tree

3 files changed

+58
-38
lines changed

3 files changed

+58
-38
lines changed

eth-types/src/sign_types.rs

+20
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,26 @@ pub fn verify<
9797
r == r_candidate
9898
}
9999

100+
/// verify r1 signature from bytes representation.
101+
pub fn verify_r1_bytes(
102+
pub_key: (&[u8; 32], &[u8; 32]),
103+
r: &[u8; 32],
104+
s: &[u8; 32],
105+
msg_hash: &[u8; 32],
106+
// if pubkey is provided rather than from recovered , v is not necessary.
107+
_v: Option<bool>,
108+
) -> bool {
109+
// Verify
110+
let x = Fp_R1::from_bytes(pub_key.0);
111+
let y = Fp_R1::from_bytes(pub_key.1);
112+
let pk = Secp256r1Affine::from_xy(x.unwrap(), y.unwrap()).unwrap();
113+
let r = Fq_R1::from_bytes(r).unwrap();
114+
let s = Fq_R1::from_bytes(s).unwrap();
115+
let msg_hash = Fq_R1::from_bytes(msg_hash).unwrap();
116+
117+
verify(pk, r, s, msg_hash, None)
118+
}
119+
100120
// convert Fp to Fq
101121
fn mod_n<Fp: PrimeField<Repr = [u8; 32]>, Fq: PrimeField + FromUniformBytes<64>>(x: Fp) -> Fq {
102122
let mut x_repr = [0u8; 32];

zkevm-circuits/src/evm_circuit/execution.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ use pc::PcGadget;
216216
use pop::PopGadget;
217217
use precompiles::{
218218
BasePrecompileGadget, EcAddGadget, EcMulGadget, EcPairingGadget, EcrecoverGadget,
219-
IdentityGadget, ModExpGadget, SHA256Gadget, P256VerifyGadget,
219+
IdentityGadget, ModExpGadget, P256VerifyGadget, SHA256Gadget,
220220
};
221221
use push::PushGadget;
222222
use return_revert::ReturnRevertGadget;

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

+37-37
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::util::Field;
22
use bus_mapping::precompile::{PrecompileAuxData, PrecompileCalls};
3-
use eth_types::{evm_types::GasCost, word, ToLittleEndian, U256};
3+
use eth_types::{evm_types::GasCost, sign_types::verify_r1_bytes, word, ToLittleEndian, U256};
44
use gadgets::util::{and, not, or, select, sum, Expr};
55
use gadgets::ToScalar;
66
use halo2_proofs::{
@@ -49,7 +49,6 @@ pub struct P256VerifyGadget<F> {
4949
sig_s_keccak_rlc: Cell<F>,
5050
// pubkey_x_keccak_rlc: Cell<F>,
5151
// pubkey_y_keccak_rlc: Cell<F>,
52-
5352
msg_hash_raw: Word<F>,
5453
msg_hash: Word<F>,
5554
fq_modulus: Word<F>,
@@ -120,7 +119,7 @@ impl<F: Field> ExecutionGadget<F> for P256VerifyGadget<F> {
120119
let pk_y = cb.query_word_rlc();
121120
let pk_x_canonical = LtWordGadget::construct(cb, &pk_x, &fp_modulus);
122121
let pk_y_canonical = LtWordGadget::construct(cb, &pk_y, &fp_modulus);
123-
122+
124123
let x_y_canonical = and::expr([pk_x_canonical.expr(), pk_y_canonical.expr()]);
125124

126125
cb.require_equal(
@@ -195,34 +194,26 @@ impl<F: Field> ExecutionGadget<F> for P256VerifyGadget<F> {
195194
// lookup to the sign_verify table:
196195
//
197196
// || msg_hash | v(0) | r | s | recovered_addr(0) | is_valid ||
198-
cb.condition(r_s_canonical.expr(),
199-
|cb| {
200-
cb.sig_table_lookup(
201-
msg_hash.expr(),
202-
// v set to zero
203-
0.expr(),
204-
sig_r.expr(),
205-
sig_s.expr(),
206-
// recovered addr set to 0.
207-
0.expr(),
208-
is_valid.expr(),
209-
);
210-
},
211-
);
212-
// check r, s is canonical
213-
cb.condition(not::expr(r_s_canonical.expr()), |cb| {
214-
cb.require_zero(
215-
"is_valid == false if r or s not canonical",
197+
cb.condition(r_s_canonical.expr(), |cb| {
198+
cb.sig_table_lookup(
199+
msg_hash.expr(),
200+
// v set to zero
201+
0.expr(),
202+
sig_r.expr(),
203+
sig_s.expr(),
204+
// recovered addr set to 0.
205+
0.expr(),
216206
is_valid.expr(),
217207
);
218208
});
209+
// check r, s is canonical
210+
cb.condition(not::expr(r_s_canonical.expr()), |cb| {
211+
cb.require_zero("is_valid == false if r or s not canonical", is_valid.expr());
212+
});
219213

220214
// check x, y is canonical
221215
cb.condition(not::expr(x_y_canonical.expr()), |cb| {
222-
cb.require_zero(
223-
"is_valid == false if x or y not canonical",
224-
is_valid.expr(),
225-
);
216+
cb.require_zero("is_valid == false if x or y not canonical", is_valid.expr());
226217
});
227218
// cb.condition(not::expr(recovered.expr()), |cb| {
228219
// cb.require_zero(
@@ -270,13 +261,9 @@ impl<F: Field> ExecutionGadget<F> for P256VerifyGadget<F> {
270261
+ (sig_r_keccak_rlc.expr() * r_pow_32)
271262
+ sig_s_keccak_rlc.expr(),
272263
);
273-
// TODO: constrain output first byte is bool .
274-
// cb.require_equal(
275-
// "output bytes (RLC) = recovered address",
276-
// output_bytes_rlc.expr(),
277-
// recovered_addr_keccak_rlc.expr(),
278-
// );
279-
264+
// constrain output first byte is bool .
265+
cb.require_boolean("output first byte is bool", output_bytes_rlc.expr());
266+
280267
let restore_context = super::gen_restore_context(
281268
cb,
282269
is_root.expr(),
@@ -297,7 +284,6 @@ impl<F: Field> ExecutionGadget<F> for P256VerifyGadget<F> {
297284
sig_r_keccak_rlc,
298285
sig_s_keccak_rlc,
299286
//recovered_addr_keccak_rlc,
300-
301287
msg_hash_raw,
302288
msg_hash,
303289
fq_modulus,
@@ -359,7 +345,6 @@ impl<F: Field> ExecutionGadget<F> for P256VerifyGadget<F> {
359345
.keccak_input()
360346
.map(|r| rlc::value(aux_data.return_bytes.iter().rev(), r)),
361347
)?;
362-
// check is_valid of sig ?
363348
self.msg_hash_keccak_rlc.assign(
364349
region,
365350
offset,
@@ -368,7 +353,7 @@ impl<F: Field> ExecutionGadget<F> for P256VerifyGadget<F> {
368353
.keccak_input()
369354
.map(|r| rlc::value(&aux_data.msg_hash.to_le_bytes(), r)),
370355
)?;
371-
356+
372357
self.sig_r_keccak_rlc.assign(
373358
region,
374359
offset,
@@ -414,8 +399,23 @@ impl<F: Field> ExecutionGadget<F> for P256VerifyGadget<F> {
414399
self.sig_s_canonical
415400
.assign(region, offset, aux_data.sig_s, *FQ_MODULUS)?;
416401
// assign pk_x_canonical, pk_y_canonical
417-
self.pk_x_canonical.assign(region, offset, aux_data.pubkey_x, *FP_MODULUS)?;
418-
self.pk_y_canonical.assign(region, offset, aux_data.pubkey_y, *FP_MODULUS)?;
402+
self.pk_x_canonical
403+
.assign(region, offset, aux_data.pubkey_x, *FP_MODULUS)?;
404+
self.pk_y_canonical
405+
.assign(region, offset, aux_data.pubkey_y, *FP_MODULUS)?;
406+
// TODO: assign is_valid correctly
407+
let pub_key_bytes = (
408+
&aux_data.pubkey_x.to_le_bytes(),
409+
&aux_data.pubkey_y.to_le_bytes(),
410+
);
411+
let r_bytes = aux_data.sig_r.to_le_bytes();
412+
let s_bytes = aux_data.sig_s.to_le_bytes();
413+
let msg_hash_bytes = aux_data.msg_hash.to_le_bytes();
414+
415+
let is_sig_valid =
416+
verify_r1_bytes(pub_key_bytes, &r_bytes, &s_bytes, &msg_hash_bytes, None);
417+
self.is_valid
418+
.assign(region, offset, Value::known(F::from(is_sig_valid)))?;
419419
// self.recovered_addr_keccak_rlc.assign(
420420
// region,
421421
// offset,

0 commit comments

Comments
 (0)