Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

Commit fba2a58

Browse files
zhenfeizhanglispc
andauthored
fix bug in #872 fix/msg-hash-zero (#880)
* Update ecdsa.rs * fmt and update cells usage --------- Co-authored-by: Zhuo Zhang <mycinbrin@gmail.com>
1 parent c41bb7a commit fba2a58

File tree

2 files changed

+43
-10
lines changed

2 files changed

+43
-10
lines changed

zkevm-circuits/src/sig_circuit/ecdsa.rs

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub(crate) fn ecdsa_verify_no_pubkey_check<F: PrimeField, CF: PrimeField, SF: Pr
3535
where
3636
GA: CurveAffineExt<Base = CF, ScalarExt = SF>,
3737
{
38+
let ecc_chip = EccChip::<F, FpConfig<F, CF>>::construct(base_chip.clone());
3839
let scalar_chip = FpConfig::<F, SF>::construct(
3940
base_chip.range.clone(),
4041
base_chip.limb_bits,
@@ -85,7 +86,6 @@ where
8586
let u3_mul = {
8687
let generator = GA::generator();
8788
let neg_generator = -generator;
88-
let ecc_chip = EccChip::<F, FpConfig<F, CF>>::construct(base_chip.clone());
8989
let generator = ecc_chip.assign_constant_point(ctx, generator);
9090
let neg_generator = ecc_chip.assign_constant_point(ctx, neg_generator);
9191
ecc_chip.select(ctx, &neg_generator, &generator, &u1_is_one)
@@ -99,21 +99,50 @@ where
9999
// check
100100
// - (u1 + u3) * G
101101
// - u2 * pubkey + u3 * G
102-
// are not negatives and not equal
102+
// are not equal
103103
//
104104
// TODO: Technically they could be equal for a valid signature, but this happens with
105105
// vanishing probability for an ECDSA signature constructed in a standard way
106106
// coordinates of u1_mul and u2_mul are in proper bigint form, and lie in but are not
107107
// constrained to [0, n) we therefore need hard inequality here
108-
let u1_u2_x_eq = base_chip.is_equal(ctx, &u1u3_mul.x, &u2_pk_u3_g.x);
109-
let u1_u2_not_neg = base_chip.range.gate().not(ctx, Existing(u1_u2_x_eq));
108+
let u1_u2_x_eq = ecc_chip.is_equal(ctx, &u1u3_mul, &u2_pk_u3_g);
109+
let u1_u2_not_eq = base_chip.range.gate().not(ctx, Existing(u1_u2_x_eq));
110+
111+
// check u1*G and u2*pubkey are not negate of each other
112+
// that means the sum of
113+
// - (u1 + u3) * G
114+
// - u2 * pubkey + u3 * G
115+
// should not equal to 2u3 * G
116+
let u1_u2_not_neg = {
117+
// again we get 2u3*G from constant to avoid scalar_multiply
118+
let two_generator = GA::generator();
119+
let neg_two_generator = -two_generator;
120+
let two_generator = ecc_chip.assign_constant_point(ctx, two_generator);
121+
let neg_two_generator = ecc_chip.assign_constant_point(ctx, neg_two_generator);
122+
let two_u3_g = ecc_chip.select(ctx, &neg_two_generator, &two_generator, &u1_is_one);
123+
124+
base_chip.enforce_less_than_p(ctx, u1u3_mul.x());
125+
base_chip.enforce_less_than_p(ctx, u2_pk_u3_g.x());
126+
// safe: we have already checked (u1 + u3) * G != u2 * pubkey + u3 * G
127+
let sum = ec_add_unequal(base_chip, ctx, &u1u3_mul, &u2_pk_u3_g, false);
128+
129+
let is_equal = ecc_chip.is_equal(ctx, &sum, &two_u3_g);
130+
base_chip.range.gate().not(ctx, Existing(is_equal))
131+
};
110132

111133
// compute (x1, y1) = u1 * G + u2 * pubkey and check (r mod n) == x1 as integers
112134
// which is basically u1u3_mul + u2_mul - u3_mul
113135
// WARNING: For optimization reasons, does not reduce x1 mod n, which is
114136
// invalid unless p is very close to n in size.
115-
base_chip.enforce_less_than_p(ctx, u1u3_mul.x());
137+
//
138+
// WARNING: this may be trigger errors if
139+
// u1u3_mul == u2_mul
140+
// if r is sampled truly from random then this will not happen
141+
// to completely ensure the correctness we may need to sample u3 from random, but it is quite
142+
// costly.
116143
let sum = ec_add_unequal(base_chip, ctx, &u1u3_mul, &u2_mul, false);
144+
// safe: we have already checked u1G + u2 pk != 0
145+
// so u1G + u3G + u2pk != u3G
117146
let sum = ec_sub_unequal(base_chip, ctx, &sum, &u3_mul, false);
118147
let equal_check = base_chip.is_equal(ctx, &sum.x, r);
119148

@@ -151,12 +180,16 @@ where
151180
let res4 = base_chip
152181
.range
153182
.gate()
154-
.and(ctx, Existing(res3), Existing(u1_u2_not_neg));
183+
.and(ctx, Existing(res3), Existing(u1_u2_not_eq));
155184
let res5 = base_chip
156185
.range
157186
.gate()
158-
.and(ctx, Existing(res4), Existing(equal_check));
159-
(res5, sum.y)
187+
.and(ctx, Existing(res4), Existing(u1_u2_not_neg));
188+
let res6 = base_chip
189+
.range
190+
.gate()
191+
.and(ctx, Existing(res5), Existing(equal_check));
192+
(res6, sum.y)
160193
}
161194

162195
fn scalar_field_element_is_one<F: PrimeField, SF: PrimeField>(

zkevm-circuits/src/sig_circuit/utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use halo2_proofs::{
1313
// Hard coded parameters.
1414
// FIXME: allow for a configurable param.
1515
pub(super) const MAX_NUM_SIG: usize = 128;
16-
// Each ecdsa signature requires 460456 cells
17-
pub(super) const CELLS_PER_SIG: usize = 460456;
16+
// Each ecdsa signature requires 462274 cells
17+
pub(super) const CELLS_PER_SIG: usize = 462274;
1818
// Each ecdsa signature requires 62994 lookup cells
1919
pub(super) const LOOKUP_CELLS_PER_SIG: usize = 62994;
2020
// Total number of rows allocated for ecdsa chip

0 commit comments

Comments
 (0)