Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support invalid signatures #1

Open
wants to merge 13 commits into
base: xiaodino/invalid-tx
Choose a base branch
from

Conversation

xiaodino
Copy link
Owner

No description provided.

Comment on lines 662 to 664
if tx.map(|x| x.invalid_signature) == Some(true) {
continue;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good, but of course this signature verification skip will have to be replaced with an actual signature check (see taikoxyz#70). Then when the circuit has checked that the signature is invalid, the tx lookup table should mark it as invalid and then the transaction execution needs to be skipped in the EVM circuit.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

* Update halo2wrong version

* Update

* Use xiaodino/halo2wrong branch

* Add offsets in ecdsa chip

* Capture errors

* Update
ecc = { git = "https://github.com/privacy-scaling-explorations/halo2wrong", tag = "v2022_10_22" }
maingate = { git = "https://github.com/privacy-scaling-explorations/halo2wrong", tag = "v2022_10_22" }
integer = { git = "https://github.com/privacy-scaling-explorations/halo2wrong", tag = "v2022_10_22" }
ecdsa = { git = "https://github.com/xiaodino/halo2wrong", rev = "dbfbcd7bc4902957f8865ca319b303e7dc51066a" }
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use xiaodino/halo2wrong#2 Return VerifyFailure::ConstraintNotSatisfied with offset

@@ -113,6 +113,7 @@ impl<'a, M: MultiMillerLoop> Circuit<M::Scalar> for RootCircuit<'a, M> {
config.aggregate::<M>(&mut layouter, &self.svk, [self.snark])?;

// Constrain equality to instance values
/*
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not related to the PR, but this part returns a compiler error.

zkevm-circuits/src/tx_circuit.rs Outdated Show resolved Hide resolved
zkevm-circuits/src/tx_circuit.rs Outdated Show resolved Hide resolved
Comment on lines 662 to 664
if tx.map(|x| x.invalid_signature) == Some(true) {
continue;
}
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

println!("VerifyFailure::ConstraintNotSatisfied at offset {:?}. Constraint {:?}", offset, constraint);
if let Some(ref c) = constraint {
if soft_check_constraints.contains(c) {
tx.invalid_signature = true;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid this is check is not good enough to ensure the prover cannot lie about the signature being invalid. A circuit can fail for many reasons, and for this to work we would have to verify that a proof for a circuit would be invalid at some specific offset which we cannot do in a practical scenario in a secure way. The only way we can be sure that a signature is invalid is by having a valid circuit that shows that the signature is invalid. So we really need to modify the constraints to be able to do so. For example this is currently done in the ECDSA circuit constraints:

// 1. check 0 < r, s
scalar_chip.assert_not_zero(ctx, &sig.r)?;
scalar_chip.assert_not_zero(ctx, &sig.s)?;

This will only pass for valid signatures, so we cannot have this hard check anymore. To be able to support invalid signatures we have to modify the constraints so the constraints can actually be valid, so we have to modify these hard checks into soft checks by doing something like this:

// 1. check 0 < r, s, if r == 0 or s == 0 the signature is marked as invalid
let is_r_invalid = scalar_chip.is_not_zero(ctx, &sig.r)?;
let is_s_invalid = scalar_chip.is_not_zero(ctx, &sig.s)?;

// Something like this, but with constraints
let is_invalid = is_r_invalid || is_s_invalid;

It's very important all these things are checked using constraints in a valid circuit, and not in some other way because the prover can manipulate everything else not directly enforced in a valid circuit.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated xiaodino/halo2wrong#2 to address what you said. Please take a look.

@xiaodino xiaodino requested a review from Brechtpd April 24, 2023 16:09
Comment on lines 266 to 269
// TODO: need to update this constrain_equal when it's invalid signature
TxFieldTag::CallerAddress => region.constrain_equal(
assigned_cell.cell(),
assigned_sig_verif.address.cell(),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the signature is invalid, can we set the address to 0x0? This will match ecrecover behavior.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

zkevm-circuits/src/tx_circuit/sign_verify.rs Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants