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: add assertions for ACVM FunctionInput bit_size #5864

Merged
merged 31 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
4c7cf89
feat: wip ensuring values and function types match ACVM FunctionInput…
michaeljklein Aug 29, 2024
fba8b77
Merge branch 'master' into michaeljklein/acvm-check-bitsize
michaeljklein Sep 3, 2024
575c2f6
wip debugging regression_4080, add error for InvalidInputBitSize, thr…
michaeljklein Sep 4, 2024
0021a68
ensure that 'should_fail_with' in noir tests matches against the erro…
michaeljklein Sep 4, 2024
252600f
Merge branch 'master' into michaeljklein/acvm-check-bitsize
michaeljklein Sep 4, 2024
d5ebc49
cargo clippy/fmt
michaeljklein Sep 4, 2024
c38bdf4
Merge branch 'master' into michaeljklein/acvm-check-bitsize
michaeljklein Sep 4, 2024
07f3e69
nargo fmt
michaeljklein Sep 4, 2024
adfe490
patch acvm_js test to use inputs < 2^128 since the FunctionInputs use…
michaeljklein Sep 4, 2024
6606cf0
another attempt to get the bit size within the expected range
michaeljklein Sep 4, 2024
30c7a70
Merge branch 'master' into michaeljklein/acvm-check-bitsize
michaeljklein Sep 4, 2024
dd645b0
update expected bit size for multi-scalar-mul TS tests to maximum
michaeljklein Sep 5, 2024
390c0fa
Merge branch 'master' into michaeljklein/acvm-check-bitsize
michaeljklein Sep 5, 2024
2c18940
cargo fmt / yarn lint
michaeljklein Sep 5, 2024
d6ba7c3
using only the value + AcirField for InvalidInputBitSize
michaeljklein Sep 5, 2024
3ae49c4
propagate RuntimeError <F> parameter
michaeljklein Sep 5, 2024
9dea841
responding to review comments
michaeljklein Sep 5, 2024
7a13c56
Merge branch 'master' into michaeljklein/acvm-check-bitsize
michaeljklein Sep 6, 2024
59a0e13
refactoring matches and updating test for overflow
michaeljklein Sep 6, 2024
c046b73
Merge branch 'master' into michaeljklein/acvm-check-bitsize
michaeljklein Sep 9, 2024
92f936a
removed <F:AcirField> parameter from invalid bit size error, disable …
michaeljklein Sep 9, 2024
7285ef3
Merge branch 'master' into michaeljklein/acvm-check-bitsize
michaeljklein Sep 9, 2024
821b2d4
add 'bitsize' to cspell.json, replace usage of InvalidInputBitSize wi…
michaeljklein Sep 9, 2024
52eabc5
split UnsupportedIntegerSize into self and InvalidBlackBoxInputBitSize
michaeljklein Sep 10, 2024
d9c1c7f
Merge branch 'master' into michaeljklein/acvm-check-bitsize
michaeljklein Sep 10, 2024
010df44
chore: remove unnecessary trait constraints
TomAFrench Sep 11, 2024
b9d52c7
.
TomAFrench Sep 11, 2024
404c838
.
TomAFrench Sep 11, 2024
e92a509
Update acvm-repo/acvm/src/pwg/mod.rs
TomAFrench Sep 11, 2024
136b48c
chore: remove extra `From` impls
TomAFrench Sep 11, 2024
876d543
.
TomAFrench Sep 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,20 @@ impl<F> FunctionInput<F> {
}

#[derive(Clone, PartialEq, Eq, Debug, Error)]
#[error("FunctionInput value has too many bits: value: {value}, {value_num_bits} >= {num_bits}")]
pub struct InvalidInputBitSize {
pub value: String,
pub value_num_bits: u32,
pub num_bits: u32,
#[error("FunctionInput value has too many bits: value: {value}, {} >= {max_bits}", value.num_bits())]
pub struct InvalidInputBitSize<F: AcirField> {
pub value: F,
pub max_bits: u32,
}

impl<F: AcirField> FunctionInput<F> {
pub fn constant(value: F, num_bits: u32) -> Result<FunctionInput<F>, InvalidInputBitSize> {
if value.num_bits() <= num_bits {
Ok(FunctionInput { input: ConstantOrWitnessEnum::Constant(value), num_bits })
pub fn constant(value: F, max_bits: u32) -> Result<FunctionInput<F>, InvalidInputBitSize<F>> {
if value.num_bits() <= max_bits {
Ok(FunctionInput { input: ConstantOrWitnessEnum::Constant(value), num_bits: max_bits })
} else {
Err(InvalidInputBitSize {
value: format!("{}", value),
value_num_bits: value.num_bits(),
num_bits,
value,
max_bits,
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion acvm-repo/acvm/src/pwg/blackbox/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl AcvmBigIntSolver {
Ok(())
}

pub(crate) fn bigint_op<F>(
pub(crate) fn bigint_op<F: AcirField>(
&mut self,
lhs: u32,
rhs: u32,
Expand Down
25 changes: 12 additions & 13 deletions acvm-repo/acvm/src/pwg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
pub use brillig::ForeignCallWaitInfo;

#[derive(Debug, Clone, PartialEq)]
pub enum ACVMStatus<F> {
pub enum ACVMStatus<F: AcirField> {
/// All opcodes have been solved.
Solved,

Expand All @@ -58,13 +58,13 @@
RequiresForeignCall(ForeignCallWaitInfo<F>),

/// The ACVM has encountered a request for an ACIR [call][acir::circuit::Opcode]
/// to execute a separate ACVM instance. The result of the ACIR call must be passd back to the ACVM.

Check warning on line 61 in acvm-repo/acvm/src/pwg/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (passd)
///
/// Once this is done, the ACVM can be restarted to solve the remaining opcodes.
RequiresAcirCall(AcirCallWaitInfo<F>),
}

impl<F> std::fmt::Display for ACVMStatus<F> {
impl<F: AcirField> std::fmt::Display for ACVMStatus<F> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ACVMStatus::Solved => write!(f, "Solved"),
Expand All @@ -76,7 +76,7 @@
}
}

pub enum StepResult<'a, F, B: BlackBoxFunctionSolver<F>> {
pub enum StepResult<'a, F: AcirField, B: BlackBoxFunctionSolver<F>> {
Status(ACVMStatus<F>),
IntoBrillig(BrilligSolver<'a, F, B>),
}
Expand Down Expand Up @@ -120,7 +120,7 @@
}

#[derive(Clone, PartialEq, Eq, Debug, Error)]
pub enum OpcodeResolutionError<F> {
pub enum OpcodeResolutionError<F: AcirField> {
#[error("Cannot solve opcode: {0}")]
OpcodeNotSolvable(#[from] OpcodeNotSolvable<F>),
#[error("Cannot satisfy constraint")]
Expand All @@ -133,7 +133,7 @@
#[error("Cannot solve opcode: {invalid_input_bit_size}")]
InvalidInputBitSize {
opcode_location: ErrorLocation,
invalid_input_bit_size: InvalidInputBitSize,
invalid_input_bit_size: InvalidInputBitSize<F>,
},
#[error("Failed to solve blackbox function: {0}, reason: {1}")]
BlackBoxFunctionFailed(BlackBoxFunc, String),
Expand All @@ -149,7 +149,7 @@
AcirCallOutputsMismatch { opcode_location: ErrorLocation, results_size: u32, outputs_size: u32 },
}

impl<F> From<BlackBoxResolutionError> for OpcodeResolutionError<F> {
impl<F: AcirField> From<BlackBoxResolutionError> for OpcodeResolutionError<F> {
fn from(value: BlackBoxResolutionError) -> Self {
match value {
BlackBoxResolutionError::Failed(func, reason) => {
Expand All @@ -159,16 +159,16 @@
}
}

impl<F> From<InvalidInputBitSize> for OpcodeResolutionError<F> {
fn from(invalid_input_bit_size: InvalidInputBitSize) -> Self {
impl<F: AcirField> From<InvalidInputBitSize<F>> for OpcodeResolutionError<F> {
fn from(invalid_input_bit_size: InvalidInputBitSize<F>) -> Self {
Self::InvalidInputBitSize {
opcode_location: ErrorLocation::Unresolved,
invalid_input_bit_size,
}
}
}

pub struct ACVM<'a, F, B: BlackBoxFunctionSolver<F>> {
pub struct ACVM<'a, F: AcirField, B: BlackBoxFunctionSolver<F>> {
status: ACVMStatus<F>,

backend: &'a B,
Expand Down Expand Up @@ -646,7 +646,7 @@
// Returns the concrete value for a particular witness
// If the witness has no assignment, then
// an error is returned
pub fn witness_to_value<F>(
pub fn witness_to_value<F: AcirField>(
initial_witness: &WitnessMap<F>,
witness: Witness,
) -> Result<&F, OpcodeResolutionError<F>> {
Expand All @@ -670,9 +670,8 @@
opcode_location: ErrorLocation::Unresolved,

invalid_input_bit_size: InvalidInputBitSize {
value: format!("{}", initial_value),
value_num_bits: initial_value.num_bits(),
num_bits: input.num_bits(),
value: initial_value,
max_bits: input.num_bits(),
},
})
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#![warn(clippy::semicolon_if_nothing_returned)]

use abi_gen::{abi_type_from_hir_type, value_from_hir_expression};
use acvm::acir::circuit::ExpressionWidth;
use acvm::{acir::circuit::ExpressionWidth, FieldElement};
use clap::Args;
use fm::{FileId, FileManager};
use iter_extended::vecmap;
Expand Down Expand Up @@ -146,7 +146,7 @@ pub fn parse_expression_width(input: &str) -> Result<ExpressionWidth, std::io::E
#[derive(Debug)]
pub enum CompileError {
MonomorphizationError(MonomorphizationError),
RuntimeError(RuntimeError),
RuntimeError(RuntimeError<FieldElement>),
}

impl From<MonomorphizationError> for CompileError {
Expand All @@ -155,8 +155,8 @@ impl From<MonomorphizationError> for CompileError {
}
}

impl From<RuntimeError> for CompileError {
fn from(error: RuntimeError) -> Self {
impl From<RuntimeError<FieldElement>> for CompileError {
fn from(error: RuntimeError<FieldElement>) -> Self {
Self::RuntimeError(error)
}
}
Expand Down
14 changes: 7 additions & 7 deletions compiler/noirc_evaluator/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! An Error of the former is a user Error
//!
//! An Error of the latter is an error in the implementation of the compiler
use acvm::{acir::InvalidInputBitSize, FieldElement};
use acvm::{acir::InvalidInputBitSize, AcirField, FieldElement};
use iter_extended::vecmap;
use noirc_errors::{CustomDiagnostic as Diagnostic, FileDiagnostic};
use thiserror::Error;
Expand All @@ -16,7 +16,7 @@ use crate::ssa::ir::{dfg::CallStack, types::NumericType};
use serde::{Deserialize, Serialize};

#[derive(Debug, PartialEq, Eq, Clone, Error)]
pub enum RuntimeError {
pub enum RuntimeError<F: AcirField> {
#[error(transparent)]
InternalError(#[from] InternalError),
#[error("Range constraint of {num_bits} bits is too large for the Field size")]
Expand Down Expand Up @@ -55,7 +55,7 @@ pub enum RuntimeError {
#[error("Could not resolve some references to the array. All references must be resolved at compile time")]
UnknownReference { call_stack: CallStack },
#[error("{invalid_input_bit_size}")]
InvalidInputBitSize { invalid_input_bit_size: InvalidInputBitSize, call_stack: CallStack },
InvalidInputBitSize { invalid_input_bit_size: InvalidInputBitSize<F>, call_stack: CallStack },
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -136,7 +136,7 @@ pub enum InternalError {
Unexpected { expected: String, found: String, call_stack: CallStack },
}

impl RuntimeError {
impl<F: AcirField> RuntimeError<F> {
fn call_stack(&self) -> &CallStack {
match self {
RuntimeError::InternalError(
Expand Down Expand Up @@ -168,16 +168,16 @@ impl RuntimeError {
}
}

impl From<RuntimeError> for FileDiagnostic {
fn from(error: RuntimeError) -> FileDiagnostic {
impl<F: AcirField> From<RuntimeError<F>> for FileDiagnostic {
fn from(error: RuntimeError<F>) -> FileDiagnostic {
let call_stack = vecmap(error.call_stack(), |location| *location);
let file_id = call_stack.last().map(|location| location.file).unwrap_or_default();
let diagnostic = error.into_diagnostic();
diagnostic.in_file(file_id).with_call_stack(call_stack)
}
}

impl RuntimeError {
impl<F: AcirField> RuntimeError<F> {
fn into_diagnostic(self) -> Diagnostic {
match self {
RuntimeError::InternalError(cause) => {
Expand Down
10 changes: 5 additions & 5 deletions compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub(crate) struct ArtifactsAndWarnings(Artifacts, Vec<SsaReport>);
pub(crate) fn optimize_into_acir(
program: Program,
options: &SsaEvaluatorOptions,
) -> Result<ArtifactsAndWarnings, RuntimeError> {
) -> Result<ArtifactsAndWarnings, RuntimeError<FieldElement>> {
let ssa_gen_span = span!(Level::TRACE, "ssa_generation");
let ssa_gen_span_guard = ssa_gen_span.enter();

Expand Down Expand Up @@ -207,7 +207,7 @@ impl SsaProgramArtifact {
pub fn create_program(
program: Program,
options: &SsaEvaluatorOptions,
) -> Result<SsaProgramArtifact, RuntimeError> {
) -> Result<SsaProgramArtifact, RuntimeError<FieldElement>> {
let debug_variables = program.debug_variables.clone();
let debug_types = program.debug_types.clone();
let debug_functions = program.debug_functions.clone();
Expand Down Expand Up @@ -385,7 +385,7 @@ impl SsaBuilder {
force_brillig_runtime: bool,
print_codegen_timings: bool,
emit_ssa: &Option<PathBuf>,
) -> Result<SsaBuilder, RuntimeError> {
) -> Result<SsaBuilder, RuntimeError<FieldElement>> {
let ssa = ssa_gen::generate_ssa(program, force_brillig_runtime)?;
if let Some(emit_ssa) = emit_ssa {
let mut emit_ssa_dir = emit_ssa.clone();
Expand All @@ -412,9 +412,9 @@ impl SsaBuilder {
/// The same as `run_pass` but for passes that may fail
fn try_run_pass(
mut self,
pass: fn(Ssa) -> Result<Ssa, RuntimeError>,
pass: fn(Ssa) -> Result<Ssa, RuntimeError<FieldElement>>,
msg: &str,
) -> Result<Self, RuntimeError> {
) -> Result<Self, RuntimeError<FieldElement>> {
self.ssa = time(msg, self.print_codegen_timings, || pass(self.ssa))?;
Ok(self.print(msg))
}
Expand Down
Loading
Loading