diff --git a/acvm-repo/acir/src/circuit/mod.rs b/acvm-repo/acir/src/circuit/mod.rs index 9b56183d047..2ff82422ef0 100644 --- a/acvm-repo/acir/src/circuit/mod.rs +++ b/acvm-repo/acir/src/circuit/mod.rs @@ -326,8 +326,6 @@ impl Deserialize<'a>> Program { impl std::fmt::Display for Circuit { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "current witness: w{}", self.current_witness_index)?; - let write_witness_indices = |f: &mut std::fmt::Formatter<'_>, indices: &[u32]| -> Result<(), std::fmt::Error> { write!(f, "[")?; @@ -540,14 +538,13 @@ mod tests { insta::assert_snapshot!( circuit.to_string(), @r" - current witness: w3 private parameters: [] public parameters: [w2] return values: [w2] - EXPR 0 = 2*w1 + 8 - BLACKBOX::RANGE [w1]:8 bits [] - BLACKBOX::AND [w1, w2]:4 bits [w3] - BLACKBOX::KECCAKF1600 [w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24, w25] [w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36, w37, w38, w39, w40, w41, w42, w43, w44, w45, w46, w47, w48, w49, w50] + ASSERT 0 = 2*w1 + 8 + BLACKBOX::RANGE input: w1, bits: 8 + BLACKBOX::AND inputs: [w1, w2], bits: 4, output: w3 + BLACKBOX::KECCAKF1600 inputs: [w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24, w25], outputs: [w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36, w37, w38, w39, w40, w41, w42, w43, w44, w45, w46, w47, w48, w49, w50] " ); } diff --git a/acvm-repo/acir/src/circuit/opcodes.rs b/acvm-repo/acir/src/circuit/opcodes.rs index 60789ed3156..76f64bd30ec 100644 --- a/acvm-repo/acir/src/circuit/opcodes.rs +++ b/acvm-repo/acir/src/circuit/opcodes.rs @@ -147,18 +147,16 @@ impl std::fmt::Display for Opcode { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Opcode::AssertZero(expr) => { - write!(f, "EXPR ")?; + write!(f, "ASSERT ")?; display_expression(expr, true, f) } Opcode::BlackBoxFuncCall(g) => g.fmt(f), Opcode::MemoryOp { block_id, op } => { - write!(f, "MEM ")?; - let is_read = op.operation.is_zero(); if is_read { - write!(f, "id: {}, read at: {}, value: {}", block_id.0, op.index, op.value) + write!(f, "READ {} = b{}[{}]", op.value, block_id.0, op.index) } else { - write!(f, "id: {}, write: {} at: {}", block_id.0, op.value, op.index) + write!(f, "WRITE b{}[{}] = {}", block_id.0, op.index, op.value) } } Opcode::MemoryInit { block_id, init, block_type: databus } => { @@ -169,14 +167,14 @@ impl std::fmt::Display for Opcode { } let witnesses = init.iter().map(|w| format!("{w}")).collect::>().join(", "); - write!(f, "id: {}, len: {}, witnesses: [{witnesses}]", block_id.0, init.len()) + write!(f, "b{} = [{witnesses}]", block_id.0) } // We keep the display for a BrilligCall and circuit Call separate as they // are distinct in their functionality and we should maintain this separation for debugging. Opcode::BrilligCall { id, inputs, outputs, predicate } => { - write!(f, "BRILLIG CALL func {id}: ")?; + write!(f, "BRILLIG CALL func: {id}, ")?; if let Some(pred) = predicate { - writeln!(f, "PREDICATE: {pred}")?; + write!(f, "predicate: {pred}, ")?; } let inputs = inputs @@ -194,9 +192,9 @@ impl std::fmt::Display for Opcode { write!(f, "outputs: [{outputs}]") } Opcode::Call { id, inputs, outputs, predicate } => { - write!(f, "CALL func {id}: ")?; + write!(f, "CALL func: {id}, ")?; if let Some(pred) = predicate { - writeln!(f, "PREDICATE: {pred}")?; + write!(f, "predicate: {pred}, ")?; } let inputs = inputs.iter().map(|w| format!("{w}")).collect::>().join(", "); @@ -237,7 +235,7 @@ mod tests { insta::assert_snapshot!( mem_init.to_string(), - @"INIT id: 42, len: 10, witnesses: [w0, w1, w2, w3, w4, w5, w6, w7, w8, w9]" + @"INIT b42 = [w0, w1, w2, w3, w4, w5, w6, w7, w8, w9]" ); } @@ -252,7 +250,7 @@ mod tests { insta::assert_snapshot!( xor.to_string(), - @"BLACKBOX::XOR [w0, w1]:32 bits [w3]" + @"BLACKBOX::XOR inputs: [w0, w1], bits: 32, output: w3" ); } @@ -265,7 +263,7 @@ mod tests { insta::assert_snapshot!( range.to_string(), - @"BLACKBOX::RANGE [w0]:32 bits []" + @"BLACKBOX::RANGE input: w0, bits: 32" ); } } diff --git a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 06547071044..287c4fa44d6 100644 --- a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -434,31 +434,34 @@ impl std::fmt::Display for BlackBoxFuncCall { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let uppercase_name = self.name().to_uppercase(); write!(f, "BLACKBOX::{uppercase_name} ")?; - // INPUTS - let inputs_str = &self - .get_inputs_vec() - .iter() - .map(|i| i.to_string()) - .collect::>() - .join(", "); + // inputs + let inputs = &self.get_inputs_vec(); + let inputs_str = inputs.iter().map(|i| i.to_string()).collect::>().join(", "); + if inputs.len() == 1 { + write!(f, "input: {inputs_str}")?; + } else { + write!(f, "inputs: [{inputs_str}]")?; + } - write!(f, "[{inputs_str}]")?; + // bits if let Some(bit_size) = self.bit_size() { - write!(f, ":{bit_size} bits")?; + write!(f, ", bits: {bit_size}")?; } - write!(f, " ")?; - - // OUTPUTS - let outputs_str = &self - .get_outputs_vec() - .iter() - .map(ToString::to_string) - .collect::>() - .join(", "); + // outputs + let outputs = &self.get_outputs_vec(); + if !outputs.is_empty() { + let outputs_str = + outputs.iter().map(ToString::to_string).collect::>().join(", "); + if outputs.len() == 1 { + write!(f, ", output: {outputs_str}")?; + } else { + write!(f, ", outputs: [{outputs_str}]")?; + } + } - write!(f, "[{outputs_str}]") + Ok(()) } } diff --git a/acvm-repo/acir/src/parser/lexer.rs b/acvm-repo/acir/src/parser/lexer.rs index 3c6d6592e8a..63e69cec9a2 100644 --- a/acvm-repo/acir/src/parser/lexer.rs +++ b/acvm-repo/acir/src/parser/lexer.rs @@ -70,16 +70,21 @@ impl<'a> Lexer<'a> { } '*' => self.single_char_token(Token::Star), '=' => self.single_char_token(Token::Equal), - 'w' if self.peek_char().is_some_and(|char| char.is_ascii_digit()) => { + 'b' | 'w' if self.peek_char().is_some_and(|char| char.is_ascii_digit()) => { let start = self.position; - // Witness token format is 'w' followed by digits + // Witness token format is 'w' followed by digits. + // Block token format is 'b' followed by digits. let digits = self.eat_while(None, |ch| ch.is_ascii_digit()); let end = self.position; // Parse digits into u32 match digits.parse::() { - Ok(value) => Ok(Token::Witness(value).into_span(start, end)), + Ok(value) => { + let token = + if ch == 'w' { Token::Witness(value) } else { Token::Block(value) }; + Ok(token.into_span(start, end)) + } Err(_) => Err(LexerError::InvalidIntegerLiteral { span: Span::inclusive(start, end), found: digits, diff --git a/acvm-repo/acir/src/parser/mod.rs b/acvm-repo/acir/src/parser/mod.rs index 09e441433f2..75914231318 100644 --- a/acvm-repo/acir/src/parser/mod.rs +++ b/acvm-repo/acir/src/parser/mod.rs @@ -114,12 +114,13 @@ impl Circuit { struct Parser<'a> { lexer: Lexer<'a>, token: SpannedToken, + max_witness_index: u32, } impl<'a> Parser<'a> { fn new(source: &'a str) -> ParseResult { let lexer = Lexer::new(source); - let mut parser = Self { lexer, token: eof_spanned_token() }; + let mut parser = Self { lexer, token: eof_spanned_token(), max_witness_index: 0 }; parser.token = parser.read_token_internal()?; Ok(parser) } @@ -153,7 +154,8 @@ impl<'a> Parser<'a> { } pub(crate) fn parse_circuit(&mut self) -> ParseResult> { - let current_witness_index = self.parse_current_witness_index()?; + self.max_witness_index = 0; + let private_parameters = self.parse_private_parameters()?; let public_parameters = PublicInputs(self.parse_public_parameters()?); let return_values = PublicInputs(self.parse_return_values()?); @@ -161,7 +163,7 @@ impl<'a> Parser<'a> { let opcodes = self.parse_opcodes()?; Ok(Circuit { - current_witness_index, + current_witness_index: self.max_witness_index, opcodes, private_parameters, public_parameters, @@ -170,14 +172,6 @@ impl<'a> Parser<'a> { }) } - fn parse_current_witness_index(&mut self) -> ParseResult { - self.eat_keyword_or_error(Keyword::Current)?; - self.eat_keyword_or_error(Keyword::Witness)?; - self.eat_or_error(Token::Colon)?; - - Ok(self.eat_witness_or_error()?.0) - } - fn parse_private_parameters(&mut self) -> ParseResult> { self.eat_keyword_or_error(Keyword::Private)?; self.eat_keyword_or_error(Keyword::Parameters)?; @@ -234,19 +228,22 @@ impl<'a> Parser<'a> { while let Some(keyword) = self.peek_keyword() { match keyword { - Keyword::Expression => { + Keyword::Assert => { let expr = self.parse_assert_zero_expression()?; opcodes.push(Opcode::AssertZero(expr)); } Keyword::BlackBoxFuncCall => { opcodes.push(Opcode::BlackBoxFuncCall(self.parse_blackbox_func_call()?)); } - Keyword::MemoryOp => { - opcodes.push(self.parse_memory_op()?); - } Keyword::MemoryInit => { opcodes.push(self.parse_memory_init()?); } + Keyword::MemoryRead => { + opcodes.push(self.parse_memory_read()?); + } + Keyword::MemoryWrite => { + opcodes.push(self.parse_memory_write()?); + } Keyword::Brillig => { opcodes.push(self.parse_brillig_call()?); } @@ -261,8 +258,8 @@ impl<'a> Parser<'a> { } fn parse_assert_zero_expression(&mut self) -> ParseResult> { - // 'EXPR' - self.eat_keyword_or_error(Keyword::Expression)?; + // 'CONSTRAIN' + self.eat_keyword_or_error(Keyword::Assert)?; // Parse the left-hand side terms let lhs_terms = self.parse_terms_or_error()?; @@ -369,60 +366,46 @@ impl<'a> Parser<'a> { let key = self.try_extract_tail::<16, _>(&mut inputs, "key")?; let iv = self.try_extract_tail::<16, _>(&mut inputs, "IV")?; - let outputs = self.parse_witness_vector()?; + let outputs = self.parse_blackbox_outputs()?; BlackBoxFuncCall::AES128Encrypt { inputs, iv, key, outputs } } BlackBoxFunc::AND => { let inputs = self.parse_blackbox_inputs()?; - let num_bits = self.parse_blackbox_bit_size()?; - let outputs = self.parse_witness_vector()?; - self.expect_len(&inputs, 2, "AND", false)?; - self.expect_len(&outputs, 1, "AND", true)?; - BlackBoxFuncCall::AND { - lhs: inputs[0], - rhs: inputs[1], - num_bits, - output: outputs[0], - } + let num_bits = self.parse_blackbox_bit_size()?; + let output = self.parse_blackbox_output()?; + + BlackBoxFuncCall::AND { lhs: inputs[0], rhs: inputs[1], num_bits, output } } BlackBoxFunc::XOR => { let inputs = self.parse_blackbox_inputs()?; - let num_bits = self.parse_blackbox_bit_size()?; - let outputs = self.parse_witness_vector()?; - self.expect_len(&inputs, 2, "XOR", false)?; - self.expect_len(&outputs, 1, "XOR", true)?; - BlackBoxFuncCall::XOR { - lhs: inputs[0], - rhs: inputs[1], - num_bits, - output: outputs[0], - } + let num_bits = self.parse_blackbox_bit_size()?; + let output = self.parse_blackbox_output()?; + + BlackBoxFuncCall::XOR { lhs: inputs[0], rhs: inputs[1], num_bits, output } } BlackBoxFunc::RANGE => { - let inputs = self.parse_blackbox_inputs()?; + self.eat_keyword_or_error(Keyword::Input)?; + self.eat_or_error(Token::Colon)?; + let input = self.parse_blackbox_input()?; let num_bits = self.parse_blackbox_bit_size()?; - let outputs = self.parse_witness_vector()?; - - self.expect_len(&inputs, 1, "RANGE", false)?; - self.expect_len(&outputs, 0, "RANGE", true)?; - BlackBoxFuncCall::RANGE { input: inputs[0], num_bits } + BlackBoxFuncCall::RANGE { input, num_bits } } BlackBoxFunc::Blake2s => { let inputs = self.parse_blackbox_inputs()?; - let outputs = self.parse_witness_vector()?; + let outputs = self.parse_blackbox_outputs()?; let outputs = self.try_vec_to_array::<32, _>(outputs, "Blake2s", true)?; BlackBoxFuncCall::Blake2s { inputs, outputs } } BlackBoxFunc::Blake3 => { let inputs = self.parse_blackbox_inputs()?; - let outputs = self.parse_witness_vector()?; + let outputs = self.parse_blackbox_outputs()?; let outputs = self.try_vec_to_array::<32, _>(outputs, "Blake3", true)?; BlackBoxFuncCall::Blake3 { inputs, outputs } @@ -436,10 +419,7 @@ impl<'a> Parser<'a> { let signature = self.try_extract_tail::<64, _>(&mut inputs, "signature")?; let public_key_y = self.try_extract_tail::<32, _>(&mut inputs, "public_key_y")?; let public_key_x = self.try_extract_tail::<32, _>(&mut inputs, "public_key_x")?; - - let outputs = self.parse_witness_vector()?; - self.expect_len(&outputs, 1, "EcdsaSecp256k1", true)?; - let output = outputs[0]; + let output = self.parse_blackbox_output()?; BlackBoxFuncCall::EcdsaSecp256k1 { public_key_x, @@ -459,10 +439,7 @@ impl<'a> Parser<'a> { let signature = self.try_extract_tail::<64, _>(&mut inputs, "signature")?; let public_key_y = self.try_extract_tail::<32, _>(&mut inputs, "public_key_y")?; let public_key_x = self.try_extract_tail::<32, _>(&mut inputs, "public_key_x")?; - - let outputs = self.parse_witness_vector()?; - self.expect_len(&outputs, 1, "EcdsaSecp256r1", true)?; - let output = outputs[0]; + let output = self.parse_blackbox_output()?; BlackBoxFuncCall::EcdsaSecp256r1 { public_key_x, @@ -477,7 +454,7 @@ impl<'a> Parser<'a> { BlackBoxFunc::Keccakf1600 => { let inputs = self.parse_blackbox_inputs()?; let inputs = self.try_vec_to_array::<25, _>(inputs, "Keccakf1600 inputs", false)?; - let outputs = self.parse_witness_vector()?; + let outputs = self.parse_blackbox_outputs()?; let outputs = self.try_vec_to_array::<25, _>(outputs, "Keccakf1600 outputs", true)?; @@ -491,7 +468,7 @@ impl<'a> Parser<'a> { let predicate = self.try_extract_tail::<1, _>(&mut inputs, "predicate")?[0]; let input2 = self.try_extract_tail::<3, _>(&mut inputs, "EC add input2")?; let input1 = self.try_extract_tail::<3, _>(&mut inputs, "EC add input1")?; - let outputs = self.parse_witness_vector()?; + let outputs = self.parse_blackbox_outputs()?; self.expect_len(&outputs, 3, "EmbeddedCurveAdd", true)?; BlackBoxFuncCall::EmbeddedCurveAdd { @@ -503,9 +480,7 @@ impl<'a> Parser<'a> { } BlackBoxFunc::Poseidon2Permutation => { let inputs = self.parse_blackbox_inputs()?; - - let outputs = self.parse_witness_vector()?; - + let outputs = self.parse_blackbox_outputs()?; BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs } } BlackBoxFunc::Sha256Compression => { @@ -514,7 +489,7 @@ impl<'a> Parser<'a> { let hash_values = self.try_extract_tail::<8, _>(&mut inputs, "hash_values")?; let inputs = self.try_extract_tail::<16, _>(&mut inputs, "inputs")?; - let outputs = self.parse_witness_vector()?; + let outputs = self.parse_blackbox_outputs()?; let outputs = self.try_vec_to_array::<8, _>(outputs, "Sha256Compression outputs", true)?; @@ -525,31 +500,14 @@ impl<'a> Parser<'a> { } fn parse_blackbox_inputs(&mut self) -> ParseResult>> { + self.eat_keyword_or_error(Keyword::Inputs)?; + self.eat_or_error(Token::Colon)?; self.eat_or_error(Token::LeftBracket)?; let mut inputs = Vec::new(); while !self.eat(Token::RightBracket)? { - let input = match self.token.token() { - Token::Int(value) => { - let value = *value; - self.bump()?; - FunctionInput::Constant(value) - } - Token::Witness(index) => { - let witness = *index; - self.bump()?; - FunctionInput::Witness(Witness(witness)) - } - other => { - return Err(ParserError::ExpectedOneOfTokens { - tokens: vec![Token::Int(FieldElement::zero()), Token::Witness(0)], - found: other.clone(), - span: self.token.span(), - }); - } - }; - + let input = self.parse_blackbox_input()?; inputs.push(input); // Eat a comma if there is another input, but do not error if there is no comma @@ -560,59 +518,50 @@ impl<'a> Parser<'a> { Ok(inputs) } - fn parse_blackbox_bit_size(&mut self) -> ParseResult { - self.eat_or_error(Token::Colon)?; - let num_bits = self.eat_u32_or_error()?; - self.eat_expected_ident("bits")?; - Ok(num_bits) + fn parse_blackbox_input(&mut self) -> Result, ParserError> { + Ok(match self.token.token() { + Token::Int(value) => { + let value = *value; + self.bump()?; + FunctionInput::Constant(value) + } + Token::Witness(index) => { + let witness = *index; + self.bump()?; + FunctionInput::Witness(Witness(witness)) + } + other => { + return Err(ParserError::ExpectedOneOfTokens { + tokens: vec![Token::Int(FieldElement::zero()), Token::Witness(0)], + found: other.clone(), + span: self.token.span(), + }); + } + }) } - fn parse_memory_op(&mut self) -> ParseResult> { - self.eat_keyword_or_error(Keyword::MemoryOp)?; - - // Parse `id: ` - self.eat_expected_ident("id")?; - self.eat_or_error(Token::Colon)?; - let block_id = self.eat_u32_or_error()?; + fn parse_blackbox_output(&mut self) -> ParseResult { self.eat_or_error(Token::Comma)?; + self.eat_keyword_or_error(Keyword::Output)?; + self.eat_or_error(Token::Colon)?; + let witness = self.eat_witness_or_error()?; + Ok(witness) + } - // Next token: read/write/op - let op_token = self.eat_ident_or_error()?; - - let (operation, index, value) = match op_token.as_str() { - "read" => { - // read at: - self.eat_expected_ident("at")?; - self.eat_or_error(Token::Colon)?; - let index = self.parse_arithmetic_expression()?; - - // value will be parsed next after comma - self.eat_or_error(Token::Comma)?; - self.eat_keyword_or_error(Keyword::Value)?; - self.eat_or_error(Token::Colon)?; - let value = self.parse_arithmetic_expression()?; - - (Expression::zero(), index, value) - } - "write" => { - // write: at: - self.eat_or_error(Token::Colon)?; - let value = self.parse_arithmetic_expression()?; - self.eat_expected_ident("at")?; - self.eat_or_error(Token::Colon)?; - let index = self.parse_arithmetic_expression()?; + fn parse_blackbox_outputs(&mut self) -> ParseResult> { + self.eat_or_error(Token::Comma)?; + self.eat_keyword_or_error(Keyword::Outputs)?; + self.eat_or_error(Token::Colon)?; + self.parse_witness_vector() + } - (Expression::one(), index, value) - } - _ => { - return self.expected_one_of_tokens(&[ - Token::Ident("read".into()), - Token::Ident("write".into()), - ]); - } - }; + fn parse_blackbox_bit_size(&mut self) -> ParseResult { + self.eat_or_error(Token::Comma)?; + self.eat_keyword_or_error(Keyword::Bits)?; + self.eat_or_error(Token::Colon)?; + let num_bits = self.eat_u32_or_error()?; - Ok(Opcode::MemoryOp { block_id: BlockId(block_id), op: MemOp { index, value, operation } }) + Ok(num_bits) } fn parse_memory_init(&mut self) -> ParseResult> { @@ -630,52 +579,65 @@ impl<'a> Parser<'a> { _ => BlockType::Memory, }; - // Parse `id: ` - self.eat_expected_ident("id")?; - self.eat_or_error(Token::Colon)?; - let block_id = BlockId(self.eat_u32_or_error()?); - self.eat_or_error(Token::Comma)?; + // blockId = [witness1, witness2, ...] + let block_id = self.eat_block_id_or_error()?; + self.eat_or_error(Token::Equal)?; + let init = self.parse_witness_vector()?; - // Parse `len: ` - self.eat_expected_ident("len")?; - self.eat_or_error(Token::Colon)?; - let len = self.eat_u32_or_error()?; - self.eat_or_error(Token::Comma)?; + Ok(Opcode::MemoryInit { block_id, init, block_type }) + } - // Parse `witnesses: [_0, _1, ...]` - self.eat_expected_ident("witnesses")?; - self.eat_or_error(Token::Colon)?; - let init = self.parse_witness_vector()?; + fn parse_memory_read(&mut self) -> ParseResult> { + self.eat_keyword_or_error(Keyword::MemoryRead)?; - if init.len() != len as usize { - return Err(ParserError::InitLengthMismatch { - expected: len as usize, - found: init.len(), - span: self.token.span(), - }); - } + // value = blockId[index] + let value = self.parse_arithmetic_expression()?; + self.eat_or_error(Token::Equal)?; + let block_id = self.eat_block_id_or_error()?; + self.eat_or_error(Token::LeftBracket)?; + let index = self.parse_arithmetic_expression()?; + self.eat_or_error(Token::RightBracket)?; - Ok(Opcode::MemoryInit { block_id, init, block_type }) + let operation = Expression::zero(); + + Ok(Opcode::MemoryOp { block_id, op: MemOp { index, value, operation } }) + } + + fn parse_memory_write(&mut self) -> ParseResult> { + self.eat_keyword_or_error(Keyword::MemoryWrite)?; + + // blockId[index] = value + let block_id = self.eat_block_id_or_error()?; + self.eat_or_error(Token::LeftBracket)?; + let index = self.parse_arithmetic_expression()?; + self.eat_or_error(Token::RightBracket)?; + self.eat_or_error(Token::Equal)?; + let value = self.parse_arithmetic_expression()?; + + let operation = Expression::one(); + + Ok(Opcode::MemoryOp { block_id, op: MemOp { index, value, operation } }) } fn parse_brillig_call(&mut self) -> ParseResult> { self.eat_keyword_or_error(Keyword::Brillig)?; self.eat_keyword_or_error(Keyword::Call)?; self.eat_keyword_or_error(Keyword::Function)?; - let func_id = self.eat_u32_or_error()?; self.eat_or_error(Token::Colon)?; + let func_id = self.eat_u32_or_error()?; + self.eat_or_error(Token::Comma)?; let predicate = self.eat_predicate()?; // Parse inputs - self.eat_expected_ident("inputs")?; + self.eat_keyword_or_error(Keyword::Inputs)?; self.eat_or_error(Token::Colon)?; let inputs = self.parse_brillig_inputs()?; self.eat_or_error(Token::Comma)?; // between inputs and outputs // Parse outputs - self.eat_expected_ident("outputs")?; + self.eat_keyword_or_error(Keyword::Outputs)?; self.eat_or_error(Token::Colon)?; let outputs = self.parse_brillig_outputs()?; @@ -749,16 +711,17 @@ impl<'a> Parser<'a> { fn parse_call(&mut self) -> ParseResult> { self.eat_keyword_or_error(Keyword::Call)?; self.eat_keyword_or_error(Keyword::Function)?; - let id = self.eat_u32_or_error()?; self.eat_or_error(Token::Colon)?; + let id = self.eat_u32_or_error()?; + self.eat_or_error(Token::Comma)?; let predicate = self.eat_predicate()?; - self.eat_expected_ident("inputs")?; + self.eat_keyword_or_error(Keyword::Inputs)?; self.eat_or_error(Token::Colon)?; let inputs = self.parse_witness_vector()?; self.eat_or_error(Token::Comma)?; - self.eat_expected_ident("outputs")?; + self.eat_keyword_or_error(Keyword::Outputs)?; self.eat_or_error(Token::Colon)?; let outputs = self.parse_witness_vector()?; @@ -769,6 +732,7 @@ impl<'a> Parser<'a> { let mut predicate = None; if self.eat_keyword(Keyword::Predicate)? && self.eat(Token::Colon)? { let expr = self.parse_arithmetic_expression()?; + self.eat_or_error(Token::Comma)?; predicate = Some(expr); } Ok(predicate) @@ -794,14 +758,6 @@ impl<'a> Parser<'a> { } } - fn eat_expected_ident(&mut self, expected: &str) -> ParseResult<()> { - let label = self.eat_ident_or_error()?; - if label != expected { - self.expected_token(Token::Ident(expected.to_string()))?; - } - Ok(()) - } - fn eat_field_element(&mut self) -> ParseResult> { if let Token::Int(_) = self.token.token() { let token = self.bump()?; @@ -870,7 +826,12 @@ impl<'a> Parser<'a> { if is_witness_type { let token = self.bump()?; match token.into_token() { - Token::Witness(witness) => Ok(Some(Witness(witness))), + Token::Witness(witness) => { + if witness > self.max_witness_index { + self.max_witness_index = witness; + } + Ok(Some(Witness(witness))) + } _ => unreachable!(), } } else { @@ -882,6 +843,23 @@ impl<'a> Parser<'a> { if let Some(int) = self.eat_witness()? { Ok(int) } else { self.expected_witness() } } + fn eat_block_id(&mut self) -> ParseResult> { + let is_block_type = matches!(self.token.token(), Token::Block(_)); + if is_block_type { + let token = self.bump()?; + match token.into_token() { + Token::Block(block) => Ok(Some(BlockId(block))), + _ => unreachable!(), + } + } else { + Ok(None) + } + } + + fn eat_block_id_or_error(&mut self) -> ParseResult { + if let Some(int) = self.eat_block_id()? { Ok(int) } else { self.expected_block_id() } + } + fn eat_or_error(&mut self, token: Token) -> ParseResult<()> { if self.eat(token.clone())? { Ok(()) } else { self.expected_token(token) } } @@ -995,6 +973,13 @@ impl<'a> Parser<'a> { }) } + fn expected_block_id(&mut self) -> ParseResult { + Err(ParserError::ExpectedBlockId { + found: self.token.token().clone(), + span: self.token.span(), + }) + } + fn expected_term(&mut self) -> ParseResult { Err(ParserError::ExpectedTerm { found: self.token.token().clone(), @@ -1077,6 +1062,8 @@ pub(crate) enum ParserError { ExpectedFieldElement { found: Token, span: Span }, #[error("Expected a witness index, found '{found}'")] ExpectedWitness { found: Token, span: Span }, + #[error("Expected a block ID, found '{found}'")] + ExpectedBlockId { found: Token, span: Span }, #[error("Expected a term, found '{found}'")] ExpectedTerm { found: Token, span: Span }, #[error("Expected valid black box function name, found '{found}'")] @@ -1087,8 +1074,6 @@ pub(crate) enum ParserError { IncorrectInputLength { expected: usize, found: usize, name: String, span: Span }, #[error("Expected {expected} outputs for {name}, found {found}")] IncorrectOutputLength { expected: usize, found: usize, name: String, span: Span }, - #[error("Expected {expected} witnesses for INIT, found {found}")] - InitLengthMismatch { expected: usize, found: usize, span: Span }, #[error("Expected function id {expected}, found {found}")] UnexpectedFunctionId { expected: u32, found: u32, span: Span }, } @@ -1103,12 +1088,12 @@ impl ParserError { | ExpectedIdentifier { span, .. } | ExpectedFieldElement { span, .. } | ExpectedWitness { span, .. } + | ExpectedBlockId { span, .. } | ExpectedTerm { span, .. } | ExpectedBlackBoxFuncName { span, .. } | IntegerLargerThanU32 { span, .. } | IncorrectInputLength { span, .. } | IncorrectOutputLength { span, .. } - | InitLengthMismatch { span, .. } | UnexpectedFunctionId { span, .. } => *span, } } diff --git a/acvm-repo/acir/src/parser/tests.rs b/acvm-repo/acir/src/parser/tests.rs index f0f00f30032..080425680ab 100644 --- a/acvm-repo/acir/src/parser/tests.rs +++ b/acvm-repo/acir/src/parser/tests.rs @@ -53,21 +53,9 @@ fn assert_program_roundtrip(src: &str) { } } -#[test] -fn current_witness() { - let src = " - current witness: w1 - private parameters: [] - public parameters: [] - return values: [] - "; - assert_circuit_roundtrip(src); -} - #[test] fn private_parameters() { let src = " - current witness: w4 private parameters: [w0, w1, w2, w3, w4] public parameters: [] return values: [] @@ -78,7 +66,6 @@ fn private_parameters() { #[test] fn public_parameters() { let src = " - current witness: w9 private parameters: [w0, w1, w2, w3, w4] public parameters: [w5, w6, w7, w8, w9] return values: [] @@ -89,7 +76,6 @@ fn public_parameters() { #[test] fn return_values() { let src = " - current witness: w12 private parameters: [w0, w1, w2, w3, w4] public parameters: [w5, w6, w7, w8, w9] return values: [w10, w11, w12] @@ -97,18 +83,28 @@ fn return_values() { assert_circuit_roundtrip(src); } +#[test] +fn computes_current_witness() { + let src = " + private parameters: [w0, w1] + public parameters: [w3] + return values: [w2] + "; + let circuit = Circuit::from_str(src).unwrap(); + assert_eq!(circuit.current_witness_index, 3); +} + #[test] fn assert_zero_opcodes() { let src = " - current witness: w9 private parameters: [w0, w1, w2, w3, w4] public parameters: [w5, w6, w7, w8, w9] return values: [] - EXPR w5 = w0 - EXPR w6 = w1 - EXPR w7 = w2 - EXPR w8 = w3 - EXPR w9 = w4 + ASSERT w5 = w0 + ASSERT w6 = w1 + ASSERT w7 = w2 + ASSERT w8 = w3 + ASSERT w9 = w4 "; assert_circuit_roundtrip(src); } @@ -116,15 +112,14 @@ fn assert_zero_opcodes() { #[test] fn assert_zero_with_mul_terms() { let src = " - current witness: w6 private parameters: [w0, w1, w2] public parameters: [] return values: [] - EXPR w3 = w0*w1 - EXPR w4 = w3*w3 - EXPR w5 = w4*w4 - EXPR w6 = w5*w5 - EXPR w6 = w2 + ASSERT w3 = w0*w1 + ASSERT w4 = w3*w3 + ASSERT w5 = w4*w4 + ASSERT w6 = w5*w5 + ASSERT w6 = w2 "; assert_circuit_roundtrip(src); } @@ -132,11 +127,10 @@ fn assert_zero_with_mul_terms() { #[test] fn range_check() { let src = " - current witness: w5 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w0]:32 bits [] + BLACKBOX::RANGE input: w0, bits: 32 "; assert_circuit_roundtrip(src); } @@ -144,14 +138,13 @@ fn range_check() { #[test] fn xor() { let src = " - current witness: w2 private parameters: [w0] public parameters: [w1] return values: [] - BLACKBOX::RANGE [w0]:32 bits [] - BLACKBOX::RANGE [w1]:32 bits [] - BLACKBOX::XOR [w0, w1]:32 bits [w2] - EXPR w2 = 15 + BLACKBOX::RANGE input: w0, bits: 32 + BLACKBOX::RANGE input: w1, bits: 32 + BLACKBOX::XOR inputs: [w0, w1], bits: 32, output: w2 + ASSERT w2 = 15 "; assert_circuit_roundtrip(src); } @@ -160,87 +153,86 @@ fn xor() { fn aes128_encrypt() { // This ACIR represents an accurately constrained aes128 encryption in ACIR let src = " - current witness: w75 private parameters: [w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24, w25, w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36, w37, w38, w39, w40, w41, w42, w43] public parameters: [w44, w45, w46, w47, w48, w49, w50, w51, w52, w53, w54, w55, w56, w57, w58, w59] return values: [] - BLACKBOX::RANGE [w0]:8 bits [] - BLACKBOX::RANGE [w1]:8 bits [] - BLACKBOX::RANGE [w2]:8 bits [] - BLACKBOX::RANGE [w3]:8 bits [] - BLACKBOX::RANGE [w4]:8 bits [] - BLACKBOX::RANGE [w5]:8 bits [] - BLACKBOX::RANGE [w6]:8 bits [] - BLACKBOX::RANGE [w7]:8 bits [] - BLACKBOX::RANGE [w8]:8 bits [] - BLACKBOX::RANGE [w9]:8 bits [] - BLACKBOX::RANGE [w10]:8 bits [] - BLACKBOX::RANGE [w11]:8 bits [] - BLACKBOX::RANGE [w12]:8 bits [] - BLACKBOX::RANGE [w13]:8 bits [] - BLACKBOX::RANGE [w14]:8 bits [] - BLACKBOX::RANGE [w15]:8 bits [] - BLACKBOX::RANGE [w16]:8 bits [] - BLACKBOX::RANGE [w17]:8 bits [] - BLACKBOX::RANGE [w18]:8 bits [] - BLACKBOX::RANGE [w19]:8 bits [] - BLACKBOX::RANGE [w20]:8 bits [] - BLACKBOX::RANGE [w21]:8 bits [] - BLACKBOX::RANGE [w22]:8 bits [] - BLACKBOX::RANGE [w23]:8 bits [] - BLACKBOX::RANGE [w24]:8 bits [] - BLACKBOX::RANGE [w25]:8 bits [] - BLACKBOX::RANGE [w26]:8 bits [] - BLACKBOX::RANGE [w27]:8 bits [] - BLACKBOX::RANGE [w28]:8 bits [] - BLACKBOX::RANGE [w29]:8 bits [] - BLACKBOX::RANGE [w30]:8 bits [] - BLACKBOX::RANGE [w31]:8 bits [] - BLACKBOX::RANGE [w32]:8 bits [] - BLACKBOX::RANGE [w33]:8 bits [] - BLACKBOX::RANGE [w34]:8 bits [] - BLACKBOX::RANGE [w35]:8 bits [] - BLACKBOX::RANGE [w36]:8 bits [] - BLACKBOX::RANGE [w37]:8 bits [] - BLACKBOX::RANGE [w38]:8 bits [] - BLACKBOX::RANGE [w39]:8 bits [] - BLACKBOX::RANGE [w40]:8 bits [] - BLACKBOX::RANGE [w41]:8 bits [] - BLACKBOX::RANGE [w42]:8 bits [] - BLACKBOX::RANGE [w43]:8 bits [] - BLACKBOX::RANGE [w44]:8 bits [] - BLACKBOX::RANGE [w45]:8 bits [] - BLACKBOX::RANGE [w46]:8 bits [] - BLACKBOX::RANGE [w47]:8 bits [] - BLACKBOX::RANGE [w48]:8 bits [] - BLACKBOX::RANGE [w49]:8 bits [] - BLACKBOX::RANGE [w50]:8 bits [] - BLACKBOX::RANGE [w51]:8 bits [] - BLACKBOX::RANGE [w52]:8 bits [] - BLACKBOX::RANGE [w53]:8 bits [] - BLACKBOX::RANGE [w54]:8 bits [] - BLACKBOX::RANGE [w55]:8 bits [] - BLACKBOX::RANGE [w56]:8 bits [] - BLACKBOX::RANGE [w57]:8 bits [] - BLACKBOX::RANGE [w58]:8 bits [] - BLACKBOX::RANGE [w59]:8 bits [] - BLACKBOX::AES128_ENCRYPT [w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24, w25, w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36, w37, w38, w39, w40, w41, w42, w43] [w60, w61, w62, w63, w64, w65, w66, w67, w68, w69, w70, w71, w72, w73, w74, w75] - EXPR w60 = w44 - EXPR w61 = w45 - EXPR w62 = w46 - EXPR w63 = w47 - EXPR w64 = w48 - EXPR w65 = w49 - EXPR w66 = w50 - EXPR w67 = w51 - EXPR w68 = w52 - EXPR w69 = w53 - EXPR w70 = w54 - EXPR w71 = w55 - EXPR w72 = w56 - EXPR w73 = w57 - EXPR w74 = w58 - EXPR w75 = w59 + BLACKBOX::RANGE input: w0, bits: 8 + BLACKBOX::RANGE input: w1, bits: 8 + BLACKBOX::RANGE input: w2, bits: 8 + BLACKBOX::RANGE input: w3, bits: 8 + BLACKBOX::RANGE input: w4, bits: 8 + BLACKBOX::RANGE input: w5, bits: 8 + BLACKBOX::RANGE input: w6, bits: 8 + BLACKBOX::RANGE input: w7, bits: 8 + BLACKBOX::RANGE input: w8, bits: 8 + BLACKBOX::RANGE input: w9, bits: 8 + BLACKBOX::RANGE input: w10, bits: 8 + BLACKBOX::RANGE input: w11, bits: 8 + BLACKBOX::RANGE input: w12, bits: 8 + BLACKBOX::RANGE input: w13, bits: 8 + BLACKBOX::RANGE input: w14, bits: 8 + BLACKBOX::RANGE input: w15, bits: 8 + BLACKBOX::RANGE input: w16, bits: 8 + BLACKBOX::RANGE input: w17, bits: 8 + BLACKBOX::RANGE input: w18, bits: 8 + BLACKBOX::RANGE input: w19, bits: 8 + BLACKBOX::RANGE input: w20, bits: 8 + BLACKBOX::RANGE input: w21, bits: 8 + BLACKBOX::RANGE input: w22, bits: 8 + BLACKBOX::RANGE input: w23, bits: 8 + BLACKBOX::RANGE input: w24, bits: 8 + BLACKBOX::RANGE input: w25, bits: 8 + BLACKBOX::RANGE input: w26, bits: 8 + BLACKBOX::RANGE input: w27, bits: 8 + BLACKBOX::RANGE input: w28, bits: 8 + BLACKBOX::RANGE input: w29, bits: 8 + BLACKBOX::RANGE input: w30, bits: 8 + BLACKBOX::RANGE input: w31, bits: 8 + BLACKBOX::RANGE input: w32, bits: 8 + BLACKBOX::RANGE input: w33, bits: 8 + BLACKBOX::RANGE input: w34, bits: 8 + BLACKBOX::RANGE input: w35, bits: 8 + BLACKBOX::RANGE input: w36, bits: 8 + BLACKBOX::RANGE input: w37, bits: 8 + BLACKBOX::RANGE input: w38, bits: 8 + BLACKBOX::RANGE input: w39, bits: 8 + BLACKBOX::RANGE input: w40, bits: 8 + BLACKBOX::RANGE input: w41, bits: 8 + BLACKBOX::RANGE input: w42, bits: 8 + BLACKBOX::RANGE input: w43, bits: 8 + BLACKBOX::RANGE input: w44, bits: 8 + BLACKBOX::RANGE input: w45, bits: 8 + BLACKBOX::RANGE input: w46, bits: 8 + BLACKBOX::RANGE input: w47, bits: 8 + BLACKBOX::RANGE input: w48, bits: 8 + BLACKBOX::RANGE input: w49, bits: 8 + BLACKBOX::RANGE input: w50, bits: 8 + BLACKBOX::RANGE input: w51, bits: 8 + BLACKBOX::RANGE input: w52, bits: 8 + BLACKBOX::RANGE input: w53, bits: 8 + BLACKBOX::RANGE input: w54, bits: 8 + BLACKBOX::RANGE input: w55, bits: 8 + BLACKBOX::RANGE input: w56, bits: 8 + BLACKBOX::RANGE input: w57, bits: 8 + BLACKBOX::RANGE input: w58, bits: 8 + BLACKBOX::RANGE input: w59, bits: 8 + BLACKBOX::AES128_ENCRYPT inputs: [w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24, w25, w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36, w37, w38, w39, w40, w41, w42, w43], outputs: [w60, w61, w62, w63, w64, w65, w66, w67, w68, w69, w70, w71, w72, w73, w74, w75] + ASSERT w60 = w44 + ASSERT w61 = w45 + ASSERT w62 = w46 + ASSERT w63 = w47 + ASSERT w64 = w48 + ASSERT w65 = w49 + ASSERT w66 = w50 + ASSERT w67 = w51 + ASSERT w68 = w52 + ASSERT w69 = w53 + ASSERT w70 = w54 + ASSERT w71 = w55 + ASSERT w72 = w56 + ASSERT w73 = w57 + ASSERT w74 = w58 + ASSERT w75 = w59 "; assert_circuit_roundtrip(src); } @@ -248,11 +240,10 @@ fn aes128_encrypt() { #[test] fn blake2s() { let src = " - current witness: w68 private parameters: [w0, w1, w2, w3, w4] public parameters: [w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24, w25, w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36] return values: [] - BLACKBOX::BLAKE2S [w0, w1, w2, w3, w4] [w37, w38, w39, w40, w41, w42, w43, w44, w45, w46, w47, w48, w49, w50, w51, w52, w53, w54, w55, w56, w57, w58, w59, w60, w61, w62, w63, w64, w65, w66, w67, w68] + BLACKBOX::BLAKE2S inputs: [w0, w1, w2, w3, w4], outputs: [w37, w38, w39, w40, w41, w42, w43, w44, w45, w46, w47, w48, w49, w50, w51, w52, w53, w54, w55, w56, w57, w58, w59, w60, w61, w62, w63, w64, w65, w66, w67, w68] "; assert_circuit_roundtrip(src); } @@ -260,11 +251,10 @@ fn blake2s() { #[test] fn blake3() { let src = " - current witness: w37 private parameters: [w0, w1, w2, w3, w4] public parameters: [] return values: [] - BLACKBOX::BLAKE3 [w0, w1, w2, w3, w4] [w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24, w25, w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36] + BLACKBOX::BLAKE3 inputs: [w0, w1, w2, w3, w4], outputs: [w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24, w25, w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36] "; assert_circuit_roundtrip(src); } @@ -276,11 +266,10 @@ fn ecdsa_secp256k1() { let src = format!( " - current witness: w161 private parameters: [] public parameters: [] return values: [] - BLACKBOX::ECDSA_SECP256K1 [{inputs_str}] [w161] + BLACKBOX::ECDSA_SECP256K1 inputs: [{inputs_str}], output: w161 " ); assert_circuit_roundtrip(&src); @@ -294,11 +283,10 @@ fn ecdsa_secp256k1_missing_inputs() { let src = format!( " - current witness: w100 private parameters: [] public parameters: [] return values: [] - BLACKBOX::ECDSA_SECP256K1 [{inputs_str}] [w100] + BLACKBOX::ECDSA_SECP256K1 inputs: [{inputs_str}], output: w100 " ); let _ = Circuit::from_str(&src).unwrap(); @@ -311,11 +299,10 @@ fn ecdsa_secp256r1() { let src = format!( " - current witness: w161 private parameters: [] public parameters: [] return values: [] - BLACKBOX::ECDSA_SECP256R1 [{inputs_str}] [w161] + BLACKBOX::ECDSA_SECP256R1 inputs: [{inputs_str}], output: w161 " ); assert_circuit_roundtrip(&src); @@ -329,11 +316,10 @@ fn ecdsa_secp256r1_missing_inputs() { let src = format!( " - current witness: w100 private parameters: [] public parameters: [] return values: [] - BLACKBOX::ECDSA_SECP256R1 [{inputs_str}] [w100] + BLACKBOX::ECDSA_SECP256R1 inputs: [{inputs_str}], outputs: [w100] " ); let _ = Circuit::from_str(&src).unwrap(); @@ -349,11 +335,10 @@ fn keccakf1600() { let src = format!( " - current witness: w50 private parameters: [] public parameters: [] return values: [] - BLACKBOX::KECCAKF1600 [{inputs_str}] [{outputs_str}] + BLACKBOX::KECCAKF1600 inputs: [{inputs_str}], outputs: [{outputs_str}] " ); assert_circuit_roundtrip(&src); @@ -370,11 +355,10 @@ fn keccakf1600_missing_inputs() { let src = format!( " - current witness: w49 private parameters: [] public parameters: [] return values: [] - BLACKBOX::KECCAKF1600 [{inputs_str}] [{outputs_str}] + BLACKBOX::KECCAKF1600 inputs: [{inputs_str}], outputs: [{outputs_str}] " ); let _ = Circuit::from_str(&src).unwrap(); @@ -383,11 +367,10 @@ fn keccakf1600_missing_inputs() { #[test] fn embedded_curve_add() { let src = " - current witness: w9 private parameters: [] public parameters: [] return values: [] - BLACKBOX::EMBEDDED_CURVE_ADD [w0, w1, w2, w3, w4, w5, w6] [w7, w8, w9] + BLACKBOX::EMBEDDED_CURVE_ADD inputs: [w0, w1, w2, w3, w4, w5, w6], outputs: [w7, w8, w9] "; assert_circuit_roundtrip(src); } @@ -396,11 +379,10 @@ fn embedded_curve_add() { #[should_panic] fn embedded_curve_add_wrong_output_count() { let src = " - current witness: w9 private parameters: [] public parameters: [] return values: [] - BLACKBOX::EMBEDDED_CURVE_ADD [w0, w1, w2, w3, w4, w5, w6] [w7, w8] + BLACKBOX::EMBEDDED_CURVE_ADD inputs: [w0, w1, w2, w3, w4, w5, w6], outputs: [w7, w8] "; let _ = Circuit::from_str(src).unwrap(); } @@ -408,11 +390,10 @@ fn embedded_curve_add_wrong_output_count() { #[test] fn poseidon2_permutation() { let src = " - current witness: w5 private parameters: [] public parameters: [] return values: [] - BLACKBOX::POSEIDON2_PERMUTATION [w0, w1, w2] [w3, w4, w5] + BLACKBOX::POSEIDON2_PERMUTATION inputs: [w0, w1, w2], outputs: [w3, w4, w5] "; assert_circuit_roundtrip(src); } @@ -427,11 +408,10 @@ fn sha256_compression() { let src = format!( " - current witness: w31 private parameters: [] public parameters: [] return values: [] - BLACKBOX::SHA256_COMPRESSION [{inputs_str}] [{outputs_str}] + BLACKBOX::SHA256_COMPRESSION inputs: [{inputs_str}], outputs: [{outputs_str}] " ); assert_circuit_roundtrip(&src); @@ -448,11 +428,10 @@ fn sha256_compression_missing_outputs() { let src = format!( " - current witness: w31 private parameters: [] public parameters: [] return values: [] - BLACKBOX::SHA256_COMPRESSION [{inputs_str}] [{outputs_str}] + BLACKBOX::SHA256_COMPRESSION inputs: [{inputs_str}], outputs: [{outputs_str}] " ); let _ = Circuit::from_str(&src).unwrap(); @@ -461,11 +440,10 @@ fn sha256_compression_missing_outputs() { #[test] fn memory_read() { let src = " - current witness: w1 private parameters: [] public parameters: [] return values: [] - MEM id: 0, read at: w0, value: w1 + READ w1 = b0[w0] "; assert_circuit_roundtrip(src); } @@ -473,11 +451,10 @@ fn memory_read() { #[test] fn memory_write() { let src = " - current witness: w1 private parameters: [] public parameters: [] return values: [] - MEM id: 3, write: w0 at: w1 + WRITE b3[w1] = w0 "; assert_circuit_roundtrip(src); } @@ -485,11 +462,10 @@ fn memory_write() { #[test] fn memory_init() { let src = " - current witness: w4 private parameters: [] public parameters: [] return values: [] - INIT id: 4, len: 5, witnesses: [w0, w1, w2, w3, w4] + INIT b4 = [w0, w1, w2, w3, w4] "; assert_circuit_roundtrip(src); } @@ -497,11 +473,10 @@ fn memory_init() { #[test] fn memory_init_duplicate_witness() { let src = " - current witness: w4 private parameters: [] public parameters: [] return values: [] - INIT id: 4, len: 2, witnesses: [w0, w0] + INIT b4 = [w0, w0] "; assert_circuit_roundtrip(src); } @@ -509,12 +484,11 @@ fn memory_init_duplicate_witness() { #[test] fn memory_databus() { let src = " - current witness: w5 private parameters: [w0, w1, w2, w3, w4, w5] public parameters: [] return values: [] - INIT CALLDATA 0 id: 1, len: 5, witnesses: [w1, w2, w3, w4, w5] - INIT RETURNDATA id: 2, len: 1, witnesses: [w6] + INIT CALLDATA 0 b1 = [w1, w2, w3, w4, w5] + INIT RETURNDATA b2 = [w6] "; assert_circuit_roundtrip(src); } @@ -522,13 +496,12 @@ fn memory_databus() { #[test] fn brillig_call() { let src = " - current witness: w2 private parameters: [w0, w1, w2] public parameters: [] return values: [] - BRILLIG CALL func 0: inputs: [w0 - w1], outputs: [w3] - EXPR 0 = w0*w3 - w1*w3 - 1 - EXPR w2 = w0 + BRILLIG CALL func: 0, inputs: [w0 - w1], outputs: [w3] + ASSERT 0 = w0*w3 - w1*w3 - 1 + ASSERT w2 = w0 "; assert_circuit_roundtrip(src); } @@ -536,14 +509,12 @@ fn brillig_call() { #[test] fn brillig_call_with_predicate() { let src = " - current witness: w2 private parameters: [w0, w1, w2] public parameters: [] return values: [] - BRILLIG CALL func 0: PREDICATE: 1 - inputs: [w0 - w1], outputs: [w3] - EXPR 0 = w0*w3 - w1*w3 - 1 - EXPR w2 = w0 + BRILLIG CALL func: 0, predicate: 1, inputs: [w0 - w1], outputs: [w3] + ASSERT 0 = w0*w3 - w1*w3 - 1 + ASSERT w2 = w0 "; assert_circuit_roundtrip(src); } @@ -551,11 +522,10 @@ fn brillig_call_with_predicate() { #[test] fn brillig_call_with_memory_array_input() { let src = " - current witness: w2 private parameters: [w0, w1, w2] public parameters: [] return values: [] - BRILLIG CALL func 0: inputs: [2, MemoryArray(0)], outputs: [] + BRILLIG CALL func: 0, inputs: [2, MemoryArray(0)], outputs: [] "; assert_circuit_roundtrip(src); } @@ -563,11 +533,10 @@ fn brillig_call_with_memory_array_input() { #[test] fn call() { let src = " - current witness: w2 private parameters: [w0] public parameters: [w1] return values: [] - CALL func 1: inputs: [w0, w1], outputs: [w2] + CALL func: 1, inputs: [w0, w1], outputs: [w2] "; assert_circuit_roundtrip(src); } @@ -575,12 +544,10 @@ fn call() { #[test] fn call_with_predicate() { let src = " - current witness: w2 private parameters: [w0] public parameters: [w1] return values: [] - CALL func 1: PREDICATE: 1 - inputs: [w0, w1], outputs: [w2] + CALL func: 1, predicate: 1, inputs: [w0, w1], outputs: [w2] "; assert_circuit_roundtrip(src); } @@ -589,117 +556,120 @@ fn call_with_predicate() { #[test] fn array_dynamic() { let src = " - current witness: w78 private parameters: [w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, w16, w17, w18] public parameters: [] return values: [] - BLACKBOX::RANGE [w0]:32 bits [] - BLACKBOX::RANGE [w1]:32 bits [] - BLACKBOX::RANGE [w2]:32 bits [] - BLACKBOX::RANGE [w3]:32 bits [] - BLACKBOX::RANGE [w4]:32 bits [] - INIT id: 0, len: 5, witnesses: [w0, w1, w2, w3, w4] - BLACKBOX::RANGE [w5]:32 bits [] - BLACKBOX::RANGE [w6]:32 bits [] - INIT id: 1, len: 5, witnesses: [w7, w8, w9, w10, w11] - BLACKBOX::RANGE [w12]:32 bits [] - BLACKBOX::RANGE [w13]:32 bits [] - BLACKBOX::RANGE [w14]:32 bits [] - BLACKBOX::RANGE [w15]:32 bits [] - BLACKBOX::RANGE [w16]:32 bits [] - BLACKBOX::RANGE [w17]:32 bits [] - EXPR w19 = 5*w6 - BLACKBOX::RANGE [w19]:32 bits [] - EXPR w20 = w5 - w19 - BLACKBOX::RANGE [w20]:32 bits [] - EXPR w21 = w20 - 5 - EXPR w22 = w21 - 3 - MEM id: 0, read at: w21, value: w23 - EXPR w23 = 111 - MEM id: 0, read at: w22, value: w24 - EXPR w24 = 101 - BRILLIG CALL func 0: inputs: [w22 + 4294967291, 4294967296], outputs: [w25, w26] - BLACKBOX::RANGE [w26]:32 bits [] - EXPR w26 = w22 - 4294967296*w25 + 4294967291 - EXPR w25 = 0 - EXPR w27 = 0 - MEM id: 0, write: w27 at: w22 - MEM id: 0, read at: w21, value: w28 - EXPR w28 = 111 - EXPR w29 = 1 - MEM id: 0, read at: w29, value: w30 - EXPR w30 = 0 - BRILLIG CALL func 0: inputs: [w21 + 4294967286, 4294967296], outputs: [w31, w32] - BLACKBOX::RANGE [w31]:1 bits [] - BLACKBOX::RANGE [w32]:32 bits [] - EXPR w32 = w21 - 4294967296*w31 + 4294967286 - EXPR w33 = -w21*w31 + w21 - MEM id: 0, read at: w33, value: w34 - EXPR w35 = -w31*w34 + 2*w31 + w34 - 2 - BLACKBOX::RANGE [w35]:32 bits [] - BRILLIG CALL func 0: inputs: [w21 + 4294967291, 4294967296], outputs: [w36, w37] - BLACKBOX::RANGE [w36]:1 bits [] - BLACKBOX::RANGE [w37]:32 bits [] - EXPR w37 = w21 - 4294967296*w36 + 4294967291 - EXPR w36 = w31*w36 - EXPR w38 = -w21*w31 + w21 - MEM id: 0, read at: w38, value: w39 - MEM id: 0, read at: w27, value: w40 - MEM id: 0, read at: w29, value: w41 - EXPR w42 = 2 - MEM id: 0, read at: w42, value: w43 - EXPR w44 = 3 - MEM id: 0, read at: w44, value: w45 - EXPR w46 = 0 - MEM id: 0, read at: w46, value: w47 - INIT id: 3, len: 5, witnesses: [w40, w41, w43, w45, w47] - EXPR w48 = -w31*w35 + w31*w39 + w35 - MEM id: 3, write: w48 at: w38 - MEM id: 3, read at: w46, value: w49 - MEM id: 0, read at: w46, value: w50 - EXPR 0 = -w31*w36 - EXPR w51 = w21*w31 - MEM id: 0, read at: w51, value: w52 - EXPR w53 = -w31*w52 + w52 - MEM id: 0, write: w53 at: w51 - MEM id: 0, read at: w46, value: w54 - EXPR w55 = -w31 + 1 - EXPR w56 = -w31*w49 + w31*w50 + w49 - EXPR 0 = w31*w54 + w55*w56 - 109 - EXPR w57 = 246 - EXPR w58 = 159 - EXPR w59 = 32 - EXPR w60 = 176 - EXPR w61 = 8 - INIT id: 4, len: 5, witnesses: [w57, w58, w59, w60, w61] - MEM id: 4, read at: w7, value: w62 - MEM id: 4, read at: w8, value: w63 - MEM id: 4, read at: w9, value: w64 - MEM id: 4, read at: w10, value: w65 - MEM id: 4, read at: w11, value: w66 - BRILLIG CALL func 1: inputs: [w62 + w63 + w64 + w65 + w66], outputs: [w67] - EXPR 0 = w62*w67 + w63*w67 + w64*w67 + w65*w67 + w66*w67 - 1 - BRILLIG CALL func 0: inputs: [w18, 4294967296], outputs: [w68, w69] - BLACKBOX::RANGE [w68]:222 bits [] - BLACKBOX::RANGE [w69]:32 bits [] - EXPR w69 = w18 - 4294967296*w68 - EXPR w70 = -w68 + 5096253676302562286669017222071363378443840053029366383258766538131 - BLACKBOX::RANGE [w70]:222 bits [] - BRILLIG CALL func 1: inputs: [-w68 + 5096253676302562286669017222071363378443840053029366383258766538131], outputs: [w71] - EXPR w72 = w68*w71 - 5096253676302562286669017222071363378443840053029366383258766538131*w71 + 1 - EXPR 0 = -w68*w72 + 5096253676302562286669017222071363378443840053029366383258766538131*w72 - EXPR w73 = w69*w72 + 268435455*w72 - BLACKBOX::RANGE [w73]:32 bits [] - BRILLIG CALL func 0: inputs: [-w69 + 4294967299, 4294967296], outputs: [w74, w75] - BLACKBOX::RANGE [w74]:1 bits [] - BLACKBOX::RANGE [w75]:32 bits [] - EXPR w75 = -w69 - 4294967296*w74 + 4294967299 - EXPR w76 = -w17*w74 + w17 - 3*w74 + 3 - BLACKBOX::RANGE [w76]:32 bits [] - EXPR w77 = -w74*w76 + w76 - MEM id: 1, read at: w77, value: w78 - EXPR w78 = -w15*w74 + w74*w78 + w15 + BLACKBOX::RANGE input: w0, bits: 32 + BLACKBOX::RANGE input: w1, bits: 32 + BLACKBOX::RANGE input: w2, bits: 32 + BLACKBOX::RANGE input: w3, bits: 32 + BLACKBOX::RANGE input: w4, bits: 32 + INIT b0 = [w0, w1, w2, w3, w4] + BLACKBOX::RANGE input: w5, bits: 32 + BLACKBOX::RANGE input: w6, bits: 32 + INIT b1 = [w7, w8, w9, w10, w11] + BLACKBOX::RANGE input: w12, bits: 32 + BLACKBOX::RANGE input: w13, bits: 32 + BLACKBOX::RANGE input: w14, bits: 32 + BLACKBOX::RANGE input: w15, bits: 32 + BLACKBOX::RANGE input: w16, bits: 32 + BLACKBOX::RANGE input: w17, bits: 32 + ASSERT w19 = 5*w6 + BLACKBOX::RANGE input: w19, bits: 32 + ASSERT w20 = w5 - w19 + BLACKBOX::RANGE input: w20, bits: 32 + ASSERT w21 = w20 - 5 + ASSERT w22 = w21 - 3 + READ w23 = b0[w21] + ASSERT w23 = 111 + READ w24 = b0[w22] + ASSERT w24 = 101 + BRILLIG CALL func: 0, inputs: [w22 + 4294967291, 4294967296], outputs: [w25, w26] + BLACKBOX::RANGE input: w26, bits: 32 + ASSERT w26 = w22 - 4294967296*w25 + 4294967291 + ASSERT w25 = 0 + ASSERT w27 = 0 + WRITE b0[w22] = w27 + READ w28 = b0[w21] + ASSERT w28 = 111 + ASSERT w29 = 1 + READ w30 = b0[w29] + ASSERT w30 = 0 + BRILLIG CALL func: 0, inputs: [w21 + 4294967286, 4294967296], outputs: [w31, w32] + BLACKBOX::RANGE input: w31, bits: 1 + BLACKBOX::RANGE input: w32, bits: 32 + ASSERT w32 = w21 - 4294967296*w31 + 4294967286 + ASSERT w33 = -w21*w31 + w21 + READ w34 = b0[w33] + ASSERT w35 = -w31*w34 + 2*w31 + w34 - 2 + BLACKBOX::RANGE input: w35, bits: 32 + BRILLIG CALL func: 0, inputs: [w21 + 4294967291, 4294967296], outputs: [w36, w37] + BLACKBOX::RANGE input: w36, bits: 1 + BLACKBOX::RANGE input: w37, bits: 32 + ASSERT w37 = w21 - 4294967296*w36 + 4294967291 + ASSERT w36 = w31*w36 + ASSERT w38 = -w21*w31 + w21 + READ w39 = b0[w38] + READ w40 = b0[w27] + READ w41 = b0[w29] + ASSERT w42 = 2 + READ w43 = b0[w42] + ASSERT w44 = 3 + READ w45 = b0[w44] + ASSERT w46 = 0 + READ w47 = b0[w46] + INIT b3 = [w40, w41, w43, w45, w47] + ASSERT w48 = -w31*w35 + w31*w39 + w35 + WRITE b3[w38] = w48 + READ w49 = b3[w46] + READ w50 = b0[w46] + ASSERT 0 = -w31*w36 + ASSERT w51 = w21*w31 + READ w52 = b0[w51] + ASSERT w53 = -w31*w52 + w52 + WRITE b0[w51] = w53 + READ w54 = b0[w46] + ASSERT w55 = -w31 + 1 + ASSERT w56 = -w31*w49 + w31*w50 + w49 + ASSERT 0 = w31*w54 + w55*w56 - 109 + ASSERT w57 = 246 + ASSERT w58 = 159 + ASSERT w59 = 32 + ASSERT w60 = 176 + ASSERT w61 = 8 + INIT b4 = [w57, w58, w59, w60, w61] + READ w62 = b4[w7] + READ w63 = b4[w8] + READ w64 = b4[w9] + READ w65 = b4[w10] + READ w999 = b4[w11] + BRILLIG CALL func: 1, inputs: [w62 + w63 + w64 + w65 + w999], outputs: [w67] + ASSERT 0 = w62*w67 + w63*w67 + w64*w67 + w65*w67 + w999*w67 - 1 + BRILLIG CALL func: 0, inputs: [w18, 4294967296], outputs: [w68, w69] + BLACKBOX::RANGE input: w68, bits: 222 + BLACKBOX::RANGE input: w69, bits: 32 + ASSERT w69 = w18 - 4294967296*w68 + ASSERT w70 = -w68 + 5096253676302562286669017222071363378443840053029366383258766538131 + BLACKBOX::RANGE input: w70, bits: 222 + BRILLIG CALL func: 1, inputs: [-w68 + 5096253676302562286669017222071363378443840053029366383258766538131], outputs: [w71] + ASSERT w72 = w68*w71 - 5096253676302562286669017222071363378443840053029366383258766538131*w71 + 1 + ASSERT 0 = -w68*w72 + 5096253676302562286669017222071363378443840053029366383258766538131*w72 + ASSERT w73 = w69*w72 + 268435455*w72 + BLACKBOX::RANGE input: w73, bits: 32 + BRILLIG CALL func: 0, inputs: [-w69 + 4294967299, 4294967296], outputs: [w74, w75] + BLACKBOX::RANGE input: w74, bits: 1 + BLACKBOX::RANGE input: w75, bits: 32 + ASSERT w75 = -w69 - 4294967296*w74 + 4294967299 + ASSERT w76 = -w17*w74 + w17 - 3*w74 + 3 + BLACKBOX::RANGE input: w76, bits: 32 + ASSERT w77 = -w74*w76 + w76 + READ w78 = b1[w77] + ASSERT w78 = -w15*w74 + w74*w78 + w15 "; + + let circuit = Circuit::from_str(src).unwrap(); + assert_eq!(circuit.current_witness_index, 999); + assert_circuit_roundtrip(src); } @@ -707,21 +677,18 @@ fn array_dynamic() { fn fold_basic() { let src = " func 0 - current witness: w2 private parameters: [w0] public parameters: [w1] return values: [] - CALL func 1: PREDICATE: 1 - inputs: [w0, w1], outputs: [w2] + CALL func: 1, predicate: 1, inputs: [w0, w1], outputs: [w2] func 1 - current witness: w3 private parameters: [w0, w1] public parameters: [] return values: [w2] - BRILLIG CALL func 0: inputs: [w0 - w1], outputs: [w3] - EXPR 0 = w0*w3 - w1*w3 - 1 - EXPR w2 = w0 + BRILLIG CALL func: 0, inputs: [w0 - w1], outputs: [w3] + ASSERT 0 = w0*w3 - w1*w3 - 1 + ASSERT w2 = w0 "; assert_program_roundtrip(src); } @@ -730,21 +697,18 @@ fn fold_basic() { fn fold_basic_mismatched_ids() { let src = " func 0 - current witness: w2 private parameters: [w0] public parameters: [w1] return values: [] - CALL func 1: PREDICATE: 1 - inputs: [w0, w1], outputs: [w2] + CALL func: 1, predicate: 1, inputs: [w0, w1], outputs: [w2] func 2 - current witness: w3 private parameters: [w0, w1] public parameters: [] return values: [w2] - BRILLIG CALL func 0: inputs: [w0 - w1], outputs: [w3] - EXPR w0*w3 - w1*w3 - 1 = 0 - EXPR w0 = w2 + BRILLIG CALL func: 0, inputs: [w0 - w1], outputs: [w3] + ASSERT w0*w3 - w1*w3 - 1 = 0 + ASSERT w0 = w2 "; let result = Program::from_str(src).err().unwrap(); let ParserError::UnexpectedFunctionId { expected, found, .. } = result.get_error() else { @@ -757,37 +721,33 @@ fn fold_basic_mismatched_ids() { #[test] fn assert_zero_equation() { let src = " - current witness: w9 private parameters: [w0, w1, w2, w2] public parameters: [] return values: [] - EXPR -w0 + w1 - 10 + 20 + w0*w2 = w2 - w3 + w0*w1 - w1*w2 - 30 + ASSERT -w0 + w1 - 10 + 20 + w0*w2 = w2 - w3 + w0*w1 - w1*w2 - 30 "; let circuit = Circuit::from_str(src).unwrap(); assert_snapshot!(circuit.to_string(), @r" - current witness: w9 private parameters: [w0, w1, w2] public parameters: [] return values: [] - EXPR w3 = -w0*w2 + w0*w1 - w1*w2 + w0 - w1 + w2 - 40 + ASSERT w3 = -w0*w2 + w0*w1 - w1*w2 + w0 - w1 + w2 - 40 "); } #[test] fn does_not_negate_when_equal_to_zero() { let src = " - current witness: w9 private parameters: [w0, w1, w2] public parameters: [] return values: [] - EXPR w0*w1 + w0*w2 = 0 + ASSERT w0*w1 + w0*w2 = 0 "; let circuit = Circuit::from_str(src).unwrap(); assert_snapshot!(circuit.to_string(), @r" - current witness: w9 private parameters: [w0, w1, w2] public parameters: [] return values: [] - EXPR 0 = w0*w1 + w0*w2 + ASSERT 0 = w0*w1 + w0*w2 "); } diff --git a/acvm-repo/acir/src/parser/token.rs b/acvm-repo/acir/src/parser/token.rs index 7cc805ac06c..a678fde3f6e 100644 --- a/acvm-repo/acir/src/parser/token.rs +++ b/acvm-repo/acir/src/parser/token.rs @@ -27,11 +27,13 @@ impl SpannedToken { pub(crate) enum Token { /// Identifier such as `RANGE`, `AND`, etc. Ident(String), - /// Reserved identifiers such as `EXPR`. + /// Reserved identifiers such as `CONSTRAIN`. /// Most words in ACIR's human readable are expected to be keywords Keyword(Keyword), - /// Witness index, like `_42` + /// Witness index, like `w42` Witness(u32), + /// Block index, like `b42` + Block(u32), /// Integer value represented using the underlying native field element Int(FieldElement), /// : @@ -74,7 +76,8 @@ impl std::fmt::Display for Token { match self { Token::Ident(ident) => write!(f, "{ident}"), Token::Keyword(keyword) => write!(f, "{keyword}"), - Token::Witness(index) => write!(f, "_{index}"), + Token::Witness(index) => write!(f, "w{index}"), + Token::Block(index) => write!(f, "b{index}"), Token::Int(int) => write!(f, "{int}"), Token::Colon => write!(f, ":"), Token::Semicolon => write!(f, ";"), @@ -95,10 +98,6 @@ impl std::fmt::Display for Token { /// ACIR human readable text format keywords #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub(crate) enum Keyword { - /// current - Current, - /// witness - Witness, /// private Private, /// parameters @@ -111,19 +110,21 @@ pub(crate) enum Keyword { Value, /// values Values, - /// EXPR - Expression, + /// ASSERT + Assert, /// BLACKBOX BlackBoxFuncCall, - /// MEM - MemoryOp, /// INIT MemoryInit, + /// READ + MemoryRead, + /// WRITE + MemoryWrite, /// BRILLIG Brillig, /// CALL Call, - /// PREDICATE + /// predicate Predicate, /// CALLDATA CallData, @@ -131,29 +132,43 @@ pub(crate) enum Keyword { ReturnData, /// func Function, + /// input + Input, + /// inputs + Inputs, + /// output + Output, + /// outputs + Outputs, + /// bits + Bits, } impl Keyword { pub(super) fn lookup_keyword(word: &str) -> Option { let keyword = match word { - "current" => Keyword::Current, - "witness" => Keyword::Witness, "private" => Keyword::Private, "parameters" => Keyword::Parameters, "public" => Keyword::Public, "return" => Keyword::Return, "value" => Keyword::Value, "values" => Keyword::Values, - "EXPR" => Keyword::Expression, + "ASSERT" => Keyword::Assert, "BLACKBOX" => Keyword::BlackBoxFuncCall, - "MEM" => Keyword::MemoryOp, "INIT" => Keyword::MemoryInit, + "READ" => Keyword::MemoryRead, + "WRITE" => Keyword::MemoryWrite, "BRILLIG" => Keyword::Brillig, "CALL" => Keyword::Call, - "PREDICATE" => Keyword::Predicate, + "predicate" => Keyword::Predicate, "CALLDATA" => Keyword::CallData, "RETURNDATA" => Keyword::ReturnData, "func" => Keyword::Function, + "input" => Keyword::Input, + "inputs" => Keyword::Inputs, + "output" => Keyword::Output, + "outputs" => Keyword::Outputs, + "bits" => Keyword::Bits, _ => return None, }; Some(Token::Keyword(keyword)) @@ -163,24 +178,28 @@ impl Keyword { impl std::fmt::Display for Keyword { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Keyword::Current => write!(f, "current"), - Keyword::Witness => write!(f, "witness"), Keyword::Private => write!(f, "private"), Keyword::Parameters => write!(f, "parameters"), Keyword::Public => write!(f, "public"), Keyword::Return => write!(f, "return"), Keyword::Value => write!(f, "value"), Keyword::Values => write!(f, "values"), - Keyword::Expression => write!(f, "EXPR"), + Keyword::Assert => write!(f, "ASSERT"), Keyword::BlackBoxFuncCall => write!(f, "BLACKBOX"), - Keyword::MemoryOp => write!(f, "MEM"), Keyword::MemoryInit => write!(f, "INIT"), + Keyword::MemoryRead => write!(f, "READ"), + Keyword::MemoryWrite => write!(f, "WRITE"), Keyword::Brillig => write!(f, "BRILLIG"), Keyword::Call => write!(f, "CALL"), - Keyword::Predicate => write!(f, "PREDICATE"), + Keyword::Predicate => write!(f, "predicate"), Keyword::CallData => write!(f, "CALLDATA"), Keyword::ReturnData => write!(f, "RETURNDATA"), Keyword::Function => write!(f, "func"), + Keyword::Input => write!(f, "input"), + Keyword::Inputs => write!(f, "inputs"), + Keyword::Output => write!(f, "output"), + Keyword::Outputs => write!(f, "outputs"), + Keyword::Bits => write!(f, "bits"), } } } diff --git a/acvm-repo/acvm/src/compiler/optimizers/general.rs b/acvm-repo/acvm/src/compiler/optimizers/general.rs index aaf0b8761c6..6d44123d994 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/general.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/general.rs @@ -93,130 +93,118 @@ mod tests { #[test] fn removes_zero_coefficients_from_mul_terms() { let src = " - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] // The first multiplication should be removed - EXPR 0*w0*w1 + w0*w1 = 0 + ASSERT 0*w0*w1 + w0*w1 = 0 "; let circuit = Circuit::from_str(src).unwrap(); let optimized_circuit = optimize(circuit); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR 0 = w0*w1 + ASSERT 0 = w0*w1 "); } #[test] fn removes_zero_coefficients_from_linear_terms() { let src = " - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] // The first linear combination should be removed - EXPR 0*w0 + w1 = 0 + ASSERT 0*w0 + w1 = 0 "; let circuit = Circuit::from_str(src).unwrap(); let optimized_circuit = optimize(circuit); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR w1 = 0 + ASSERT w1 = 0 "); } #[test] fn simplifies_mul_terms() { let src = " - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] // There are all mul terms with the same variables so we should end up with just one // that is the sum of all the coefficients - EXPR 2*w0*w1 + 3*w1*w0 + 4*w0*w1 = 0 + ASSERT 2*w0*w1 + 3*w1*w0 + 4*w0*w1 = 0 "; let circuit = Circuit::from_str(src).unwrap(); let optimized_circuit = optimize(circuit); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR 0 = 9*w0*w1 + ASSERT 0 = 9*w0*w1 "); } #[test] fn removes_zero_coefficients_after_simplifying_mul_terms() { let src = " - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR 2*w0*w1 + 3*w1*w0 - 5*w0*w1 = 0 + ASSERT 2*w0*w1 + 3*w1*w0 - 5*w0*w1 = 0 "; let circuit = Circuit::from_str(src).unwrap(); let optimized_circuit = optimize(circuit); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR 0 = 0 + ASSERT 0 = 0 "); } #[test] fn simplifies_linear_terms() { let src = " - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] // These are all linear terms with the same variable so we should end up with just one // that is the sum of all the coefficients - EXPR w0 + 2*w0 + 3*w0 = 0 + ASSERT w0 + 2*w0 + 3*w0 = 0 "; let circuit = Circuit::from_str(src).unwrap(); let optimized_circuit = optimize(circuit); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR 0 = 6*w0 + ASSERT 0 = 6*w0 "); } #[test] fn removes_zero_coefficients_after_simplifying_linear_terms() { let src = " - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR w0 + 2*w0 - 3*w0 = 0 + ASSERT w0 + 2*w0 - 3*w0 = 0 "; let circuit = Circuit::from_str(src).unwrap(); let optimized_circuit = optimize(circuit); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR 0 = 0 + ASSERT 0 = 0 "); } } diff --git a/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs b/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs index e7e278e8d92..7995ea2d7b4 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs @@ -302,13 +302,12 @@ mod tests { #[test] fn does_not_eliminate_witnesses_returned_from_brillig() { let src = " - current witness: w1 private parameters: [w0] public parameters: [] return values: [] - BRILLIG CALL func 0: inputs: [], outputs: [w1] - EXPR 2*w0 + 3*w1 + w2 + 1 = 0 - EXPR 2*w0 + 2*w1 + w5 + 1 = 0 + BRILLIG CALL func: 0, inputs: [], outputs: [w1] + ASSERT 2*w0 + 3*w1 + w2 + 1 = 0 + ASSERT 2*w0 + 2*w1 + w5 + 1 = 0 "; let circuit = Circuit::from_str(src).unwrap(); let optimized_circuit = merge_expressions(circuit.clone()); @@ -318,12 +317,11 @@ mod tests { #[test] fn does_not_eliminate_witnesses_returned_from_circuit() { let src = " - current witness: w2 private parameters: [w0] public parameters: [] return values: [w1, w2] - EXPR -w0*w0 + w1 = 0 - EXPR -w1 + w2 = 0 + ASSERT -w0*w0 + w1 = 0 + ASSERT -w1 + w2 = 0 "; let circuit = Circuit::from_str(src).unwrap(); let optimized_circuit = merge_expressions(circuit.clone()); @@ -333,27 +331,25 @@ mod tests { #[test] fn does_not_attempt_to_merge_into_previous_opcodes() { let src = " - current witness: w5 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR w0*w0 - w4 = 0 - EXPR w0*w1 + w5 = 0 - EXPR -w2 + w4 + w5 = 0 - EXPR w2 - w3 + w4 + w5 = 0 - BLACKBOX::RANGE [w3]:32 bits [] + ASSERT w0*w0 - w4 = 0 + ASSERT w0*w1 + w5 = 0 + ASSERT -w2 + w4 + w5 = 0 + ASSERT w2 - w3 + w4 + w5 = 0 + BLACKBOX::RANGE input: w3, bits: 32 "; let circuit = Circuit::from_str(src).unwrap(); let optimized_circuit = merge_expressions(circuit); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w5 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR w5 = -w0*w1 - EXPR w3 = 2*w0*w0 + 2*w5 - BLACKBOX::RANGE [w3]:32 bits [] + ASSERT w5 = -w0*w1 + ASSERT w3 = 2*w0*w0 + 2*w5 + BLACKBOX::RANGE input: w3, bits: 32 "); } @@ -364,14 +360,13 @@ mod tests { // We would then merge the final two opcodes losing the check that the brillig call must match // with `w0 ^ w1`. let src = " - current witness: w7 private parameters: [w0, w1] public parameters: [] return values: [w2] - BRILLIG CALL func 0: inputs: [], outputs: [w3] - BLACKBOX::AND [w0, w1]:8 bits [w4] - EXPR w3 - w4 = 0 - EXPR -w2 + w4 = 0 + BRILLIG CALL func: 0, inputs: [], outputs: [w3] + BLACKBOX::AND inputs: [w0, w1], bits: 8, output: w4 + ASSERT w3 - w4 = 0 + ASSERT -w2 + w4 = 0 "; let circuit = Circuit::from_str(src).unwrap(); let optimized_circuit = merge_expressions(circuit.clone()); diff --git a/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs b/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs index 01fe6dffc79..e37700c885c 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs @@ -285,12 +285,11 @@ mod tests { fn retain_lowest_range_size() { // The optimizer should keep the lowest bit size range constraint let src = " - current witness: w1 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:32 bits [] - BLACKBOX::RANGE [w1]:16 bits [] + BLACKBOX::RANGE input: w1, bits: 32 + BLACKBOX::RANGE input: w1, bits: 16 "; let circuit = Circuit::from_str(src).unwrap(); @@ -309,11 +308,10 @@ mod tests { let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:16 bits [] + BLACKBOX::RANGE input: w1, bits: 16 "); } @@ -321,14 +319,13 @@ mod tests { fn remove_duplicates() { // The optimizer should remove all duplicate range opcodes. let src = " - current witness: w1 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:16 bits [] - BLACKBOX::RANGE [w1]:16 bits [] - BLACKBOX::RANGE [w2]:23 bits [] - BLACKBOX::RANGE [w2]:23 bits [] + BLACKBOX::RANGE input: w1, bits: 16 + BLACKBOX::RANGE input: w1, bits: 16 + BLACKBOX::RANGE input: w2, bits: 23 + BLACKBOX::RANGE input: w2, bits: 23 "; let circuit = Circuit::from_str(src).unwrap(); @@ -337,12 +334,11 @@ mod tests { let optimizer = RangeOptimizer::new(circuit, &brillig_side_effects); let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:16 bits [] - BLACKBOX::RANGE [w2]:23 bits [] + BLACKBOX::RANGE input: w1, bits: 16 + BLACKBOX::RANGE input: w2, bits: 23 "); } @@ -351,16 +347,15 @@ mod tests { // The optimizer should not remove or change non-range opcodes // The four AssertZero opcodes should remain unchanged. let src = " - current witness: w1 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:16 bits [] - BLACKBOX::RANGE [w1]:16 bits [] - EXPR 0 = 0 - EXPR 0 = 0 - EXPR 0 = 0 - EXPR 0 = 0 + BLACKBOX::RANGE input: w1, bits: 16 + BLACKBOX::RANGE input: w1, bits: 16 + ASSERT 0 = 0 + ASSERT 0 = 0 + ASSERT 0 = 0 + ASSERT 0 = 0 "; let circuit = Circuit::from_str(src).unwrap(); @@ -369,15 +364,14 @@ mod tests { let optimizer = RangeOptimizer::new(circuit, &brillig_side_effects); let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:16 bits [] - EXPR 0 = 0 - EXPR 0 = 0 - EXPR 0 = 0 - EXPR 0 = 0 + BLACKBOX::RANGE input: w1, bits: 16 + ASSERT 0 = 0 + ASSERT 0 = 0 + ASSERT 0 = 0 + ASSERT 0 = 0 "); } @@ -385,12 +379,11 @@ mod tests { fn constant_implied_ranges() { // The optimizer should use knowledge about constant witness assignments to remove range opcodes. let src = " - current witness: w1 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:16 bits [] - EXPR w1 = 0 + BLACKBOX::RANGE input: w1, bits: 16 + ASSERT w1 = 0 "; let circuit = Circuit::from_str(src).unwrap(); @@ -399,11 +392,10 @@ mod tests { let optimizer = RangeOptimizer::new(circuit, &brillig_side_effects); let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [] public parameters: [] return values: [] - EXPR w1 = 0 + ASSERT w1 = 0 "); } @@ -411,24 +403,23 @@ mod tests { fn potential_side_effects() { // The optimizer should not remove range constraints if doing so might allow invalid side effects to go through. let src = " - current witness: w1 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:32 bits [] + BLACKBOX::RANGE input: w1, bits: 32 // Call brillig with w2 - BRILLIG CALL func 0: inputs: [w2], outputs: [] - BLACKBOX::RANGE [w1]:16 bits [] + BRILLIG CALL func: 0, inputs: [w2], outputs: [] + BLACKBOX::RANGE input: w1, bits: 16 // Another call - BRILLIG CALL func 0: inputs: [w2], outputs: [] + BRILLIG CALL func: 0, inputs: [w2], outputs: [] // One more constraint, but this is redundant. - BLACKBOX::RANGE [w1]:64 bits [] + BLACKBOX::RANGE input: w1, bits: 64 // assert w1 == 0 - EXPR w1 = 0 + ASSERT w1 = 0 "; let circuit = Circuit::from_str(src).unwrap(); @@ -444,15 +435,14 @@ mod tests { // `BLACKBOX::RANGE [w1]:32 bits []` remains: The minimum does not propagate backwards. assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:32 bits [] - BRILLIG CALL func 0: inputs: [w2], outputs: [] - BLACKBOX::RANGE [w1]:16 bits [] - BRILLIG CALL func 0: inputs: [w2], outputs: [] - EXPR w1 = 0 + BLACKBOX::RANGE input: w1, bits: 32 + BRILLIG CALL func: 0, inputs: [w2], outputs: [] + BLACKBOX::RANGE input: w1, bits: 16 + BRILLIG CALL func: 0, inputs: [w2], outputs: [] + ASSERT w1 = 0 "); // Applying again should have no effect (despite the range having the same bit size as the assert). @@ -466,13 +456,12 @@ mod tests { fn array_implied_ranges() { // The optimizer should use knowledge about array lengths and witnesses used to index these to remove range opcodes. let src = " - current witness: w1 private parameters: [] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:16 bits [] - INIT id: 0, len: 8, witnesses: [w0, w0, w0, w0, w0, w0, w0, w0] - MEM id: 0, read at: w1, value: w2 + BLACKBOX::RANGE input: w1, bits: 16 + INIT b0 = [w0, w0, w0, w0, w0, w0, w0, w0] + READ w2 = b0[w1] "; let circuit = Circuit::from_str(src).unwrap(); @@ -481,12 +470,11 @@ mod tests { let optimizer = RangeOptimizer::new(circuit, &brillig_side_effects); let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions); assert_circuit_snapshot!(optimized_circuit, @r" - current witness: w1 private parameters: [] public parameters: [] return values: [] - INIT id: 0, len: 8, witnesses: [w0, w0, w0, w0, w0, w0, w0, w0] - MEM id: 0, read at: w1, value: w2 + INIT b0 = [w0, w0, w0, w0, w0, w0, w0, w0] + READ w2 = b0[w1] "); } } diff --git a/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs b/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs index c332c64dc7d..490b54ef0c4 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs @@ -86,7 +86,6 @@ mod tests { #[test] fn unused_memory_is_removed() { let src = " - current witness: w3 private parameters: [w0, w1] public parameters: [] return values: [w2] @@ -119,7 +118,6 @@ mod tests { #[test] fn databus_is_not_removed() { let src = " - current witness: w3 private parameters: [w0, w1] public parameters: [] return values: [w2] diff --git a/compiler/noirc_evaluator/src/acir/tests/arrays.rs b/compiler/noirc_evaluator/src/acir/tests/arrays.rs index a261a92d243..24185e866a0 100644 --- a/compiler/noirc_evaluator/src/acir/tests/arrays.rs +++ b/compiler/noirc_evaluator/src/acir/tests/arrays.rs @@ -45,16 +45,15 @@ fn constant_array_access_out_of_bounds() { // This means memory checks will be laid down and array access OOB checks will be handled there. assert_circuit_snapshot!(program, @r" func 0 - current witness: w3 private parameters: [] public parameters: [] return values: [] - EXPR w0 = 0 - EXPR w1 = 1 - INIT id: 0, len: 2, witnesses: [w0, w1] - EXPR w2 = 5 - MEM id: 0, read at: w2, value: w3 - EXPR w3 = 0 + ASSERT w0 = 0 + ASSERT w1 = 1 + INIT b0 = [w0, w1] + ASSERT w2 = 5 + READ w3 = b0[w2] + ASSERT w3 = 0 "); } @@ -91,13 +90,12 @@ fn generates_memory_op_for_dynamic_read() { assert_circuit_snapshot!(program, @r" func 0 - current witness: w4 private parameters: [w0, w1, w2, w3] public parameters: [] return values: [] - INIT id: 0, len: 3, witnesses: [w0, w1, w2] - MEM id: 0, read at: w3, value: w4 - EXPR w4 = 10 + INIT b0 = [w0, w1, w2] + READ w4 = b0[w3] + ASSERT w4 = 10 "); } @@ -115,22 +113,21 @@ fn generates_memory_op_for_dynamic_write() { // All logic after the write is expected as we generate new witnesses for return values assert_circuit_snapshot!(program, @r" func 0 - current witness: w13 private parameters: [w0, w1, w2, w3] public parameters: [] return values: [w4, w5, w6] - INIT id: 1, len: 3, witnesses: [w0, w1, w2] - EXPR w7 = 10 - MEM id: 1, write: w7 at: w3 - EXPR w8 = 0 - MEM id: 1, read at: w8, value: w9 - EXPR w10 = 1 - MEM id: 1, read at: w10, value: w11 - EXPR w12 = 2 - MEM id: 1, read at: w12, value: w13 - EXPR w9 = w4 - EXPR w11 = w5 - EXPR w13 = w6 + INIT b1 = [w0, w1, w2] + ASSERT w7 = 10 + WRITE b1[w3] = w7 + ASSERT w8 = 0 + READ w9 = b1[w8] + ASSERT w10 = 1 + READ w11 = b1[w10] + ASSERT w12 = 2 + READ w13 = b1[w12] + ASSERT w9 = w4 + ASSERT w11 = w5 + ASSERT w13 = w6 "); } @@ -154,16 +151,15 @@ fn generates_predicated_index_for_dynamic_read() { // w5 is then used as the index which we use to read from the memory block assert_circuit_snapshot!(program, @r" func 0 - current witness: w6 private parameters: [w0, w1, w2, w3, w4] public parameters: [] return values: [] - INIT id: 0, len: 3, witnesses: [w0, w1, w2] - BLACKBOX::RANGE [w3]:32 bits [] - BLACKBOX::RANGE [w4]:1 bits [] - EXPR w5 = w3*w4 - MEM id: 0, read at: w5, value: w6 - EXPR w6 = 10 + INIT b0 = [w0, w1, w2] + BLACKBOX::RANGE input: w3, bits: 32 + BLACKBOX::RANGE input: w4, bits: 1 + ASSERT w5 = w3*w4 + READ w6 = b0[w5] + ASSERT w6 = 10 "); } @@ -185,34 +181,33 @@ fn generates_predicated_index_and_dummy_value_for_dynamic_write() { // The original value we want to write is `Field 10` and our predicate is `w4`. // We read the value at the predicated index into `w9`. This is our dummy value. // We can then see how we form our new store value with: - // `EXPR -w4*w9 + 10*w4 + w9 - w10 = 0` -> (predicate*value + (1-predicate)*dummy) + // `ASSERT -w4*w9 + 10*w4 + w9 - w10 = 0` -> (predicate*value + (1-predicate)*dummy) // `10*w4` -> predicate*value // `-w4*w9` -> (-predicate * dummy) // `w9` -> dummy // As expected, we then store `w10` at the predicated index `w8`. assert_circuit_snapshot!(program, @r" func 0 - current witness: w16 private parameters: [w0, w1, w2, w3, w4] public parameters: [] return values: [w5, w6, w7] - INIT id: 0, len: 3, witnesses: [w0, w1, w2] - BLACKBOX::RANGE [w3]:32 bits [] - BLACKBOX::RANGE [w4]:1 bits [] - EXPR w8 = w3*w4 - MEM id: 0, read at: w8, value: w9 - INIT id: 1, len: 3, witnesses: [w0, w1, w2] - EXPR w10 = -w4*w9 + 10*w4 + w9 - MEM id: 1, write: w10 at: w8 - EXPR w11 = 0 - MEM id: 1, read at: w11, value: w12 - EXPR w13 = 1 - MEM id: 1, read at: w13, value: w14 - EXPR w15 = 2 - MEM id: 1, read at: w15, value: w16 - EXPR w12 = w5 - EXPR w14 = w6 - EXPR w16 = w7 + INIT b0 = [w0, w1, w2] + BLACKBOX::RANGE input: w3, bits: 32 + BLACKBOX::RANGE input: w4, bits: 1 + ASSERT w8 = w3*w4 + READ w9 = b0[w8] + INIT b1 = [w0, w1, w2] + ASSERT w10 = -w4*w9 + 10*w4 + w9 + WRITE b1[w8] = w10 + ASSERT w11 = 0 + READ w12 = b1[w11] + ASSERT w13 = 1 + READ w14 = b1[w13] + ASSERT w15 = 2 + READ w16 = b1[w15] + ASSERT w12 = w5 + ASSERT w14 = w6 + ASSERT w16 = w7 "); } @@ -233,11 +228,10 @@ fn zero_length_array_constant() { // We expect ever expression to equal zero when executed. Thus, this circuit will always fail. assert_circuit_snapshot!(program, @r" func 0 - current witness: w0 private parameters: [] public parameters: [] return values: [] - EXPR 0 = 1 + ASSERT 0 = 1 "); } @@ -260,10 +254,9 @@ fn zero_length_array_dynamic_predicate() { // However, we must gate it by the predicate in case the branch is inactive. assert_circuit_snapshot!(program, @r" func 0 - current witness: w0 private parameters: [w0] public parameters: [] return values: [] - EXPR w0 = 0 + ASSERT w0 = 0 "); } diff --git a/compiler/noirc_evaluator/src/acir/tests/brillig_call.rs b/compiler/noirc_evaluator/src/acir/tests/brillig_call.rs index 2f6e8025e82..16455961761 100644 --- a/compiler/noirc_evaluator/src/acir/tests/brillig_call.rs +++ b/compiler/noirc_evaluator/src/acir/tests/brillig_call.rs @@ -41,16 +41,15 @@ fn multiple_brillig_calls_one_bytecode() { assert_circuit_snapshot!(program, @r" func 0 - current witness: w7 private parameters: [w0, w1] public parameters: [] return values: [] - BRILLIG CALL func 0: inputs: [w0, w1], outputs: [w2] - BRILLIG CALL func 0: inputs: [w0, w1], outputs: [w3] - BRILLIG CALL func 0: inputs: [w0, w1], outputs: [w4] - BRILLIG CALL func 1: inputs: [w0, w1], outputs: [w5] - BRILLIG CALL func 0: inputs: [w0, w1], outputs: [w6] - BRILLIG CALL func 1: inputs: [w0, w1], outputs: [w7] + BRILLIG CALL func: 0, inputs: [w0, w1], outputs: [w2] + BRILLIG CALL func: 0, inputs: [w0, w1], outputs: [w3] + BRILLIG CALL func: 0, inputs: [w0, w1], outputs: [w4] + BRILLIG CALL func: 1, inputs: [w0, w1], outputs: [w5] + BRILLIG CALL func: 0, inputs: [w0, w1], outputs: [w6] + BRILLIG CALL func: 1, inputs: [w0, w1], outputs: [w7] unconstrained func 0 0: @2 = const u32 1 @@ -145,30 +144,29 @@ fn multiple_brillig_stdlib_calls() { assert_circuit_snapshot!(program, @r" func 0 - current witness: w10 private parameters: [w0, w1, w2] public parameters: [] return values: [] - BLACKBOX::RANGE [w0]:32 bits [] - BLACKBOX::RANGE [w1]:32 bits [] - BLACKBOX::RANGE [w2]:32 bits [] - BRILLIG CALL func 0: inputs: [w1], outputs: [w3] - EXPR 0 = w1*w3 - 1 - BRILLIG CALL func 1: inputs: [w0, w1], outputs: [w4, w5] - BLACKBOX::RANGE [w4]:32 bits [] - BLACKBOX::RANGE [w5]:32 bits [] - EXPR w6 = w1 - w5 - 1 - BLACKBOX::RANGE [w6]:32 bits [] - EXPR w5 = -w1*w4 + w0 - EXPR w4 = w2 - BRILLIG CALL func 0: inputs: [w2], outputs: [w7] - EXPR 0 = w2*w7 - 1 - BRILLIG CALL func 1: inputs: [w1, w2], outputs: [w8, w9] - BLACKBOX::RANGE [w9]:32 bits [] - EXPR w10 = w2 - w9 - 1 - BLACKBOX::RANGE [w10]:32 bits [] - EXPR w9 = -w2*w8 + w1 - EXPR w8 = 1 + BLACKBOX::RANGE input: w0, bits: 32 + BLACKBOX::RANGE input: w1, bits: 32 + BLACKBOX::RANGE input: w2, bits: 32 + BRILLIG CALL func: 0, inputs: [w1], outputs: [w3] + ASSERT 0 = w1*w3 - 1 + BRILLIG CALL func: 1, inputs: [w0, w1], outputs: [w4, w5] + BLACKBOX::RANGE input: w4, bits: 32 + BLACKBOX::RANGE input: w5, bits: 32 + ASSERT w6 = w1 - w5 - 1 + BLACKBOX::RANGE input: w6, bits: 32 + ASSERT w5 = -w1*w4 + w0 + ASSERT w4 = w2 + BRILLIG CALL func: 0, inputs: [w2], outputs: [w7] + ASSERT 0 = w2*w7 - 1 + BRILLIG CALL func: 1, inputs: [w1, w2], outputs: [w8, w9] + BLACKBOX::RANGE input: w9, bits: 32 + ASSERT w10 = w2 - w9 - 1 + BLACKBOX::RANGE input: w10, bits: 32 + ASSERT w9 = -w2*w8 + w1 + ASSERT w8 = 1 unconstrained func 0 0: @21 = const u32 1 @@ -233,34 +231,33 @@ fn brillig_stdlib_calls_with_regular_brillig_call() { // Brillig stdlib IDs are expected to always come at the end of the Brillig functions list. assert_circuit_snapshot!(program, @r" func 0 - current witness: w12 private parameters: [w0, w1, w2] public parameters: [] return values: [] - BLACKBOX::RANGE [w0]:32 bits [] - BLACKBOX::RANGE [w1]:32 bits [] - BLACKBOX::RANGE [w2]:32 bits [] - BRILLIG CALL func 1: inputs: [w1], outputs: [w3] - EXPR 0 = w1*w3 - 1 - BRILLIG CALL func 2: inputs: [w0, w1], outputs: [w4, w5] - BLACKBOX::RANGE [w4]:32 bits [] - BLACKBOX::RANGE [w5]:32 bits [] - EXPR w6 = w1 - w5 - 1 - BLACKBOX::RANGE [w6]:32 bits [] - EXPR w5 = -w1*w4 + w0 - EXPR w4 = w2 - BRILLIG CALL func 0: inputs: [w0, w1], outputs: [w7] - BLACKBOX::RANGE [w7]:32 bits [] - BRILLIG CALL func 0: inputs: [w0, w1], outputs: [w8] - BLACKBOX::RANGE [w8]:32 bits [] - BRILLIG CALL func 1: inputs: [w2], outputs: [w9] - EXPR 0 = w2*w9 - 1 - BRILLIG CALL func 2: inputs: [w1, w2], outputs: [w10, w11] - BLACKBOX::RANGE [w11]:32 bits [] - EXPR w12 = w2 - w11 - 1 - BLACKBOX::RANGE [w12]:32 bits [] - EXPR w11 = -w2*w10 + w1 - EXPR w10 = 1 + BLACKBOX::RANGE input: w0, bits: 32 + BLACKBOX::RANGE input: w1, bits: 32 + BLACKBOX::RANGE input: w2, bits: 32 + BRILLIG CALL func: 1, inputs: [w1], outputs: [w3] + ASSERT 0 = w1*w3 - 1 + BRILLIG CALL func: 2, inputs: [w0, w1], outputs: [w4, w5] + BLACKBOX::RANGE input: w4, bits: 32 + BLACKBOX::RANGE input: w5, bits: 32 + ASSERT w6 = w1 - w5 - 1 + BLACKBOX::RANGE input: w6, bits: 32 + ASSERT w5 = -w1*w4 + w0 + ASSERT w4 = w2 + BRILLIG CALL func: 0, inputs: [w0, w1], outputs: [w7] + BLACKBOX::RANGE input: w7, bits: 32 + BRILLIG CALL func: 0, inputs: [w0, w1], outputs: [w8] + BLACKBOX::RANGE input: w8, bits: 32 + BRILLIG CALL func: 1, inputs: [w2], outputs: [w9] + ASSERT 0 = w2*w9 - 1 + BRILLIG CALL func: 2, inputs: [w1, w2], outputs: [w10, w11] + BLACKBOX::RANGE input: w11, bits: 32 + ASSERT w12 = w2 - w11 - 1 + BLACKBOX::RANGE input: w12, bits: 32 + ASSERT w11 = -w2*w10 + w1 + ASSERT w10 = 1 unconstrained func 0 0: @2 = const u32 1 @@ -364,53 +361,50 @@ fn brillig_stdlib_calls_with_multiple_acir_calls() { assert_eq!(foo_debug.brillig_locations.len(), 0); // TODO(https://github.com/noir-lang/noir/issues/9877): Update this snapshot once the linked issue is fixed. - // `CALL func 2` in `func 0` is incorrect. + // `CALL func: 2` in `func 0` is incorrect. assert_circuit_snapshot!(program, @r" func 0 - current witness: w13 private parameters: [w0, w1, w2] public parameters: [] return values: [] - BLACKBOX::RANGE [w0]:32 bits [] - BLACKBOX::RANGE [w1]:32 bits [] - BLACKBOX::RANGE [w2]:32 bits [] - BRILLIG CALL func 1: inputs: [w1], outputs: [w3] - EXPR 0 = w1*w3 - 1 - BRILLIG CALL func 2: inputs: [w0, w1], outputs: [w4, w5] - BLACKBOX::RANGE [w4]:32 bits [] - BLACKBOX::RANGE [w5]:32 bits [] - EXPR w6 = w1 - w5 - 1 - BLACKBOX::RANGE [w6]:32 bits [] - EXPR w5 = -w1*w4 + w0 - EXPR w4 = w2 - BRILLIG CALL func 0: inputs: [w0, w1], outputs: [w7] - BLACKBOX::RANGE [w7]:32 bits [] - BRILLIG CALL func 0: inputs: [w0, w1], outputs: [w8] - BLACKBOX::RANGE [w8]:32 bits [] - CALL func 1: PREDICATE: 1 - inputs: [w0, w1], outputs: [w9] - BRILLIG CALL func 1: inputs: [w2], outputs: [w10] - EXPR 0 = w2*w10 - 1 - BRILLIG CALL func 2: inputs: [w1, w2], outputs: [w11, w12] - BLACKBOX::RANGE [w12]:32 bits [] - EXPR w13 = w2 - w12 - 1 - BLACKBOX::RANGE [w13]:32 bits [] - EXPR w12 = -w2*w11 + w1 - EXPR w11 = 1 + BLACKBOX::RANGE input: w0, bits: 32 + BLACKBOX::RANGE input: w1, bits: 32 + BLACKBOX::RANGE input: w2, bits: 32 + BRILLIG CALL func: 1, inputs: [w1], outputs: [w3] + ASSERT 0 = w1*w3 - 1 + BRILLIG CALL func: 2, inputs: [w0, w1], outputs: [w4, w5] + BLACKBOX::RANGE input: w4, bits: 32 + BLACKBOX::RANGE input: w5, bits: 32 + ASSERT w6 = w1 - w5 - 1 + BLACKBOX::RANGE input: w6, bits: 32 + ASSERT w5 = -w1*w4 + w0 + ASSERT w4 = w2 + BRILLIG CALL func: 0, inputs: [w0, w1], outputs: [w7] + BLACKBOX::RANGE input: w7, bits: 32 + BRILLIG CALL func: 0, inputs: [w0, w1], outputs: [w8] + BLACKBOX::RANGE input: w8, bits: 32 + CALL func: 1, predicate: 1, inputs: [w0, w1], outputs: [w9] + BRILLIG CALL func: 1, inputs: [w2], outputs: [w10] + ASSERT 0 = w2*w10 - 1 + BRILLIG CALL func: 2, inputs: [w1, w2], outputs: [w11, w12] + BLACKBOX::RANGE input: w12, bits: 32 + ASSERT w13 = w2 - w12 - 1 + BLACKBOX::RANGE input: w13, bits: 32 + ASSERT w12 = -w2*w11 + w1 + ASSERT w11 = 1 func 1 - current witness: w5 private parameters: [w0, w1] public parameters: [] return values: [w2] - BLACKBOX::RANGE [w0]:32 bits [] - BLACKBOX::RANGE [w1]:32 bits [] - EXPR w3 = w0 - w1 - BRILLIG CALL func 1: inputs: [w3], outputs: [w4] - EXPR w5 = -w3*w4 + 1 - EXPR 0 = w3*w5 - EXPR w5 = 0 - EXPR w2 = w0 + BLACKBOX::RANGE input: w0, bits: 32 + BLACKBOX::RANGE input: w1, bits: 32 + ASSERT w3 = w0 - w1 + BRILLIG CALL func: 1, inputs: [w3], outputs: [w4] + ASSERT w5 = -w3*w4 + 1 + ASSERT 0 = w3*w5 + ASSERT w5 = 0 + ASSERT w2 = w0 unconstrained func 0 0: @2 = const u32 1 diff --git a/compiler/noirc_evaluator/src/acir/tests/call.rs b/compiler/noirc_evaluator/src/acir/tests/call.rs index 5ca29a82645..938cbd3c914 100644 --- a/compiler/noirc_evaluator/src/acir/tests/call.rs +++ b/compiler/noirc_evaluator/src/acir/tests/call.rs @@ -56,23 +56,19 @@ fn basic_call_with_outputs_assert(inline_type: InlineType) { let program = ssa_to_acir_program(src); assert_circuit_snapshot!(program, @r" func 0 - current witness: w3 private parameters: [w0, w1] public parameters: [] return values: [] - CALL func 1: PREDICATE: 1 - inputs: [w0, w1], outputs: [w2] - CALL func 1: PREDICATE: 1 - inputs: [w0, w1], outputs: [w3] - EXPR w3 = w2 + CALL func: 1, predicate: 1, inputs: [w0, w1], outputs: [w2] + CALL func: 1, predicate: 1, inputs: [w0, w1], outputs: [w3] + ASSERT w3 = w2 func 1 - current witness: w2 private parameters: [w0, w1] public parameters: [] return values: [w2] - EXPR w1 = w0 - EXPR w2 = w0 + ASSERT w1 = w0 + ASSERT w2 = w0 "); } @@ -99,23 +95,19 @@ fn call_output_as_next_call_input(inline_type: InlineType) { // the input witnesses of the `Call` opcodes will be different. The differences can discerned from the output below. assert_circuit_snapshot!(program, @r" func 0 - current witness: w3 private parameters: [w0, w1] public parameters: [] return values: [] - CALL func 1: PREDICATE: 1 - inputs: [w0, w1], outputs: [w2] - CALL func 1: PREDICATE: 1 - inputs: [w2, w1], outputs: [w3] - EXPR w3 = w2 + CALL func: 1, predicate: 1, inputs: [w0, w1], outputs: [w2] + CALL func: 1, predicate: 1, inputs: [w2, w1], outputs: [w3] + ASSERT w3 = w2 func 1 - current witness: w2 private parameters: [w0, w1] public parameters: [] return values: [w2] - EXPR w1 = w0 - EXPR w2 = w0 + ASSERT w1 = w0 + ASSERT w2 = w0 "); } @@ -146,32 +138,26 @@ fn basic_nested_call(inline_type: InlineType) { let program = ssa_to_acir_program(src); assert_circuit_snapshot!(program, @r" func 0 - current witness: w3 private parameters: [w0, w1] public parameters: [] return values: [] - CALL func 1: PREDICATE: 1 - inputs: [w0, w1], outputs: [w2] - CALL func 1: PREDICATE: 1 - inputs: [w0, w1], outputs: [w3] - EXPR w3 = w2 + CALL func: 1, predicate: 1, inputs: [w0, w1], outputs: [w2] + CALL func: 1, predicate: 1, inputs: [w0, w1], outputs: [w3] + ASSERT w3 = w2 func 1 - current witness: w4 private parameters: [w0, w1] public parameters: [] return values: [w2] - EXPR w3 = w0 + 2 - CALL func 2: PREDICATE: 1 - inputs: [w3, w1], outputs: [w4] - EXPR w4 = w2 + ASSERT w3 = w0 + 2 + CALL func: 2, predicate: 1, inputs: [w3, w1], outputs: [w4] + ASSERT w4 = w2 func 2 - current witness: w2 private parameters: [w0, w1] public parameters: [] return values: [w2] - EXPR w1 = w0 - EXPR w2 = w0 + ASSERT w1 = w0 + ASSERT w2 = w0 "); } diff --git a/compiler/noirc_evaluator/src/acir/tests/intrinsics.rs b/compiler/noirc_evaluator/src/acir/tests/intrinsics.rs index e06e5635712..768c30323e0 100644 --- a/compiler/noirc_evaluator/src/acir/tests/intrinsics.rs +++ b/compiler/noirc_evaluator/src/acir/tests/intrinsics.rs @@ -24,24 +24,23 @@ fn slice_push_back() { // Note that w9 is now at the end of memory block 3 and that w1 has been asserted to equal 3 assert_circuit_snapshot!(program, @r" func 0 - current witness: w10 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR w2 = 2 - EXPR w3 = 3 - INIT id: 1, len: 2, witnesses: [w2, w3] - EXPR w4 = 4 - MEM id: 1, write: w4 at: w0 - EXPR w5 = 0 - MEM id: 1, read at: w5, value: w6 - EXPR w7 = 1 - MEM id: 1, read at: w7, value: w8 - EXPR w9 = 10 - EXPR w1 = 3 - INIT id: 3, len: 3, witnesses: [w6, w8, w9] - EXPR w10 = 20 - MEM id: 3, write: w10 at: w0 + ASSERT w2 = 2 + ASSERT w3 = 3 + INIT b1 = [w2, w3] + ASSERT w4 = 4 + WRITE b1[w0] = w4 + ASSERT w5 = 0 + READ w6 = b1[w5] + ASSERT w7 = 1 + READ w8 = b1[w7] + ASSERT w9 = 10 + ASSERT w1 = 3 + INIT b3 = [w6, w8, w9] + ASSERT w10 = 20 + WRITE b3[w0] = w10 "); } @@ -65,24 +64,23 @@ fn slice_push_front() { // Note that w9 is now in the front of memory block 3 and that w1 has been asserted to equal 3 assert_circuit_snapshot!(program, @r" func 0 - current witness: w10 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR w2 = 2 - EXPR w3 = 3 - INIT id: 1, len: 2, witnesses: [w2, w3] - EXPR w4 = 4 - MEM id: 1, write: w4 at: w0 - EXPR w5 = 0 - MEM id: 1, read at: w5, value: w6 - EXPR w7 = 1 - MEM id: 1, read at: w7, value: w8 - EXPR w9 = 10 - EXPR w1 = 3 - INIT id: 3, len: 3, witnesses: [w9, w6, w8] - EXPR w10 = 20 - MEM id: 3, write: w10 at: w0 + ASSERT w2 = 2 + ASSERT w3 = 3 + INIT b1 = [w2, w3] + ASSERT w4 = 4 + WRITE b1[w0] = w4 + ASSERT w5 = 0 + READ w6 = b1[w5] + ASSERT w7 = 1 + READ w8 = b1[w7] + ASSERT w9 = 10 + ASSERT w1 = 3 + INIT b3 = [w9, w6, w8] + ASSERT w10 = 20 + WRITE b3[w0] = w10 "); } @@ -108,25 +106,24 @@ fn slice_pop_back() { // In practice, when writing to the slice we would assert that the index is less than w1 assert_circuit_snapshot!(program, @r" func 0 - current witness: w10 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR w2 = 2 - EXPR w3 = 3 - INIT id: 1, len: 2, witnesses: [w2, w3] - EXPR w4 = 4 - MEM id: 1, write: w4 at: w0 - EXPR w5 = 1 - MEM id: 1, read at: w5, value: w6 - EXPR w7 = 0 - MEM id: 1, read at: w7, value: w8 - MEM id: 1, read at: w5, value: w9 - EXPR w1 = 1 - EXPR w6 = 3 - INIT id: 3, len: 2, witnesses: [w8, w9] - EXPR w10 = 20 - MEM id: 3, write: w10 at: w0 + ASSERT w2 = 2 + ASSERT w3 = 3 + INIT b1 = [w2, w3] + ASSERT w4 = 4 + WRITE b1[w0] = w4 + ASSERT w5 = 1 + READ w6 = b1[w5] + ASSERT w7 = 0 + READ w8 = b1[w7] + READ w9 = b1[w5] + ASSERT w1 = 1 + ASSERT w6 = 3 + INIT b3 = [w8, w9] + ASSERT w10 = 20 + WRITE b3[w0] = w10 "); } @@ -150,25 +147,24 @@ fn slice_pop_front() { // In practice, when writing to the slice we would assert that the index is less than w1 assert_circuit_snapshot!(program, @r" func 0 - current witness: w10 private parameters: [w0, w1] public parameters: [] return values: [] - EXPR w2 = 2 - EXPR w3 = 3 - INIT id: 1, len: 2, witnesses: [w2, w3] - EXPR w4 = 4 - MEM id: 1, write: w4 at: w0 - EXPR w5 = 0 - MEM id: 1, read at: w5, value: w6 - EXPR w7 = 1 - MEM id: 1, read at: w7, value: w8 - MEM id: 1, read at: w5, value: w9 - EXPR w9 = 2 - EXPR w1 = 1 - INIT id: 3, len: 1, witnesses: [w8] - EXPR w10 = 20 - MEM id: 3, write: w10 at: w0 + ASSERT w2 = 2 + ASSERT w3 = 3 + INIT b1 = [w2, w3] + ASSERT w4 = 4 + WRITE b1[w0] = w4 + ASSERT w5 = 0 + READ w6 = b1[w5] + ASSERT w7 = 1 + READ w8 = b1[w7] + READ w9 = b1[w5] + ASSERT w9 = 2 + ASSERT w1 = 1 + INIT b3 = [w8] + ASSERT w10 = 20 + WRITE b3[w0] = w10 "); } @@ -196,66 +192,65 @@ fn slice_insert() { // The Brillig calls are to our stdlib quotient directive assert_circuit_snapshot!(program, @r" func 0 - current witness: w34 private parameters: [w0, w1] public parameters: [] return values: [] - BLACKBOX::RANGE [w1]:32 bits [] - EXPR w2 = 2 - EXPR w3 = 3 - EXPR w4 = 5 - INIT id: 1, len: 3, witnesses: [w2, w3, w4] - EXPR w5 = 4 - MEM id: 1, write: w5 at: w0 - EXPR w6 = 0 - INIT id: 2, len: 3, witnesses: [w6, w6, w6] - BRILLIG CALL func 0: inputs: [-w1 + 18446744073709551616, 18446744073709551616], outputs: [w7, w8] - BLACKBOX::RANGE [w7]:1 bits [] - BLACKBOX::RANGE [w8]:64 bits [] - EXPR w8 = -w1 - 18446744073709551616*w7 + 18446744073709551616 - BRILLIG CALL func 0: inputs: [-w1 + 18446744073709551615, 18446744073709551616], outputs: [w9, w10] - BLACKBOX::RANGE [w9]:1 bits [] - BLACKBOX::RANGE [w10]:64 bits [] - EXPR w10 = -w1 - 18446744073709551616*w9 + 18446744073709551615 - MEM id: 1, read at: w6, value: w11 - EXPR w12 = w7*w9 - w7 + 1 - EXPR w13 = -10*w7*w9 + w11*w12 + 10*w7 - MEM id: 2, write: w13 at: w6 - BRILLIG CALL func 0: inputs: [-w1 + 18446744073709551617, 18446744073709551616], outputs: [w14, w15] - BLACKBOX::RANGE [w14]:1 bits [] - BLACKBOX::RANGE [w15]:64 bits [] - EXPR w15 = -w1 - 18446744073709551616*w14 + 18446744073709551617 - BRILLIG CALL func 0: inputs: [-w1 + 18446744073709551616, 18446744073709551616], outputs: [w16, w17] - BLACKBOX::RANGE [w16]:1 bits [] - BLACKBOX::RANGE [w17]:64 bits [] - EXPR w17 = -w1 - 18446744073709551616*w16 + 18446744073709551616 - EXPR w18 = -w14 + 1 - MEM id: 1, read at: w18, value: w19 - EXPR w20 = w14*w16 - w14 + 1 - EXPR w21 = 1 - EXPR w22 = -10*w14*w16 + w19*w20 + 10*w14 - MEM id: 2, write: w22 at: w21 - BRILLIG CALL func 0: inputs: [-w1 + 18446744073709551618, 18446744073709551616], outputs: [w23, w24] - BLACKBOX::RANGE [w23]:1 bits [] - BLACKBOX::RANGE [w24]:64 bits [] - EXPR w24 = -w1 - 18446744073709551616*w23 + 18446744073709551618 - BRILLIG CALL func 0: inputs: [-w1 + 18446744073709551617, 18446744073709551616], outputs: [w25, w26] - BLACKBOX::RANGE [w25]:1 bits [] - BLACKBOX::RANGE [w26]:64 bits [] - EXPR w26 = -w1 - 18446744073709551616*w25 + 18446744073709551617 - EXPR w27 = -w23 + 2 - MEM id: 1, read at: w27, value: w28 - EXPR w29 = w23*w25 - w23 + 1 - EXPR w30 = -10*w23*w25 + w28*w29 + 10*w23 - MEM id: 2, write: w30 at: w2 - EXPR w1 = 4 - MEM id: 2, read at: w6, value: w31 - MEM id: 2, read at: w21, value: w32 - MEM id: 2, read at: w2, value: w33 - INIT id: 3, len: 3, witnesses: [w31, w32, w33] - EXPR w34 = 20 - MEM id: 3, write: w34 at: w0 - + BLACKBOX::RANGE input: w1, bits: 32 + ASSERT w2 = 2 + ASSERT w3 = 3 + ASSERT w4 = 5 + INIT b1 = [w2, w3, w4] + ASSERT w5 = 4 + WRITE b1[w0] = w5 + ASSERT w6 = 0 + INIT b2 = [w6, w6, w6] + BRILLIG CALL func: 0, inputs: [-w1 + 18446744073709551616, 18446744073709551616], outputs: [w7, w8] + BLACKBOX::RANGE input: w7, bits: 1 + BLACKBOX::RANGE input: w8, bits: 64 + ASSERT w8 = -w1 - 18446744073709551616*w7 + 18446744073709551616 + BRILLIG CALL func: 0, inputs: [-w1 + 18446744073709551615, 18446744073709551616], outputs: [w9, w10] + BLACKBOX::RANGE input: w9, bits: 1 + BLACKBOX::RANGE input: w10, bits: 64 + ASSERT w10 = -w1 - 18446744073709551616*w9 + 18446744073709551615 + READ w11 = b1[w6] + ASSERT w12 = w7*w9 - w7 + 1 + ASSERT w13 = -10*w7*w9 + w11*w12 + 10*w7 + WRITE b2[w6] = w13 + BRILLIG CALL func: 0, inputs: [-w1 + 18446744073709551617, 18446744073709551616], outputs: [w14, w15] + BLACKBOX::RANGE input: w14, bits: 1 + BLACKBOX::RANGE input: w15, bits: 64 + ASSERT w15 = -w1 - 18446744073709551616*w14 + 18446744073709551617 + BRILLIG CALL func: 0, inputs: [-w1 + 18446744073709551616, 18446744073709551616], outputs: [w16, w17] + BLACKBOX::RANGE input: w16, bits: 1 + BLACKBOX::RANGE input: w17, bits: 64 + ASSERT w17 = -w1 - 18446744073709551616*w16 + 18446744073709551616 + ASSERT w18 = -w14 + 1 + READ w19 = b1[w18] + ASSERT w20 = w14*w16 - w14 + 1 + ASSERT w21 = 1 + ASSERT w22 = -10*w14*w16 + w19*w20 + 10*w14 + WRITE b2[w21] = w22 + BRILLIG CALL func: 0, inputs: [-w1 + 18446744073709551618, 18446744073709551616], outputs: [w23, w24] + BLACKBOX::RANGE input: w23, bits: 1 + BLACKBOX::RANGE input: w24, bits: 64 + ASSERT w24 = -w1 - 18446744073709551616*w23 + 18446744073709551618 + BRILLIG CALL func: 0, inputs: [-w1 + 18446744073709551617, 18446744073709551616], outputs: [w25, w26] + BLACKBOX::RANGE input: w25, bits: 1 + BLACKBOX::RANGE input: w26, bits: 64 + ASSERT w26 = -w1 - 18446744073709551616*w25 + 18446744073709551617 + ASSERT w27 = -w23 + 2 + READ w28 = b1[w27] + ASSERT w29 = w23*w25 - w23 + 1 + ASSERT w30 = -10*w23*w25 + w28*w29 + 10*w23 + WRITE b2[w2] = w30 + ASSERT w1 = 4 + READ w31 = b2[w6] + READ w32 = b2[w21] + READ w33 = b2[w2] + INIT b3 = [w31, w32, w33] + ASSERT w34 = 20 + WRITE b3[w0] = w34 + unconstrained func 0 0: @10 = const u32 2 1: @11 = const u32 0 @@ -292,46 +287,45 @@ fn slice_remove() { // The Brillig calls are to our stdlib quotient directive assert_circuit_snapshot!(program, @r" func 0 - current witness: w24 private parameters: [w0, w1, w2] public parameters: [] return values: [] - EXPR w3 = 2 - EXPR w4 = 3 - EXPR w5 = 5 - INIT id: 1, len: 3, witnesses: [w3, w4, w5] - EXPR w6 = 4 - MEM id: 1, write: w6 at: w0 - EXPR w7 = 0 - MEM id: 1, read at: w7, value: w8 - EXPR w9 = 1 - MEM id: 1, read at: w9, value: w10 - MEM id: 1, read at: w3, value: w11 - MEM id: 1, read at: w1, value: w12 - INIT id: 2, len: 3, witnesses: [w8, w10, w11] - MEM id: 1, read at: w9, value: w13 - BRILLIG CALL func 0: inputs: [-w1 + 18446744073709551616, 18446744073709551616], outputs: [w14, w15] - BLACKBOX::RANGE [w14]:1 bits [] - BLACKBOX::RANGE [w15]:64 bits [] - EXPR w15 = -w1 - 18446744073709551616*w14 + 18446744073709551616 - EXPR w16 = w13*w14 - w8*w14 + w8 - MEM id: 2, write: w16 at: w7 - MEM id: 1, read at: w3, value: w17 - BRILLIG CALL func 0: inputs: [-w1 + 18446744073709551617, 18446744073709551616], outputs: [w18, w19] - BLACKBOX::RANGE [w18]:1 bits [] - BLACKBOX::RANGE [w19]:64 bits [] - EXPR w19 = -w1 - 18446744073709551616*w18 + 18446744073709551617 - EXPR w20 = w17*w18 - w10*w18 + w10 - MEM id: 2, write: w20 at: w9 - EXPR w1 = 2 - EXPR w12 = w2 - MEM id: 2, read at: w7, value: w21 - MEM id: 2, read at: w9, value: w22 - MEM id: 2, read at: w3, value: w23 - INIT id: 3, len: 3, witnesses: [w21, w22, w23] - EXPR w24 = 20 - MEM id: 3, write: w24 at: w0 - + ASSERT w3 = 2 + ASSERT w4 = 3 + ASSERT w5 = 5 + INIT b1 = [w3, w4, w5] + ASSERT w6 = 4 + WRITE b1[w0] = w6 + ASSERT w7 = 0 + READ w8 = b1[w7] + ASSERT w9 = 1 + READ w10 = b1[w9] + READ w11 = b1[w3] + READ w12 = b1[w1] + INIT b2 = [w8, w10, w11] + READ w13 = b1[w9] + BRILLIG CALL func: 0, inputs: [-w1 + 18446744073709551616, 18446744073709551616], outputs: [w14, w15] + BLACKBOX::RANGE input: w14, bits: 1 + BLACKBOX::RANGE input: w15, bits: 64 + ASSERT w15 = -w1 - 18446744073709551616*w14 + 18446744073709551616 + ASSERT w16 = w13*w14 - w8*w14 + w8 + WRITE b2[w7] = w16 + READ w17 = b1[w3] + BRILLIG CALL func: 0, inputs: [-w1 + 18446744073709551617, 18446744073709551616], outputs: [w18, w19] + BLACKBOX::RANGE input: w18, bits: 1 + BLACKBOX::RANGE input: w19, bits: 64 + ASSERT w19 = -w1 - 18446744073709551616*w18 + 18446744073709551617 + ASSERT w20 = w17*w18 - w10*w18 + w10 + WRITE b2[w9] = w20 + ASSERT w1 = 2 + ASSERT w12 = w2 + READ w21 = b2[w7] + READ w22 = b2[w9] + READ w23 = b2[w3] + INIT b3 = [w21, w22, w23] + ASSERT w24 = 20 + WRITE b3[w0] = w24 + unconstrained func 0 0: @10 = const u32 2 1: @11 = const u32 0 diff --git a/compiler/noirc_evaluator/src/acir/tests/mod.rs b/compiler/noirc_evaluator/src/acir/tests/mod.rs index 7d639e4f2ab..412f30678eb 100644 --- a/compiler/noirc_evaluator/src/acir/tests/mod.rs +++ b/compiler/noirc_evaluator/src/acir/tests/mod.rs @@ -89,13 +89,12 @@ fn unchecked_mul_should_not_have_range_check() { // Check that range checks only exist on the function parameters assert_circuit_snapshot!(program, @r" func 0 - current witness: w2 private parameters: [w0, w1] public parameters: [] return values: [w2] - BLACKBOX::RANGE [w0]:32 bits [] - BLACKBOX::RANGE [w1]:32 bits [] - EXPR w2 = w0*w1 + BLACKBOX::RANGE input: w0, bits: 32 + BLACKBOX::RANGE input: w1, bits: 32 + ASSERT w2 = w0*w1 "); }