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

feat: --pedantic-solving flag #6716

Open
wants to merge 25 commits into
base: master
Choose a base branch
from

Conversation

michaeljklein
Copy link
Contributor

Description

Problem*

Resolves #6275

Summary*

Adds a compile-time flag --pedantic-solving to run extra sanity-check assertions at the opcode level in ACVM.

Additional Context

  1. This is expected to be useful for fuzzing
  2. This will need a follow-up for similar types of assertions

Documentation*

Check one:

  • No documentation needed.
  • Documentation included in this PR.
  • [For Experimental Features] Documentation to be submitted in a separate PR.

PR Checklist*

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt on default settings.

…dd method to check for valid bigint modulus, add error for predicate > 1, add cli option for pedantic solving
…testing or constant-folding, add tests for pedantic_solving, test to ensure allowed bingint moduli are prime
Comment on lines -56 to +60
let skip_bitsize_checks = true;
let skip_bitsize_checks = !pedantic_solving;
Copy link
Contributor

Choose a reason for hiding this comment

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

I see we have stand-alone functions here, so the pedantic_solving can only be a function parameter. Would it make sense to create a LogicSolver similar to the BigintSolver and make it a config parameter, so as not to complicate the API methods?

Copy link
Contributor

@aakoshh aakoshh Dec 6, 2024

Choose a reason for hiding this comment

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

Or maybe introduce some kind os SolverContext that could contain the initial_witness and the pedantic_solving; most functions I look at take the &mut WitnessMap as parameters, and by wrapping these up we could have a bunch of ambient studd we always pass around.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I looked into using WitnessMap, but 1) I don't want to modify a native type, and 2) WitnessMap is used more often than pedantic_solving. I already moved pedantic_solving to the blackbox/bigint solver structs, so will look into the remaining cases next.

Copy link
Contributor

@aakoshh aakoshh Dec 6, 2024

Choose a reason for hiding this comment

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

To be clear I did not want to suggest modifying WitnessMap but to create a struct SolverContext { initial_witness: WistnessMap, pedantic_solver: bool } which could be used by the numerous functions that take both of these. If something only takes one we could always pass e.g. self.ctx.initial_witness. Or it might just take ctx anyway, as you said you plan on expanding the number of checks, maybe other parameters will be added to the context later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd prefer to keep it as-is since there's only ~5 cases left where pedantic_solving is passed along with a WitnessMap and I'd have to modify a bunch of places where the WitnessMap is created/updated.

Comment on lines 618 to 623
if is_predicate_false(
&self.witness_map,
predicate,
self.pedantic_solving,
&opcode_location,
)? {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe is_predicate_false could be added to that SolverContext I suggested, resulting in a ctx.is_predicate_false(predicate, &opcode_location) which is a bit less busy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

General response above

Copy link
Contributor

@aakoshh aakoshh left a comment

Choose a reason for hiding this comment

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

Well if it ain't pedantic_solving being true to its name, this is a pervasive setting!

I added a lot of comments about potentially trying to add it to the solvers, or a context that is passed to the solvers, but even then there is a lot of threading through. It sounds more of an ambient setting like the logging level, not something that varies per function call, yet it's present in each bigint method, logical function and such like.

For something that is an optional setting, I do wonder if a solution involving an env var, perhaps some global variable would be a lighter touch. Not sure if there would be a good candidate for a module that could hold it though.

Copy link
Contributor

github-actions bot commented Dec 6, 2024

Peak Memory Sample

Program Peak Memory %
keccak256 79.14M 0%
workspace 121.98M -1%
regression_4709 295.99M 0%
ram_blowup_regression 2.44G 0%
private-kernel-tail 210.43M 0%
private-kernel-reset 862.22M 0%
private-kernel-inner 307.94M 0%
parity-root 175.78M 0%

Copy link
Member

@TomAFrench TomAFrench left a comment

Choose a reason for hiding this comment

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

Looks sensible but we seem to be being pedantic all the time for memory ops.

acvm-repo/acvm/src/pwg/mod.rs Outdated Show resolved Hide resolved
acvm-repo/acvm/src/pwg/memory_op.rs Outdated Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

Do we not have pedantic checks for the EC operations? I'd expect that we'd want to check that the points are all on the curve (or are marked as points at infinity).

Copy link
Member

Choose a reason for hiding this comment

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

Actually, we want to exclude any points at infinity. The set of assumptions we make are documented in the stdlib.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, we're currently checking that all points are on curves for multi_scalar_mul and embedded_curve_add here

I've added checks for points at infinity: it looks like we support them for multi_scalar_mul?

Copy link
Contributor

github-actions bot commented Dec 9, 2024

Compilation Sample

Program Compilation Time %
sha256_regression 0m1.536s -10%
regression_4709 0m0.760s -6%
ram_blowup_regression 0m17.073s -1%
private-kernel-tail 0m1.136s -26%
private-kernel-reset 0m8.779s 0%
private-kernel-inner 0m2.410s -12%
parity-root 0m0.932s -1%
noir-contracts 2m51.609s 1%

…solving, check grumpkin_integer and whether points are infinite for ec add and multi_scalar_mul
@michaeljklein
Copy link
Contributor Author

michaeljklein commented Dec 11, 2024

NOTE: the following test appears to be was failing due to a bug that is fixed in #6771:

tests::compile_success_empty::test_embedded_curve_add_simplification::forcebrillig_false_inliner_0_expects

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.

Compilation flag to add runtime checks for opcode assumptions
3 participants