From 7fce5adcbbc535eea4d4ffe60028b3f07a5dc2d3 Mon Sep 17 00:00:00 2001 From: Tom French Date: Thu, 14 Nov 2024 16:55:35 +0000 Subject: [PATCH 1/5] chore: replace `to_radix` directive with brillig --- avm-transpiler/Cargo.lock | 1 - noir/noir-repo/Cargo.lock | 1 - .../acvm-repo/acir/src/circuit/opcodes.rs | 15 +-- noir/noir-repo/acvm-repo/acvm/Cargo.toml | 1 - .../optimizers/constant_backpropagation.rs | 28 ---- .../compiler/optimizers/merge_expressions.rs | 4 +- .../acvm-repo/acvm/src/compiler/simulator.rs | 15 +-- .../acvm/src/compiler/transformers/mod.rs | 15 +-- .../acvm-repo/acvm/src/pwg/directives/mod.rs | 49 ------- noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs | 8 +- .../brillig/brillig_gen/brillig_directive.rs | 125 +++++++++++++++++- .../ssa/acir_gen/acir_ir/generated_acir.rs | 62 +++++++-- .../tooling/fuzzer/src/dictionary/mod.rs | 6 +- .../tooling/profiler/src/opcode_formatter.rs | 15 +-- 14 files changed, 196 insertions(+), 149 deletions(-) delete mode 100644 noir/noir-repo/acvm-repo/acvm/src/pwg/directives/mod.rs diff --git a/avm-transpiler/Cargo.lock b/avm-transpiler/Cargo.lock index 47110353d7a..11bed94262c 100644 --- a/avm-transpiler/Cargo.lock +++ b/avm-transpiler/Cargo.lock @@ -36,7 +36,6 @@ dependencies = [ "acvm_blackbox_solver", "brillig_vm", "indexmap 1.9.3", - "num-bigint", "serde", "thiserror", "tracing", diff --git a/noir/noir-repo/Cargo.lock b/noir/noir-repo/Cargo.lock index 35ff97f55e3..aed29c229c5 100644 --- a/noir/noir-repo/Cargo.lock +++ b/noir/noir-repo/Cargo.lock @@ -49,7 +49,6 @@ dependencies = [ "bn254_blackbox_solver", "brillig_vm", "indexmap 1.9.3", - "num-bigint", "proptest", "serde", "thiserror", diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs index 848d7bda84b..c32aa6edd27 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs @@ -60,7 +60,7 @@ pub enum Opcode { /// specialized constraints. /// /// Often used for exposing more efficient implementations of - /// SNARK-unfriendly computations. + /// SNARK-unfriendly computations. /// /// All black box functions take as input a tuple `(witness, num_bits)`, /// where `num_bits` is a constant representing the bit size of the input @@ -158,17 +158,8 @@ impl std::fmt::Display for Opcode { } Opcode::BlackBoxFuncCall(g) => write!(f, "{g}"), - Opcode::Directive(Directive::ToLeRadix { a, b, radix: _ }) => { - write!(f, "DIR::TORADIX ")?; - write!( - f, - // TODO (Note): this assumes that the decomposed bits have contiguous witness indices - // This should be the case, however, we can also have a function which checks this - "(_{}, [_{}..._{}] )", - a, - b.first().unwrap().witness_index(), - b.last().unwrap().witness_index(), - ) + Opcode::Directive(_) => { + unreachable!("directives no longer exist") } Opcode::MemoryOp { block_id, op, predicate } => { write!(f, "MEM ")?; diff --git a/noir/noir-repo/acvm-repo/acvm/Cargo.toml b/noir/noir-repo/acvm-repo/acvm/Cargo.toml index 2b143ebe475..54bb8962966 100644 --- a/noir/noir-repo/acvm-repo/acvm/Cargo.toml +++ b/noir/noir-repo/acvm-repo/acvm/Cargo.toml @@ -14,7 +14,6 @@ repository.workspace = true workspace = true [dependencies] -num-bigint.workspace = true thiserror.workspace = true tracing.workspace = true serde.workspace = true diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/constant_backpropagation.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/constant_backpropagation.rs index 991b91fce21..c2ee9e93a87 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/constant_backpropagation.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/constant_backpropagation.rs @@ -212,34 +212,6 @@ impl ConstantBackpropagationOptimizer { } } - Opcode::Directive(Directive::ToLeRadix { a, b, radix }) => { - if b.iter().all(|output| known_witnesses.contains_key(output)) { - continue; - } else if b.iter().any(|witness| required_witnesses.contains(witness)) { - // If one of the brillig opcode's outputs is a required witness then we can't remove the opcode. In this case we can't replace - // all of the uses of this witness with the calculated constant so we'll be attempting to use an uninitialized witness. - // - // We then do not attempt execution of this opcode and just simplify the inputs. - Opcode::Directive(Directive::ToLeRadix { - a: remap_expression(&known_witnesses, a), - b, - radix, - }) - } else { - let directive = Directive::ToLeRadix { - a: remap_expression(&known_witnesses, a), - b, - radix, - }; - let result = solve_directives(&mut known_witnesses, &directive); - - match result { - Ok(()) => continue, - Err(_) => Opcode::Directive(directive), - } - } - } - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { input }) => { if solve_range_opcode(&known_witnesses, &input).is_ok() { continue; diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs index a5258a494a2..ff91cc80735 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs @@ -3,7 +3,6 @@ use std::collections::{BTreeMap, BTreeSet, HashMap}; use acir::{ circuit::{ brillig::{BrilligInputs, BrilligOutputs}, - directives::Directive, opcodes::BlockId, Circuit, Opcode, }, @@ -157,7 +156,6 @@ impl MergeExpressionsOptimizer { match opcode { Opcode::AssertZero(expr) => CircuitSimulator::expr_wit(expr), Opcode::BlackBoxFuncCall(bb_func) => bb_func.get_input_witnesses(), - Opcode::Directive(Directive::ToLeRadix { a, .. }) => CircuitSimulator::expr_wit(a), Opcode::MemoryOp { block_id: _, op, predicate } => { //index et value, et predicate let mut witnesses = BTreeSet::new(); @@ -193,6 +191,8 @@ impl MergeExpressionsOptimizer { } witnesses } + // Directive opcode is to be removed + Opcode::Directive(_) => unreachable!(), } } diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/simulator.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/simulator.rs index 8f15cf88519..47bc0f72864 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/simulator.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/simulator.rs @@ -1,7 +1,6 @@ use acir::{ circuit::{ brillig::{BrilligInputs, BrilligOutputs}, - directives::Directive, opcodes::{BlockId, FunctionInput}, Circuit, Opcode, }, @@ -84,17 +83,9 @@ impl CircuitSimulator { } true } - Opcode::Directive(directive) => match directive { - Directive::ToLeRadix { a, b, .. } => { - if !self.can_solve_expression(a) { - return false; - } - for w in b { - self.mark_solvable(*w); - } - true - } - }, + Opcode::Directive(_) => { + unreachable!("directives no longer exist") + } Opcode::MemoryOp { block_id, op, predicate } => { if !self.can_solve_expression(&op.index) { return false; diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs index b11d054a57b..ad399138929 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs @@ -1,5 +1,5 @@ use acir::{ - circuit::{brillig::BrilligOutputs, directives::Directive, Circuit, ExpressionWidth, Opcode}, + circuit::{brillig::BrilligOutputs, Circuit, ExpressionWidth, Opcode}, native_types::{Expression, Witness}, AcirField, }; @@ -104,17 +104,6 @@ pub(super) fn transform_internal( new_acir_opcode_positions.push(acir_opcode_positions[index]); transformed_opcodes.push(opcode); } - Opcode::Directive(ref directive) => { - match directive { - Directive::ToLeRadix { b, .. } => { - for witness in b { - transformer.mark_solvable(*witness); - } - } - } - new_acir_opcode_positions.push(acir_opcode_positions[index]); - transformed_opcodes.push(opcode); - } Opcode::MemoryInit { .. } => { // `MemoryInit` does not write values to the `WitnessMap` new_acir_opcode_positions.push(acir_opcode_positions[index]); @@ -156,6 +145,8 @@ pub(super) fn transform_internal( new_acir_opcode_positions.push(acir_opcode_positions[index]); transformed_opcodes.push(opcode); } + // Directive opcode is to be removed + Opcode::Directive(_) => unreachable!(), } } diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/directives/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/directives/mod.rs deleted file mode 100644 index d7bee88c278..00000000000 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/directives/mod.rs +++ /dev/null @@ -1,49 +0,0 @@ -use acir::{circuit::directives::Directive, native_types::WitnessMap, AcirField}; -use num_bigint::BigUint; - -use crate::OpcodeResolutionError; - -use super::{get_value, insert_value, ErrorLocation}; - -/// Attempts to solve the [`Directive`] opcode `directive`. -/// If successful, `initial_witness` will be mutated to contain the new witness assignment. -/// -/// Returns `Ok(OpcodeResolution)` to signal whether the directive was successful solved. -/// -/// Returns `Err(OpcodeResolutionError)` if a circuit constraint is unsatisfied. -pub(crate) fn solve_directives( - initial_witness: &mut WitnessMap, - directive: &Directive, -) -> Result<(), OpcodeResolutionError> { - match directive { - Directive::ToLeRadix { a, b, radix } => { - let value_a = get_value(a, initial_witness)?; - let big_integer = BigUint::from_bytes_be(&value_a.to_be_bytes()); - - // Decompose the integer into its radix digits in little endian form. - let decomposed_integer = big_integer.to_radix_le(*radix); - - if b.len() < decomposed_integer.len() { - return Err(OpcodeResolutionError::UnsatisfiedConstrain { - opcode_location: ErrorLocation::Unresolved, - payload: None, - }); - } - - for (i, witness) in b.iter().enumerate() { - // Fetch the `i'th` digit from the decomposed integer list - // and convert it to a field element. - // If it is not available, which can happen when the decomposed integer - // list is shorter than the witness list, we return 0. - let value = match decomposed_integer.get(i) { - Some(digit) => F::from_be_bytes_reduce(&[*digit]), - None => F::zero(), - }; - - insert_value(witness, value, initial_witness)?; - } - - Ok(()) - } - } -} diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs index e2b9ef1defa..2faf8fccd3a 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs @@ -18,8 +18,7 @@ use acir::{ use acvm_blackbox_solver::BlackBoxResolutionError; use self::{ - arithmetic::ExpressionSolver, blackbox::bigint::AcvmBigIntSolver, directives::solve_directives, - memory_op::MemoryOpSolver, + arithmetic::ExpressionSolver, blackbox::bigint::AcvmBigIntSolver, memory_op::MemoryOpSolver, }; use crate::BlackBoxFunctionSolver; @@ -29,8 +28,6 @@ use thiserror::Error; pub(crate) mod arithmetic; // Brillig bytecode pub(crate) mod brillig; -// Directives -pub(crate) mod directives; // black box functions pub(crate) mod blackbox; mod memory_op; @@ -371,7 +368,6 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { bb_func, &mut self.bigint_solver, ), - Opcode::Directive(directive) => solve_directives(&mut self.witness_map, directive), Opcode::MemoryInit { block_id, init, .. } => { let solver = self.block_solvers.entry(*block_id).or_default(); solver.init(init, &self.witness_map) @@ -388,6 +384,8 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { Ok(Some(input_values)) => return self.wait_for_acir_call(input_values), res => res.map(|_| ()), }, + // Directive opcode is to be removed + Opcode::Directive(_) => unreachable!(), }; self.handle_opcode_resolution(resolution) } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs index d5529c00d6c..8ce41bdacc0 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs @@ -1,6 +1,7 @@ use acvm::acir::{ brillig::{ - BinaryFieldOp, BitSize, HeapVector, IntegerBitSize, MemoryAddress, Opcode as BrilligOpcode, + BinaryFieldOp, BinaryIntOp, BitSize, HeapVector, IntegerBitSize, MemoryAddress, + Opcode as BrilligOpcode, }, AcirField, }; @@ -146,3 +147,125 @@ pub(crate) fn directive_quotient() -> GeneratedBrillig { ..Default::default() } } + +/// Generates brillig bytecode which performs a radix-base decomposition of `a` +/// The brillig inputs are 'a', the numbers of limbs and the radix +pub(crate) fn directive_to_radix() -> GeneratedBrillig { + let memory_adr_int_size = IntegerBitSize::U32; + let memory_adr_size = BitSize::Integer(memory_adr_int_size); + + // (0) is the input field `a` to decompose + // (1) contains the number of limbs (second input) + let limbs_nb = MemoryAddress::direct(1); + // (2) contains the radix (third input) + let radix = MemoryAddress::direct(2); + // (3) and (4) are intermediate registers + // (5,6,7) are constants: 0,1,3 + let zero = MemoryAddress::direct(5); + let one = MemoryAddress::direct(6); + let three = MemoryAddress::direct(7); + // (7) is the iteration bound, it is the same register as three because the latter is only used at the start + let bound = MemoryAddress::direct(7); + // (8) is the register for storing the loop condition + let cond = MemoryAddress::direct(8); + // (9) is the pointer to the result array + let result_pointer = MemoryAddress::direct(9); + // address of the result array + let result_base_adr = 10_usize; + + let result_vector = + HeapVector { pointer: MemoryAddress::direct(result_base_adr), size: limbs_nb }; + + let byte_code = vec![ + // Initialize registers + // Constants + // Zero + BrilligOpcode::Const { destination: zero, bit_size: memory_adr_size, value: F::zero() }, + // One + BrilligOpcode::Const { + destination: one, + bit_size: memory_adr_size, + value: F::from(1_usize), + }, + // Three + BrilligOpcode::Const { + destination: three, + bit_size: memory_adr_size, + value: F::from(3_usize), + }, + // Brillig Inputs + BrilligOpcode::CalldataCopy { + destination_address: MemoryAddress::direct(0), + size_address: three, + offset_address: zero, + }, + // The number of limbs needs to be an integer + BrilligOpcode::Cast { destination: limbs_nb, source: limbs_nb, bit_size: memory_adr_size }, + // Result_pointer starts at the base address + BrilligOpcode::Const { + destination: result_pointer, + bit_size: memory_adr_size, + value: F::from(result_base_adr), + }, + // Loop bound + BrilligOpcode::BinaryIntOp { + destination: bound, + op: BinaryIntOp::Add, + bit_size: memory_adr_int_size, + lhs: result_pointer, + rhs: limbs_nb, + }, + // loop label: (3) = a / radix (integer division) + BrilligOpcode::BinaryFieldOp { + op: BinaryFieldOp::IntegerDiv, + lhs: MemoryAddress::direct(0), + rhs: radix, + destination: MemoryAddress::direct(3), + }, + //(4) = (3)*256 + BrilligOpcode::BinaryFieldOp { + op: BinaryFieldOp::Mul, + lhs: MemoryAddress::direct(3), + rhs: radix, + destination: MemoryAddress::direct(4), + }, + //(4) = a-(3)*256 (remainder) + BrilligOpcode::BinaryFieldOp { + op: BinaryFieldOp::Sub, + lhs: MemoryAddress::direct(0), + rhs: MemoryAddress::direct(4), + destination: MemoryAddress::direct(4), + }, + // Store the remainder in the result array + BrilligOpcode::Store { + destination_pointer: result_pointer, + source: MemoryAddress::direct(4), + }, + // Increment the result pointer + BrilligOpcode::BinaryIntOp { + op: BinaryIntOp::Add, + lhs: result_pointer, + rhs: one, + destination: result_pointer, + bit_size: memory_adr_int_size, + }, + //a := quotient + BrilligOpcode::Mov { + destination: MemoryAddress::direct(0), + source: MemoryAddress::direct(3), + }, + // loop condition + BrilligOpcode::BinaryIntOp { + op: BinaryIntOp::LessThan, + lhs: result_pointer, + rhs: bound, + destination: cond, + bit_size: memory_adr_int_size, + }, + // loop back + BrilligOpcode::JumpIf { condition: cond, location: 7 }, + BrilligOpcode::Stop { return_data: result_vector }, + ]; + + GeneratedBrillig { byte_code, name: "directive_to_radix".to_string(), ..Default::default() } +} diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index 72380dd04eb..6b215839f34 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -16,10 +16,7 @@ use acvm::acir::{ native_types::Witness, BlackBoxFunc, }; -use acvm::{ - acir::AcirField, - acir::{circuit::directives::Directive, native_types::Expression}, -}; +use acvm::{acir::native_types::Expression, acir::AcirField}; use iter_extended::vecmap; use noirc_errors::debug_info::ProcedureDebugId; @@ -95,6 +92,7 @@ pub(crate) type BrilligProcedureRangeMap = BTreeMap brillig_directive::directive_invert(), BrilligStdlibFunc::Quotient => brillig_directive::directive_quotient(), + BrilligStdlibFunc::ToLeBytes => brillig_directive::directive_to_radix(), } } } @@ -380,12 +379,7 @@ impl GeneratedAcir { "ICE: Radix must be a power of 2" ); - let limb_witnesses = vecmap(0..limb_count, |_| self.next_witness_index()); - self.push_opcode(AcirOpcode::Directive(Directive::ToLeRadix { - a: input_expr.clone(), - b: limb_witnesses.clone(), - radix, - })); + let limb_witnesses = self.brillig_to_radix(input_expr, radix, limb_count); let mut composed_limbs = Expression::default(); @@ -406,6 +400,54 @@ impl GeneratedAcir { Ok(limb_witnesses) } + /// Adds brillig opcode for to_radix + /// + /// This code will decompose `expr` in a radix-base + /// and return `Witnesses` which may (or not, because it does not apply constraints) + /// be limbs resulting from the decomposition. + /// + /// Safety: It is the callers responsibility to ensure that the + /// resulting `Witnesses` are properly constrained. + pub(crate) fn brillig_to_radix( + &mut self, + expr: &Expression, + radix: u32, + limb_count: u32, + ) -> Vec { + // Create the witness for the result + let limb_witnesses = vecmap(0..limb_count, |_| self.next_witness_index()); + + // Get the decomposition brillig code + let le_bytes_code = brillig_directive::directive_to_radix(); + // Prepare the inputs/outputs + let limbs_nb = Expression { + mul_terms: Vec::new(), + linear_combinations: Vec::new(), + q_c: F::from(limb_count as u128), + }; + let radix_expr = Expression { + mul_terms: Vec::new(), + linear_combinations: Vec::new(), + q_c: F::from(radix as u128), + }; + let inputs = vec![ + BrilligInputs::Single(expr.clone()), + BrilligInputs::Single(limbs_nb), + BrilligInputs::Single(radix_expr), + ]; + let outputs = vec![BrilligOutputs::Array(limb_witnesses.clone())]; + + self.brillig_call( + None, + &le_bytes_code, + inputs, + outputs, + PLACEHOLDER_BRILLIG_INDEX, + Some(BrilligStdlibFunc::ToLeBytes), + ); + limb_witnesses + } + /// Adds an inversion brillig opcode. /// /// This code will invert `expr` without applying constraints diff --git a/noir/noir-repo/tooling/fuzzer/src/dictionary/mod.rs b/noir/noir-repo/tooling/fuzzer/src/dictionary/mod.rs index e10da8cc54a..172edfa54c2 100644 --- a/noir/noir-repo/tooling/fuzzer/src/dictionary/mod.rs +++ b/noir/noir-repo/tooling/fuzzer/src/dictionary/mod.rs @@ -9,7 +9,6 @@ use acvm::{ acir::{ circuit::{ brillig::{BrilligBytecode, BrilligInputs}, - directives::Directive, opcodes::{BlackBoxFuncCall, ConstantOrWitnessEnum}, Circuit, Opcode, Program, }, @@ -60,10 +59,7 @@ fn build_dictionary_from_circuit(circuit: &Circuit) -> HashSet< match opcode { Opcode::AssertZero(expr) | Opcode::Call { predicate: Some(expr), .. } - | Opcode::MemoryOp { predicate: Some(expr), .. } - | Opcode::Directive(Directive::ToLeRadix { a: expr, .. }) => { - insert_expr(&mut constants, expr) - } + | Opcode::MemoryOp { predicate: Some(expr), .. } => insert_expr(&mut constants, expr), Opcode::MemoryInit { init, .. } => insert_array_len(&mut constants, init), diff --git a/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs b/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs index 68057b6d86f..aacc2ae438f 100644 --- a/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs +++ b/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs @@ -1,5 +1,5 @@ use acir::brillig::{BinaryFieldOp, BinaryIntOp, BlackBoxOp, Opcode as BrilligOpcode}; -use acir::circuit::{directives::Directive, opcodes::BlackBoxFuncCall, Opcode as AcirOpcode}; +use acir::circuit::{opcodes::BlackBoxFuncCall, Opcode as AcirOpcode}; use acir::AcirField; #[derive(Debug)] @@ -57,12 +57,6 @@ fn format_blackbox_op(call: &BlackBoxOp) -> String { } } -fn format_directive_kind(directive: &Directive) -> String { - match directive { - Directive::ToLeRadix { .. } => "to_le_radix".to_string(), - } -} - fn format_acir_opcode_kind(opcode: &AcirOpcode) -> String { match opcode { AcirOpcode::AssertZero(_) => "arithmetic".to_string(), @@ -71,11 +65,12 @@ fn format_acir_opcode_kind(opcode: &AcirOpcode) -> String { } AcirOpcode::MemoryOp { .. } => "memory::op".to_string(), AcirOpcode::MemoryInit { .. } => "memory::init".to_string(), - AcirOpcode::Directive(directive) => { - format!("directive::{}", format_directive_kind(directive)) - } AcirOpcode::BrilligCall { id, .. } => format!("brillig_call({id})"), AcirOpcode::Call { .. } => "acir_call".to_string(), + + AcirOpcode::Directive(_) => { + unreachable!("directives no longer exist") + } } } From d838e0b3de8349fc56cfbe36d3000ff76b55a642 Mon Sep 17 00:00:00 2001 From: Tom French Date: Thu, 14 Nov 2024 17:48:17 +0000 Subject: [PATCH 2/5] . --- noir/noir-repo/Cargo.lock | 1 + noir/noir-repo/acvm-repo/acvm/Cargo.toml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/noir/noir-repo/Cargo.lock b/noir/noir-repo/Cargo.lock index aed29c229c5..35ff97f55e3 100644 --- a/noir/noir-repo/Cargo.lock +++ b/noir/noir-repo/Cargo.lock @@ -49,6 +49,7 @@ dependencies = [ "bn254_blackbox_solver", "brillig_vm", "indexmap 1.9.3", + "num-bigint", "proptest", "serde", "thiserror", diff --git a/noir/noir-repo/acvm-repo/acvm/Cargo.toml b/noir/noir-repo/acvm-repo/acvm/Cargo.toml index 54bb8962966..722c825dca5 100644 --- a/noir/noir-repo/acvm-repo/acvm/Cargo.toml +++ b/noir/noir-repo/acvm-repo/acvm/Cargo.toml @@ -42,3 +42,5 @@ ark-bn254.workspace = true bn254_blackbox_solver.workspace = true proptest.workspace = true zkhash = { version = "^0.2.0", default-features = false } +num-bigint.workspace = true + From e4246317649f19f96e960c188069b4b862eac280 Mon Sep 17 00:00:00 2001 From: Tom French Date: Thu, 14 Nov 2024 20:06:18 +0000 Subject: [PATCH 3/5] chore: remove directive opcode --- .../dsl/acir_format/serde/acir.hpp | 181 +----------------- noir/noir-repo/acvm-repo/acir/README.md | 14 +- .../noir-repo/acvm-repo/acir/codegen/acir.cpp | 153 +-------------- .../acvm-repo/acir/src/circuit/directives.rs | 11 -- .../acvm-repo/acir/src/circuit/mod.rs | 1 - .../acvm-repo/acir/src/circuit/opcodes.rs | 18 +- noir/noir-repo/acvm-repo/acir/src/lib.rs | 2 - .../acir/tests/test_program_serialization.rs | 60 +++--- .../optimizers/constant_backpropagation.rs | 5 +- .../compiler/optimizers/merge_expressions.rs | 2 - .../acvm-repo/acvm/src/compiler/simulator.rs | 3 - .../acvm/src/compiler/transformers/mod.rs | 2 - noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs | 2 - .../test/shared/complex_foreign_call.ts | 14 +- .../acvm_js/test/shared/foreign_call.ts | 10 +- .../acvm_js/test/shared/memory_op.ts | 8 +- .../acvm_js/test/shared/nested_acir_call.ts | 14 +- noir/noir-repo/acvm-repo/brillig/src/lib.rs | 1 - .../noir-repo/acvm-repo/brillig_vm/src/lib.rs | 1 - 19 files changed, 60 insertions(+), 442 deletions(-) delete mode 100644 noir/noir-repo/acvm-repo/acir/src/circuit/directives.rs diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index d8bfc79dab0..e65e5f00f1e 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -1144,25 +1144,6 @@ struct BrilligOutputs { static BrilligOutputs bincodeDeserialize(std::vector); }; -struct Directive { - - struct ToLeRadix { - Program::Expression a; - std::vector b; - uint32_t radix; - - friend bool operator==(const ToLeRadix&, const ToLeRadix&); - std::vector bincodeSerialize() const; - static ToLeRadix bincodeDeserialize(std::vector); - }; - - std::variant value; - - friend bool operator==(const Directive&, const Directive&); - std::vector bincodeSerialize() const; - static Directive bincodeDeserialize(std::vector); -}; - struct MemOp { Program::Expression operation; Program::Expression index; @@ -1191,14 +1172,6 @@ struct Opcode { static BlackBoxFuncCall bincodeDeserialize(std::vector); }; - struct Directive { - Program::Directive value; - - friend bool operator==(const Directive&, const Directive&); - std::vector bincodeSerialize() const; - static Directive bincodeDeserialize(std::vector); - }; - struct MemoryOp { Program::BlockId block_id; Program::MemOp op; @@ -1241,7 +1214,7 @@ struct Opcode { static Call bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; friend bool operator==(const Opcode&, const Opcode&); std::vector bincodeSerialize() const; @@ -6812,112 +6785,6 @@ Program::ConstantOrWitnessEnum::Witness serde::Deserializable Directive::bincodeSerialize() const -{ - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); -} - -inline Directive Directive::bincodeDeserialize(std::vector input) -{ - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw_or_abort("Some input bytes were not read"); - } - return value; -} - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::Directive& obj, Serializer& serializer) -{ - serializer.increase_container_depth(); - serde::Serializable::serialize(obj.value, serializer); - serializer.decrease_container_depth(); -} - -template <> -template -Program::Directive serde::Deserializable::deserialize(Deserializer& deserializer) -{ - deserializer.increase_container_depth(); - Program::Directive obj; - obj.value = serde::Deserializable::deserialize(deserializer); - deserializer.decrease_container_depth(); - return obj; -} - -namespace Program { - -inline bool operator==(const Directive::ToLeRadix& lhs, const Directive::ToLeRadix& rhs) -{ - if (!(lhs.a == rhs.a)) { - return false; - } - if (!(lhs.b == rhs.b)) { - return false; - } - if (!(lhs.radix == rhs.radix)) { - return false; - } - return true; -} - -inline std::vector Directive::ToLeRadix::bincodeSerialize() const -{ - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); -} - -inline Directive::ToLeRadix Directive::ToLeRadix::bincodeDeserialize(std::vector input) -{ - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw_or_abort("Some input bytes were not read"); - } - return value; -} - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::Directive::ToLeRadix& obj, - Serializer& serializer) -{ - serde::Serializable::serialize(obj.a, serializer); - serde::Serializable::serialize(obj.b, serializer); - serde::Serializable::serialize(obj.radix, serializer); -} - -template <> -template -Program::Directive::ToLeRadix serde::Deserializable::deserialize( - Deserializer& deserializer) -{ - Program::Directive::ToLeRadix obj; - obj.a = serde::Deserializable::deserialize(deserializer); - obj.b = serde::Deserializable::deserialize(deserializer); - obj.radix = serde::Deserializable::deserialize(deserializer); - return obj; -} - -namespace Program { - inline bool operator==(const Expression& lhs, const Expression& rhs) { if (!(lhs.mul_terms == rhs.mul_terms)) { @@ -8253,52 +8120,6 @@ Program::Opcode::BlackBoxFuncCall serde::Deserializable Opcode::Directive::bincodeSerialize() const -{ - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); -} - -inline Opcode::Directive Opcode::Directive::bincodeDeserialize(std::vector input) -{ - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw_or_abort("Some input bytes were not read"); - } - return value; -} - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::Opcode::Directive& obj, - Serializer& serializer) -{ - serde::Serializable::serialize(obj.value, serializer); -} - -template <> -template -Program::Opcode::Directive serde::Deserializable::deserialize(Deserializer& deserializer) -{ - Program::Opcode::Directive obj; - obj.value = serde::Deserializable::deserialize(deserializer); - return obj; -} - -namespace Program { - inline bool operator==(const Opcode::MemoryOp& lhs, const Opcode::MemoryOp& rhs) { if (!(lhs.block_id == rhs.block_id)) { diff --git a/noir/noir-repo/acvm-repo/acir/README.md b/noir/noir-repo/acvm-repo/acir/README.md index 902769e3ad7..a0e7094b4d6 100644 --- a/noir/noir-repo/acvm-repo/acir/README.md +++ b/noir/noir-repo/acvm-repo/acir/README.md @@ -77,7 +77,7 @@ In summary, the workflow is the following: 1. user program -> (compilation) ACIR, a list of opcodes which constrain (partial) witnesses 2. user inputs + ACIR -> (execution/solving) assign values to all the - (partial) witnesses + (partial) witnesses 3. witness assignment + ACIR -> (proving system) proof Although the ordering of opcode does not matter in theory, since a system of @@ -121,7 +121,7 @@ proving system and are only used by the solver. Finally, some opcodes will have a predicate, whose value is `0` or `1`. Its purpose is to nullify the opcode when the value is `0`, so that it has no effect. Note that removing the opcode is not a solution because this modifies -the circuit (the circuit being mainly the list of the opcodes). +the circuit (the circuit being mainly the list of the opcodes). *Remark*: Opcodes operate on witnesses, but we will see that some opcode work on expressions of witnesses. We call an expression a linear combination of @@ -265,16 +265,6 @@ without adding any constraint. NOTE: see the [circuit/opcodes.rs](src/circuit/opcodes.rs) file for the most up-to-date documentation on these opcodes. -#### Directive - -This opcode is a specialization of Brillig opcode. Instead of having some generic -assembly code like Brillig, a directive has a hardcoded name which tells the -solver which computation to do: with Brillig, the computation refers to the -compiled bytecode of an unconstrained Noir function, but with a directive, the -computation is hardcoded inside the compiler. - -Directives will be replaced by Brillig opcodes in the future. - #### MemoryOp: memory abstraction for ACIR ACIR is able to address any array of witnesses. Each array is assigned an ID diff --git a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp index d237f2ab3b4..2ae9a31d6ca 100644 --- a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp +++ b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp @@ -1085,25 +1085,6 @@ namespace Program { static BrilligOutputs bincodeDeserialize(std::vector); }; - struct Directive { - - struct ToLeRadix { - Program::Expression a; - std::vector b; - uint32_t radix; - - friend bool operator==(const ToLeRadix&, const ToLeRadix&); - std::vector bincodeSerialize() const; - static ToLeRadix bincodeDeserialize(std::vector); - }; - - std::variant value; - - friend bool operator==(const Directive&, const Directive&); - std::vector bincodeSerialize() const; - static Directive bincodeDeserialize(std::vector); - }; - struct MemOp { Program::Expression operation; Program::Expression index; @@ -1132,14 +1113,6 @@ namespace Program { static BlackBoxFuncCall bincodeDeserialize(std::vector); }; - struct Directive { - Program::Directive value; - - friend bool operator==(const Directive&, const Directive&); - std::vector bincodeSerialize() const; - static Directive bincodeDeserialize(std::vector); - }; - struct MemoryOp { Program::BlockId block_id; Program::MemOp op; @@ -1182,7 +1155,7 @@ namespace Program { static Call bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; friend bool operator==(const Opcode&, const Opcode&); std::vector bincodeSerialize() const; @@ -5663,92 +5636,6 @@ Program::ConstantOrWitnessEnum::Witness serde::Deserializable Directive::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline Directive Directive::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::Directive &obj, Serializer &serializer) { - serializer.increase_container_depth(); - serde::Serializable::serialize(obj.value, serializer); - serializer.decrease_container_depth(); -} - -template <> -template -Program::Directive serde::Deserializable::deserialize(Deserializer &deserializer) { - deserializer.increase_container_depth(); - Program::Directive obj; - obj.value = serde::Deserializable::deserialize(deserializer); - deserializer.decrease_container_depth(); - return obj; -} - -namespace Program { - - inline bool operator==(const Directive::ToLeRadix &lhs, const Directive::ToLeRadix &rhs) { - if (!(lhs.a == rhs.a)) { return false; } - if (!(lhs.b == rhs.b)) { return false; } - if (!(lhs.radix == rhs.radix)) { return false; } - return true; - } - - inline std::vector Directive::ToLeRadix::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline Directive::ToLeRadix Directive::ToLeRadix::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::Directive::ToLeRadix &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.a, serializer); - serde::Serializable::serialize(obj.b, serializer); - serde::Serializable::serialize(obj.radix, serializer); -} - -template <> -template -Program::Directive::ToLeRadix serde::Deserializable::deserialize(Deserializer &deserializer) { - Program::Directive::ToLeRadix obj; - obj.a = serde::Deserializable::deserialize(deserializer); - obj.b = serde::Deserializable::deserialize(deserializer); - obj.radix = serde::Deserializable::deserialize(deserializer); - return obj; -} - namespace Program { inline bool operator==(const Expression &lhs, const Expression &rhs) { @@ -6860,44 +6747,6 @@ Program::Opcode::BlackBoxFuncCall serde::Deserializable Opcode::Directive::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline Opcode::Directive Opcode::Directive::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::Opcode::Directive &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.value, serializer); -} - -template <> -template -Program::Opcode::Directive serde::Deserializable::deserialize(Deserializer &deserializer) { - Program::Opcode::Directive obj; - obj.value = serde::Deserializable::deserialize(deserializer); - return obj; -} - namespace Program { inline bool operator==(const Opcode::MemoryOp &lhs, const Opcode::MemoryOp &rhs) { diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/directives.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/directives.rs deleted file mode 100644 index 3bc66288590..00000000000 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/directives.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::native_types::{Expression, Witness}; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -/// Directives do not apply any constraints. -/// You can think of them as opcodes that allow one to use non-determinism -/// In the future, this can be replaced with asm non-determinism blocks -pub enum Directive { - //decomposition of a: a=\sum b[i]*radix^i where b is an array of witnesses < radix in little endian form - ToLeRadix { a: Expression, b: Vec, radix: u32 }, -} diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs index 12990f66175..33982065c2a 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs @@ -1,6 +1,5 @@ pub mod black_box_functions; pub mod brillig; -pub mod directives; pub mod opcodes; use crate::native_types::{Expression, Witness}; diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs index c32aa6edd27..06effd3c5b6 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs @@ -1,7 +1,4 @@ -use super::{ - brillig::{BrilligFunctionId, BrilligInputs, BrilligOutputs}, - directives::Directive, -}; +use super::brillig::{BrilligFunctionId, BrilligInputs, BrilligOutputs}; pub mod function_id; pub use function_id::AcirFunctionId; @@ -75,16 +72,6 @@ pub enum Opcode { /// embedded curve. BlackBoxFuncCall(BlackBoxFuncCall), - /// This opcode is a specialization of a Brillig opcode. Instead of having - /// some generic assembly code like Brillig, a directive has a hardcoded - /// name which tells the solver which computation to do: with Brillig, the - /// computation refers to the compiled bytecode of an unconstrained Noir - /// function, but with a directive, the computation is hardcoded inside the - /// compiler. - /// - /// Directives will be replaced by Brillig opcodes in the future. - Directive(Directive), - /// Atomic operation on a block of memory /// /// ACIR is able to address any array of witnesses. Each array is assigned @@ -158,9 +145,6 @@ impl std::fmt::Display for Opcode { } Opcode::BlackBoxFuncCall(g) => write!(f, "{g}"), - Opcode::Directive(_) => { - unreachable!("directives no longer exist") - } Opcode::MemoryOp { block_id, op, predicate } => { write!(f, "MEM ")?; if let Some(pred) = predicate { diff --git a/noir/noir-repo/acvm-repo/acir/src/lib.rs b/noir/noir-repo/acvm-repo/acir/src/lib.rs index f8a31439127..bb5b50c0daf 100644 --- a/noir/noir-repo/acvm-repo/acir/src/lib.rs +++ b/noir/noir-repo/acvm-repo/acir/src/lib.rs @@ -42,7 +42,6 @@ mod reflection { use crate::{ circuit::{ brillig::{BrilligInputs, BrilligOutputs}, - directives::Directive, opcodes::{BlackBoxFuncCall, BlockType, ConstantOrWitnessEnum, FunctionInput}, AssertionPayload, Circuit, ExpressionOrMemory, ExpressionWidth, Opcode, OpcodeLocation, Program, @@ -77,7 +76,6 @@ mod reflection { tracer.trace_simple_type::>().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::>().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::>().unwrap(); diff --git a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs index b463d4d1fe5..002bad0e7f3 100644 --- a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs +++ b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs @@ -222,12 +222,12 @@ fn simple_brillig_foreign_call() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 81, 203, 10, 128, 48, 12, 179, 19, 31, 3, 111, 254, - 200, 246, 7, 254, 140, 7, 47, 30, 68, 252, 126, 39, 182, 80, 70, 182, 203, 26, 40, 73, 3, - 43, 9, 163, 238, 199, 156, 134, 88, 15, 204, 178, 107, 136, 183, 49, 135, 54, 68, 178, 187, - 21, 116, 94, 151, 11, 210, 102, 165, 152, 148, 247, 153, 255, 113, 111, 24, 214, 131, 124, - 134, 247, 227, 4, 58, 58, 208, 119, 73, 51, 178, 62, 206, 103, 191, 110, 244, 237, 250, 69, - 105, 47, 249, 43, 240, 37, 201, 11, 205, 95, 230, 87, 127, 2, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 81, 203, 10, 128, 48, 12, 179, 243, 57, 240, 230, + 143, 108, 127, 224, 207, 120, 240, 226, 65, 196, 239, 119, 98, 11, 101, 100, 94, 214, 64, + 73, 26, 88, 73, 24, 53, 31, 166, 52, 196, 186, 99, 150, 93, 67, 188, 149, 57, 212, 33, 146, + 221, 173, 160, 243, 186, 92, 144, 54, 127, 138, 245, 204, 62, 243, 95, 110, 13, 195, 122, + 144, 207, 240, 126, 28, 65, 71, 7, 250, 206, 105, 6, 214, 251, 113, 111, 231, 133, 190, 93, + 191, 40, 237, 37, 127, 1, 190, 36, 121, 0, 128, 254, 118, 42, 127, 2, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -368,16 +368,16 @@ fn complex_brillig_foreign_call() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 85, 205, 14, 130, 48, 12, 238, 54, 20, 136, 222, - 124, 1, 19, 125, 128, 161, 241, 238, 187, 24, 111, 26, 61, 250, 248, 186, 208, 198, 89, 26, - 56, 216, 18, 248, 18, 82, 6, 237, 215, 255, 204, 65, 139, 234, 243, 56, 124, 95, 160, 244, - 40, 211, 247, 0, 191, 32, 221, 51, 202, 248, 31, 26, 167, 199, 21, 173, 98, 244, 51, 136, - 49, 24, 196, 8, 89, 255, 39, 216, 111, 205, 190, 168, 214, 47, 8, 251, 83, 64, 187, 95, 75, - 60, 151, 40, 43, 94, 232, 100, 228, 161, 187, 120, 57, 104, 120, 86, 40, 107, 225, 191, 98, - 66, 199, 154, 249, 85, 230, 143, 84, 140, 45, 244, 231, 107, 155, 231, 33, 18, 127, 48, - 225, 143, 13, 241, 23, 70, 125, 42, 89, 189, 242, 92, 114, 191, 107, 248, 14, 224, 229, - 113, 127, 222, 174, 175, 32, 152, 114, 243, 132, 29, 59, 239, 133, 146, 13, 113, 16, 242, - 123, 166, 79, 223, 9, 250, 67, 54, 99, 141, 138, 209, 74, 156, 54, 208, 5, 249, 122, 3, 73, - 2, 62, 54, 188, 7, 0, 0, + 124, 1, 19, 125, 128, 161, 241, 238, 187, 24, 111, 26, 61, 250, 248, 178, 216, 198, 89, 26, + 56, 216, 18, 248, 146, 165, 12, 218, 175, 255, 193, 193, 7, 85, 123, 28, 62, 23, 40, 61, + 202, 244, 62, 192, 47, 72, 247, 140, 50, 254, 135, 198, 233, 113, 69, 171, 24, 253, 12, 98, + 12, 6, 49, 66, 214, 255, 9, 246, 91, 179, 47, 170, 245, 11, 194, 254, 164, 221, 90, 180, + 103, 137, 247, 18, 101, 197, 11, 157, 140, 60, 116, 23, 47, 7, 13, 207, 10, 101, 45, 124, + 87, 76, 232, 88, 51, 191, 202, 252, 145, 138, 177, 133, 254, 124, 109, 243, 60, 68, 226, + 15, 38, 252, 177, 33, 254, 194, 168, 79, 37, 171, 87, 158, 75, 238, 119, 13, 223, 1, 188, + 60, 238, 207, 219, 245, 21, 4, 83, 110, 158, 176, 99, 247, 189, 80, 178, 33, 14, 66, 254, + 159, 233, 211, 119, 130, 254, 144, 205, 88, 163, 98, 180, 18, 167, 13, 116, 65, 190, 222, + 250, 76, 4, 233, 188, 7, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -415,11 +415,11 @@ fn memory_op_circuit() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 82, 65, 10, 0, 32, 8, 211, 180, 255, 216, 15, 250, - 255, 171, 10, 82, 176, 58, 166, 135, 6, 178, 29, 100, 204, 33, 194, 66, 157, 67, 170, 89, - 185, 40, 163, 211, 182, 115, 162, 43, 203, 27, 90, 182, 47, 6, 251, 82, 156, 151, 100, 151, - 43, 191, 149, 203, 209, 183, 147, 11, 90, 96, 255, 102, 11, 207, 112, 99, 0, 192, 100, 38, - 199, 38, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 144, 75, 10, 0, 32, 8, 68, 253, 117, 31, 187, 65, + 247, 63, 85, 65, 10, 82, 203, 116, 209, 128, 60, 221, 12, 227, 32, 108, 181, 53, 108, 187, + 147, 140, 24, 118, 231, 169, 97, 212, 55, 245, 106, 95, 76, 246, 229, 60, 47, 173, 46, 87, + 127, 43, 87, 178, 127, 231, 16, 148, 194, 29, 195, 11, 220, 154, 119, 139, 115, 25, 38, 3, + 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -518,15 +518,15 @@ fn nested_acir_call_circuit() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 146, 81, 10, 195, 48, 8, 134, 77, 132, 158, 71, 99, - 210, 152, 183, 93, 101, 97, 233, 253, 143, 176, 142, 165, 44, 100, 133, 62, 52, 125, 232, - 7, 63, 138, 136, 232, 143, 8, 95, 176, 234, 195, 180, 202, 172, 178, 240, 195, 84, 193, 86, - 63, 106, 66, 232, 216, 26, 31, 53, 210, 57, 216, 54, 179, 132, 102, 239, 75, 116, 133, 133, - 159, 228, 82, 214, 64, 62, 228, 89, 89, 57, 104, 120, 57, 21, 41, 234, 53, 166, 156, 34, - 37, 246, 82, 120, 9, 73, 150, 58, 12, 199, 237, 69, 208, 152, 208, 230, 6, 254, 193, 206, - 192, 171, 188, 130, 129, 94, 217, 113, 123, 185, 169, 222, 106, 155, 187, 119, 159, 168, - 255, 178, 62, 199, 174, 102, 110, 102, 170, 129, 177, 15, 120, 228, 215, 30, 111, 39, 140, - 108, 64, 11, 4, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 146, 81, 10, 195, 48, 8, 134, 77, 164, 247, 209, + 152, 52, 230, 109, 87, 89, 88, 122, 255, 35, 172, 99, 41, 11, 89, 161, 15, 77, 31, 250, + 193, 143, 34, 34, 250, 35, 194, 23, 172, 250, 48, 173, 50, 171, 44, 252, 48, 85, 176, 213, + 143, 154, 16, 58, 182, 198, 71, 141, 116, 14, 182, 205, 44, 161, 217, 251, 18, 93, 97, 225, + 39, 185, 148, 53, 144, 15, 121, 86, 86, 14, 26, 94, 78, 69, 138, 122, 141, 41, 167, 72, + 137, 189, 20, 94, 66, 146, 165, 14, 195, 113, 123, 17, 52, 38, 180, 185, 129, 127, 176, 51, + 240, 42, 175, 96, 160, 87, 118, 220, 94, 110, 170, 183, 218, 230, 238, 221, 39, 234, 191, + 172, 207, 177, 171, 153, 155, 153, 106, 96, 236, 3, 30, 249, 181, 199, 27, 99, 149, 130, + 253, 11, 4, 0, 0, ]; assert_eq!(bytes, expected_serialization); } diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/constant_backpropagation.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/constant_backpropagation.rs index c2ee9e93a87..994cfc84e66 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/constant_backpropagation.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/constant_backpropagation.rs @@ -3,14 +3,13 @@ use std::collections::{BTreeMap, BTreeSet, HashMap}; use crate::{ compiler::optimizers::GeneralOptimizer, pwg::{ - arithmetic::ExpressionSolver, blackbox::solve_range_opcode, directives::solve_directives, - BrilligSolver, BrilligSolverStatus, + arithmetic::ExpressionSolver, blackbox::solve_range_opcode, BrilligSolver, + BrilligSolverStatus, }, }; use acir::{ circuit::{ brillig::{Brillig, BrilligInputs, BrilligOutputs}, - directives::Directive, opcodes::BlackBoxFuncCall, Circuit, Opcode, }, diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs index ff91cc80735..56cfa000da2 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs @@ -191,8 +191,6 @@ impl MergeExpressionsOptimizer { } witnesses } - // Directive opcode is to be removed - Opcode::Directive(_) => unreachable!(), } } diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/simulator.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/simulator.rs index 47bc0f72864..893195f342a 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/simulator.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/simulator.rs @@ -83,9 +83,6 @@ impl CircuitSimulator { } true } - Opcode::Directive(_) => { - unreachable!("directives no longer exist") - } Opcode::MemoryOp { block_id, op, predicate } => { if !self.can_solve_expression(&op.index) { return false; diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs index ad399138929..c9ce4ac7895 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs @@ -145,8 +145,6 @@ pub(super) fn transform_internal( new_acir_opcode_positions.push(acir_opcode_positions[index]); transformed_opcodes.push(opcode); } - // Directive opcode is to be removed - Opcode::Directive(_) => unreachable!(), } } diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs index 2faf8fccd3a..20c12a72fc0 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs @@ -384,8 +384,6 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { Ok(Some(input_values)) => return self.wait_for_acir_call(input_values), res => res.map(|_| ()), }, - // Directive opcode is to be removed - Opcode::Directive(_) => unreachable!(), }; self.handle_opcode_resolution(resolution) } diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts index 755b5a7587b..24fbc1a921a 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts @@ -3,13 +3,13 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `complex_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 85, 205, 14, 130, 48, 12, 238, 54, 20, 136, 222, 124, 1, 19, 125, 128, 161, - 241, 238, 187, 24, 111, 26, 61, 250, 248, 186, 208, 198, 89, 26, 56, 216, 18, 248, 18, 82, 6, 237, 215, 255, 204, 65, - 139, 234, 243, 56, 124, 95, 160, 244, 40, 211, 247, 0, 191, 32, 221, 51, 202, 248, 31, 26, 167, 199, 21, 173, 98, 244, - 51, 136, 49, 24, 196, 8, 89, 255, 39, 216, 111, 205, 190, 168, 214, 47, 8, 251, 83, 64, 187, 95, 75, 60, 151, 40, 43, - 94, 232, 100, 228, 161, 187, 120, 57, 104, 120, 86, 40, 107, 225, 191, 98, 66, 199, 154, 249, 85, 230, 143, 84, 140, - 45, 244, 231, 107, 155, 231, 33, 18, 127, 48, 225, 143, 13, 241, 23, 70, 125, 42, 89, 189, 242, 92, 114, 191, 107, - 248, 14, 224, 229, 113, 127, 222, 174, 175, 32, 152, 114, 243, 132, 29, 59, 239, 133, 146, 13, 113, 16, 242, 123, 166, - 79, 223, 9, 250, 67, 54, 99, 141, 138, 209, 74, 156, 54, 208, 5, 249, 122, 3, 73, 2, 62, 54, 188, 7, 0, 0, + 241, 238, 187, 24, 111, 26, 61, 250, 248, 178, 216, 198, 89, 26, 56, 216, 18, 248, 146, 165, 12, 218, 175, 255, 193, + 193, 7, 85, 123, 28, 62, 23, 40, 61, 202, 244, 62, 192, 47, 72, 247, 140, 50, 254, 135, 198, 233, 113, 69, 171, 24, + 253, 12, 98, 12, 6, 49, 66, 214, 255, 9, 246, 91, 179, 47, 170, 245, 11, 194, 254, 164, 221, 90, 180, 103, 137, 247, + 18, 101, 197, 11, 157, 140, 60, 116, 23, 47, 7, 13, 207, 10, 101, 45, 124, 87, 76, 232, 88, 51, 191, 202, 252, 145, + 138, 177, 133, 254, 124, 109, 243, 60, 68, 226, 15, 38, 252, 177, 33, 254, 194, 168, 79, 37, 171, 87, 158, 75, 238, + 119, 13, 223, 1, 188, 60, 238, 207, 219, 245, 21, 4, 83, 110, 158, 176, 99, 247, 189, 80, 178, 33, 14, 66, 254, 159, + 233, 211, 119, 130, 254, 144, 205, 88, 163, 98, 180, 18, 167, 13, 116, 65, 190, 222, 250, 76, 4, 233, 188, 7, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts index 37b70e23a3a..da0b9974c61 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts @@ -2,11 +2,11 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `simple_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 81, 203, 10, 128, 48, 12, 179, 19, 31, 3, 111, 254, 200, 246, 7, 254, 140, 7, - 47, 30, 68, 252, 126, 39, 182, 80, 70, 182, 203, 26, 40, 73, 3, 43, 9, 163, 238, 199, 156, 134, 88, 15, 204, 178, 107, - 136, 183, 49, 135, 54, 68, 178, 187, 21, 116, 94, 151, 11, 210, 102, 165, 152, 148, 247, 153, 255, 113, 111, 24, 214, - 131, 124, 134, 247, 227, 4, 58, 58, 208, 119, 73, 51, 178, 62, 206, 103, 191, 110, 244, 237, 250, 69, 105, 47, 249, - 43, 240, 37, 201, 11, 205, 95, 230, 87, 127, 2, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 81, 203, 10, 128, 48, 12, 179, 243, 57, 240, 230, 143, 108, 127, 224, 207, + 120, 240, 226, 65, 196, 239, 119, 98, 11, 101, 100, 94, 214, 64, 73, 26, 88, 73, 24, 53, 31, 166, 52, 196, 186, 99, + 150, 93, 67, 188, 149, 57, 212, 33, 146, 221, 173, 160, 243, 186, 92, 144, 54, 127, 138, 245, 204, 62, 243, 95, 110, + 13, 195, 122, 144, 207, 240, 126, 28, 65, 71, 7, 250, 206, 105, 6, 214, 251, 113, 111, 231, 133, 190, 93, 191, 40, + 237, 37, 127, 1, 190, 36, 121, 0, 128, 254, 118, 42, 127, 2, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000005'], diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/memory_op.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/memory_op.ts index 2287d31d37e..2f0fbfb85f1 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/memory_op.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/memory_op.ts @@ -1,9 +1,9 @@ // See `memory_op_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 82, 65, 10, 0, 32, 8, 211, 180, 255, 216, 15, 250, 255, 171, 10, 82, 176, 58, - 166, 135, 6, 178, 29, 100, 204, 33, 194, 66, 157, 67, 170, 89, 185, 40, 163, 211, 182, 115, 162, 43, 203, 27, 90, 182, - 47, 6, 251, 82, 156, 151, 100, 151, 43, 191, 149, 203, 209, 183, 147, 11, 90, 96, 255, 102, 11, 207, 112, 99, 0, 192, - 100, 38, 199, 38, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 144, 75, 10, 0, 32, 8, 68, 253, 117, 31, 187, 65, 247, 63, 85, 65, 10, 82, + 203, 116, 209, 128, 60, 221, 12, 227, 32, 108, 181, 53, 108, 187, 147, 140, 24, 118, 231, 169, 97, 212, 55, 245, 106, + 95, 76, 246, 229, 60, 47, 173, 46, 87, 127, 43, 87, 178, 127, 231, 16, 148, 194, 29, 195, 11, 220, 154, 119, 139, 115, + 25, 38, 3, 0, 0, ]); export const initialWitnessMap = new Map([ diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/nested_acir_call.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/nested_acir_call.ts index 5e0bcf25300..3464809dfc4 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/nested_acir_call.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/nested_acir_call.ts @@ -2,13 +2,13 @@ import { WitnessMap, StackItem, WitnessStack } from '@noir-lang/acvm_js'; // See `nested_acir_call_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 146, 81, 10, 195, 48, 8, 134, 77, 132, 158, 71, 99, 210, 152, 183, 93, 101, - 97, 233, 253, 143, 176, 142, 165, 44, 100, 133, 62, 52, 125, 232, 7, 63, 138, 136, 232, 143, 8, 95, 176, 234, 195, - 180, 202, 172, 178, 240, 195, 84, 193, 86, 63, 106, 66, 232, 216, 26, 31, 53, 210, 57, 216, 54, 179, 132, 102, 239, - 75, 116, 133, 133, 159, 228, 82, 214, 64, 62, 228, 89, 89, 57, 104, 120, 57, 21, 41, 234, 53, 166, 156, 34, 37, 246, - 82, 120, 9, 73, 150, 58, 12, 199, 237, 69, 208, 152, 208, 230, 6, 254, 193, 206, 192, 171, 188, 130, 129, 94, 217, - 113, 123, 185, 169, 222, 106, 155, 187, 119, 159, 168, 255, 178, 62, 199, 174, 102, 110, 102, 170, 129, 177, 15, 120, - 228, 215, 30, 111, 39, 140, 108, 64, 11, 4, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 146, 81, 10, 195, 48, 8, 134, 77, 164, 247, 209, 152, 52, 230, 109, 87, 89, + 88, 122, 255, 35, 172, 99, 41, 11, 89, 161, 15, 77, 31, 250, 193, 143, 34, 34, 250, 35, 194, 23, 172, 250, 48, 173, + 50, 171, 44, 252, 48, 85, 176, 213, 143, 154, 16, 58, 182, 198, 71, 141, 116, 14, 182, 205, 44, 161, 217, 251, 18, 93, + 97, 225, 39, 185, 148, 53, 144, 15, 121, 86, 86, 14, 26, 94, 78, 69, 138, 122, 141, 41, 167, 72, 137, 189, 20, 94, 66, + 146, 165, 14, 195, 113, 123, 17, 52, 38, 180, 185, 129, 127, 176, 51, 240, 42, 175, 96, 160, 87, 118, 220, 94, 110, + 170, 183, 218, 230, 238, 221, 39, 234, 191, 172, 207, 177, 171, 153, 155, 153, 106, 96, 236, 3, 30, 249, 181, 199, 27, + 99, 149, 130, 253, 11, 4, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ diff --git a/noir/noir-repo/acvm-repo/brillig/src/lib.rs b/noir/noir-repo/acvm-repo/brillig/src/lib.rs index 5bd9f898d59..cf31ff79996 100644 --- a/noir/noir-repo/acvm-repo/brillig/src/lib.rs +++ b/noir/noir-repo/acvm-repo/brillig/src/lib.rs @@ -4,7 +4,6 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] //! The Brillig bytecode is distinct from regular [ACIR][acir] in that it does not generate constraints. -//! This is a generalization over the fixed directives that exists within in the ACVM. //! //! [acir]: https://crates.io/crates/acir //! [acvm]: https://crates.io/crates/acvm diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs index 0a1614a98fc..45025fbb208 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs @@ -6,7 +6,6 @@ //! The Brillig VM is a specialized VM which allows the [ACVM][acvm] to perform custom non-determinism. //! //! Brillig bytecode is distinct from regular [ACIR][acir] in that it does not generate constraints. -//! This is a generalization over the fixed directives that exists within in the ACVM. //! //! [acir]: https://crates.io/crates/acir //! [acvm]: https://crates.io/crates/acvm From 5f8a9e2766cfe1861dcd95acf03db094047c8368 Mon Sep 17 00:00:00 2001 From: Tom French Date: Thu, 14 Nov 2024 20:07:47 +0000 Subject: [PATCH 4/5] . --- noir/noir-repo/tooling/profiler/src/opcode_formatter.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs b/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs index aacc2ae438f..3c910fa5401 100644 --- a/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs +++ b/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs @@ -67,10 +67,6 @@ fn format_acir_opcode_kind(opcode: &AcirOpcode) -> String { AcirOpcode::MemoryInit { .. } => "memory::init".to_string(), AcirOpcode::BrilligCall { id, .. } => format!("brillig_call({id})"), AcirOpcode::Call { .. } => "acir_call".to_string(), - - AcirOpcode::Directive(_) => { - unreachable!("directives no longer exist") - } } } From 3747c11d915d68b607be6fa7acd93eaab8f5c76d Mon Sep 17 00:00:00 2001 From: guipublic Date: Fri, 15 Nov 2024 10:36:51 +0000 Subject: [PATCH 5/5] fix to_radix brillig return to return a pointer to the result --- .../src/brillig/brillig_gen/brillig_directive.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs index 8ce41bdacc0..89fc7f1eda5 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs @@ -173,8 +173,7 @@ pub(crate) fn directive_to_radix() -> GeneratedBrillig { // address of the result array let result_base_adr = 10_usize; - let result_vector = - HeapVector { pointer: MemoryAddress::direct(result_base_adr), size: limbs_nb }; + let result_vector = HeapVector { pointer: result_pointer, size: limbs_nb }; let byte_code = vec![ // Initialize registers @@ -264,6 +263,12 @@ pub(crate) fn directive_to_radix() -> GeneratedBrillig { }, // loop back BrilligOpcode::JumpIf { condition: cond, location: 7 }, + // reset result pointer to the start of the array + BrilligOpcode::Const { + destination: result_pointer, + bit_size: memory_adr_size, + value: F::from(result_base_adr), + }, BrilligOpcode::Stop { return_data: result_vector }, ];