Skip to content

Commit

Permalink
Implement poseidon2_permutation in interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
jfecher committed Jul 23, 2024
1 parent c12bd39 commit 7378330
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions compiler/noirc_frontend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ license.workspace = true

[dependencies]
acvm.workspace = true
bn254_blackbox_solver.workspace = true
noirc_arena.workspace = true
noirc_errors.workspace = true
noirc_printable_type.workspace = true
Expand Down
19 changes: 11 additions & 8 deletions compiler/noirc_frontend/src/hir/comptime/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
token::Tokens,
Type,
};
use acvm::{acir::AcirField, FieldElement};
use acvm::{acir::AcirField, BlackBoxResolutionError, FieldElement};
use fm::FileId;
use iter_extended::vecmap;
use noirc_errors::{CustomDiagnostic, Location};
Expand Down Expand Up @@ -53,13 +53,11 @@ pub enum InterpreterError {
NoImpl { location: Location },
NoMatchingImplFound { error: NoMatchingImplFoundError, file: FileId },
ImplMethodTypeMismatch { expected: Type, actual: Type, location: Location },

Unimplemented { item: String, location: Location },

// Perhaps this should be unreachable! due to type checking also preventing this error?
// Currently it and the Continue variant are the only interpreter errors without a Location field
BreakNotInLoop { location: Location },
ContinueNotInLoop { location: Location },
BlackBoxError(BlackBoxResolutionError, Location),

Unimplemented { item: String, location: Location },

// These cases are not errors, they are just used to prevent us from running more code
// until the loop can be resumed properly. These cases will never be displayed to users.
Expand Down Expand Up @@ -118,9 +116,11 @@ impl InterpreterError {
| InterpreterError::Unimplemented { location, .. }
| InterpreterError::NoImpl { location, .. }
| InterpreterError::ImplMethodTypeMismatch { location, .. }
| InterpreterError::DebugEvaluateComptime { location, .. }
| InterpreterError::BlackBoxError(_, location)
| InterpreterError::BreakNotInLoop { location, .. }
| InterpreterError::DebugEvaluateComptime { location, .. } => *location,
InterpreterError::ContinueNotInLoop { location, .. } => *location,
| InterpreterError::ContinueNotInLoop { location, .. } => *location,

InterpreterError::FailedToParseMacro { error, file, .. } => {
Location::new(error.span(), *file)
}
Expand Down Expand Up @@ -370,6 +370,9 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic {
);
CustomDiagnostic::simple_error(msg, String::new(), location.span)
}
InterpreterError::BlackBoxError(error, location) => {
CustomDiagnostic::simple_error(error.to_string(), String::new(), location.span)
}
InterpreterError::NoMatchingImplFound { error, .. } => error.into(),
InterpreterError::Break => unreachable!("Uncaught InterpreterError::Break"),
InterpreterError::Continue => unreachable!("Uncaught InterpreterError::Continue"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ fn get_slice(
}
}

pub(super) fn get_field(value: Value, location: Location) -> IResult<FieldElement> {
match value {
Value::Field(value) => Ok(value),
value => {
Err(InterpreterError::TypeMismatch { expected: Type::FieldElement, value, location })
}
}
}

pub(super) fn get_u32(value: Value, location: Location) -> IResult<u32> {
match value {
Value::U32(value) => Ok(value),
Expand Down
25 changes: 17 additions & 8 deletions compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@

use acvm::{AcirField, FieldElement, BlackBoxFunctionSolver};
use acvm::BlackBoxFunctionSolver;
use bn254_blackbox_solver::Bn254BlackBoxSolver;
use iter_extended::try_vecmap;
use noirc_errors::Location;

use crate::{
hir::comptime::{errors::IResult, InterpreterError, Value},
hir::comptime::{errors::IResult, interpreter::builtin::get_field, InterpreterError, Value},
macros_api::NodeInterner,
};

use super::builtin::{check_argument_count, get_u32, get_array};
use super::builtin::{check_argument_count, get_array, get_u32};

pub(super) fn call_foreign(
interner: &mut NodeInterner,
Expand All @@ -25,15 +26,23 @@ pub(super) fn call_foreign(
}

// poseidon2_permutation<let N: u32>(_input: [Field; N], _state_length: u32) -> [Field; N]
fn posdon2_permutation(
fn poseidon2_permutation(
interner: &mut NodeInterner,
mut arguments: Vec<(Value, Location)>,
location: Location,
) -> IResult<Value> {
check_argument_count(2, &arguments, location)?;

let state_length = get_u32(arguments.pop().unwrap().0, location);
let input = get_array(interner, arguments.pop().unwrap().0, location);
let state_length = get_u32(arguments.pop().unwrap().0, location)?;
let (input, typ) = get_array(interner, arguments.pop().unwrap().0, location)?;

let input = try_vecmap(input, |integer| get_field(integer, location))?;

// Currently locked to only bn254!
let fields = Bn254BlackBoxSolver
.poseidon2_permutation(&input, state_length)
.map_err(|error| InterpreterError::BlackBoxError(error, location))?;

let result = Bn254BlackBoxSolver.poseidon2_permutation(inputs, state_length);
let array = fields.into_iter().map(Value::Field).collect();
Ok(Value::Array(array, typ))
}

0 comments on commit 7378330

Please sign in to comment.