Skip to content

Commit

Permalink
Merge branch 'master' into tf/codegen-nargo-reference-docs
Browse files Browse the repository at this point in the history
* master: (22 commits)
  feat: remove predicate from `sort` intrinsic function (#4228)
  chore: add test for missing lambda closure environment (#2120) (#4212)
  chore(docs): Updates following `is_recursive` flag removal (#4199)
  fix: from field with constant values (#4226)
  feat: Option expect method (#4219)
  feat: Evaluation of dynamic assert messages (#4101)
  chore(docs): XOR typo in docs (#4223)
  fix: apply range constraints to return values from unconstrained functions (#4217)
  fix(lsp): replace panics with errors (#4209)
  feat: Improve Error Handling for Cargo in Bootstrap Script (#4211)
  fix: prevent declarations of blackbox functions outside of the stdlib (#4177)
  feat: disable unused variable checks on low-level and oracle functions (#4179)
  chore: Rename acir_docs.md to README.md (#4208)
  feat: remove replacement of boolean range opcodes with `AssertZero` opcodes (#4107)
  chore(docs): updating docs to match new recursion interfacee (#4187)
  feat!: Sync commits from `aztec-packages` (#4144)
  feat: multiply first to allow more ACIR gen optimizations (#4201)
  feat: Move bounded_vec into the noir stdlib (#4197)
  chore: simplify marking black box function outputs as solvable (#4194)
  chore(doc): Add docs for `assert_max_bit_size` (#4196)
  ...
  • Loading branch information
TomAFrench committed Feb 2, 2024
2 parents 42b4456 + d646243 commit d40c81b
Show file tree
Hide file tree
Showing 153 changed files with 3,287 additions and 1,812 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
[workspace]

members = [
# Macros crates for metaprogramming
"aztec_macros",
"noirc_macros",
# Compiler crates
"compiler/noirc_evaluator",
"compiler/noirc_frontend",
"compiler/noirc_errors",
Expand Down
File renamed without changes.
1,312 changes: 1,030 additions & 282 deletions acvm-repo/acir/codegen/acir.cpp

Large diffs are not rendered by default.

42 changes: 36 additions & 6 deletions acvm-repo/acir/src/circuit/black_box_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,22 @@ pub enum BlackBoxFunc {
RecursiveAggregation,
/// Addition over the embedded curve on which [`FieldElement`][acir_field::FieldElement] is defined.
EmbeddedCurveAdd,
/// Point doubling over the embedded curve on which [`FieldElement`][acir_field::FieldElement] is defined.
EmbeddedCurveDouble,
/// BigInt addition
BigIntAdd,
/// BigInt subtraction
BigIntNeg,
/// BigInt multiplication
BigIntMul,
/// BigInt division
BigIntDiv,
/// BigInt from le bytes
BigIntFromLeBytes,
/// BigInt to le bytes
BigIntToLeBytes,
/// Permutation function of Poseidon2
Poseidon2Permutation,
/// SHA256 compression function
Sha256Compression,
}

impl std::fmt::Display for BlackBoxFunc {
Expand All @@ -68,17 +82,25 @@ impl BlackBoxFunc {
BlackBoxFunc::PedersenHash => "pedersen_hash",
BlackBoxFunc::EcdsaSecp256k1 => "ecdsa_secp256k1",
BlackBoxFunc::FixedBaseScalarMul => "fixed_base_scalar_mul",
BlackBoxFunc::EmbeddedCurveAdd => "ec_add",
BlackBoxFunc::EmbeddedCurveDouble => "ec_double",
BlackBoxFunc::EmbeddedCurveAdd => "embedded_curve_add",
BlackBoxFunc::AND => "and",
BlackBoxFunc::XOR => "xor",
BlackBoxFunc::RANGE => "range",
BlackBoxFunc::Keccak256 => "keccak256",
BlackBoxFunc::Keccakf1600 => "keccakf1600",
BlackBoxFunc::RecursiveAggregation => "recursive_aggregation",
BlackBoxFunc::EcdsaSecp256r1 => "ecdsa_secp256r1",
BlackBoxFunc::BigIntAdd => "bigint_add",
BlackBoxFunc::BigIntNeg => "bigint_neg",
BlackBoxFunc::BigIntMul => "bigint_mul",
BlackBoxFunc::BigIntDiv => "bigint_div",
BlackBoxFunc::BigIntFromLeBytes => "bigint_from_le_bytes",
BlackBoxFunc::BigIntToLeBytes => "bigint_to_le_bytes",
BlackBoxFunc::Poseidon2Permutation => "poseidon2_permutation",
BlackBoxFunc::Sha256Compression => "sha256_compression",
}
}

pub fn lookup(op_name: &str) -> Option<BlackBoxFunc> {
match op_name {
"sha256" => Some(BlackBoxFunc::SHA256),
Expand All @@ -90,17 +112,25 @@ impl BlackBoxFunc {
"ecdsa_secp256k1" => Some(BlackBoxFunc::EcdsaSecp256k1),
"ecdsa_secp256r1" => Some(BlackBoxFunc::EcdsaSecp256r1),
"fixed_base_scalar_mul" => Some(BlackBoxFunc::FixedBaseScalarMul),
"ec_add" => Some(BlackBoxFunc::EmbeddedCurveAdd),
"ec_double" => Some(BlackBoxFunc::EmbeddedCurveDouble),
"embedded_curve_add" => Some(BlackBoxFunc::EmbeddedCurveAdd),
"and" => Some(BlackBoxFunc::AND),
"xor" => Some(BlackBoxFunc::XOR),
"range" => Some(BlackBoxFunc::RANGE),
"keccak256" => Some(BlackBoxFunc::Keccak256),
"keccakf1600" => Some(BlackBoxFunc::Keccakf1600),
"recursive_aggregation" => Some(BlackBoxFunc::RecursiveAggregation),
"bigint_add" => Some(BlackBoxFunc::BigIntAdd),
"bigint_neg" => Some(BlackBoxFunc::BigIntNeg),
"bigint_mul" => Some(BlackBoxFunc::BigIntMul),
"bigint_div" => Some(BlackBoxFunc::BigIntDiv),
"bigint_from_le_bytes" => Some(BlackBoxFunc::BigIntFromLeBytes),
"bigint_to_le_bytes" => Some(BlackBoxFunc::BigIntToLeBytes),
"poseidon2_permutation" => Some(BlackBoxFunc::Poseidon2Permutation),
"sha256_compression" => Some(BlackBoxFunc::Sha256Compression),
_ => None,
}
}

pub fn is_valid_black_box_func_name(op_name: &str) -> bool {
BlackBoxFunc::lookup(op_name).is_some()
}
Expand Down
4 changes: 4 additions & 0 deletions acvm-repo/acir/src/circuit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ pub struct Circuit {
// Note: This should be a BTreeMap, but serde-reflect is creating invalid
// c++ code at the moment when it is, due to OpcodeLocation needing a comparison
// implementation which is never generated.
//
// TODO: These are only used for constraints that are explicitly created during code generation (such as index out of bounds on slices)
// TODO: We should move towards having all the checks being evaluated in the same manner
// TODO: as runtime assert messages specified by the user. This will also be a breaking change as the `Circuit` structure will change.
pub assert_messages: Vec<(OpcodeLocation, String)>,
}

Expand Down
100 changes: 85 additions & 15 deletions acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,6 @@ pub enum BlackBoxFuncCall {
input2_y: FunctionInput,
outputs: (Witness, Witness),
},
EmbeddedCurveDouble {
input_x: FunctionInput,
input_y: FunctionInput,
outputs: (Witness, Witness),
},
Keccak256 {
inputs: Vec<FunctionInput>,
outputs: Vec<Witness>,
Expand Down Expand Up @@ -120,6 +115,61 @@ pub enum BlackBoxFuncCall {
/// key provided to the circuit matches the key produced by the circuit creator
key_hash: FunctionInput,
},
BigIntAdd {
lhs: u32,
rhs: u32,
output: u32,
},
BigIntNeg {
lhs: u32,
rhs: u32,
output: u32,
},
BigIntMul {
lhs: u32,
rhs: u32,
output: u32,
},
BigIntDiv {
lhs: u32,
rhs: u32,
output: u32,
},
BigIntFromLeBytes {
inputs: Vec<FunctionInput>,
modulus: Vec<u8>,
output: u32,
},
BigIntToLeBytes {
input: u32,
outputs: Vec<Witness>,
},
/// Applies the Poseidon2 permutation function to the given state,
/// outputting the permuted state.
Poseidon2Permutation {
/// Input state for the permutation of Poseidon2
inputs: Vec<FunctionInput>,
/// Permuted state
outputs: Vec<Witness>,
/// State length (in number of field elements)
/// It is the length of inputs and outputs vectors
len: u32,
},
/// Applies the SHA-256 compression function to the input message
///
/// # Arguments
///
/// * `inputs` - input message block
/// * `hash_values` - state from the previous compression
/// * `outputs` - result of the input compressed into 256 bits
Sha256Compression {
/// 512 bits of the input message, represented by 16 u32s
inputs: Vec<FunctionInput>,
/// Vector of 8 u32s used to compress the input
hash_values: Vec<FunctionInput>,
/// Output of the compression, represented by 8 u32s
outputs: Vec<Witness>,
},
}

impl BlackBoxFuncCall {
Expand All @@ -138,11 +188,18 @@ impl BlackBoxFuncCall {
BlackBoxFuncCall::EcdsaSecp256r1 { .. } => BlackBoxFunc::EcdsaSecp256r1,
BlackBoxFuncCall::FixedBaseScalarMul { .. } => BlackBoxFunc::FixedBaseScalarMul,
BlackBoxFuncCall::EmbeddedCurveAdd { .. } => BlackBoxFunc::EmbeddedCurveAdd,
BlackBoxFuncCall::EmbeddedCurveDouble { .. } => BlackBoxFunc::EmbeddedCurveDouble,
BlackBoxFuncCall::Keccak256 { .. } => BlackBoxFunc::Keccak256,
BlackBoxFuncCall::Keccak256VariableLength { .. } => BlackBoxFunc::Keccak256,
BlackBoxFuncCall::Keccakf1600 { .. } => BlackBoxFunc::Keccakf1600,
BlackBoxFuncCall::RecursiveAggregation { .. } => BlackBoxFunc::RecursiveAggregation,
BlackBoxFuncCall::BigIntAdd { .. } => BlackBoxFunc::BigIntAdd,
BlackBoxFuncCall::BigIntNeg { .. } => BlackBoxFunc::BigIntNeg,
BlackBoxFuncCall::BigIntMul { .. } => BlackBoxFunc::BigIntMul,
BlackBoxFuncCall::BigIntDiv { .. } => BlackBoxFunc::BigIntDiv,
BlackBoxFuncCall::BigIntFromLeBytes { .. } => BlackBoxFunc::BigIntFromLeBytes,
BlackBoxFuncCall::BigIntToLeBytes { .. } => BlackBoxFunc::BigIntToLeBytes,
BlackBoxFuncCall::Poseidon2Permutation { .. } => BlackBoxFunc::Poseidon2Permutation,
BlackBoxFuncCall::Sha256Compression { .. } => BlackBoxFunc::Sha256Compression,
}
}

Expand All @@ -158,17 +215,22 @@ impl BlackBoxFuncCall {
| BlackBoxFuncCall::Keccak256 { inputs, .. }
| BlackBoxFuncCall::Keccakf1600 { inputs, .. }
| BlackBoxFuncCall::PedersenCommitment { inputs, .. }
| BlackBoxFuncCall::PedersenHash { inputs, .. } => inputs.to_vec(),
| BlackBoxFuncCall::PedersenHash { inputs, .. }
| BlackBoxFuncCall::BigIntFromLeBytes { inputs, .. }
| BlackBoxFuncCall::Poseidon2Permutation { inputs, .. }
| BlackBoxFuncCall::Sha256Compression { inputs, .. } => inputs.to_vec(),
BlackBoxFuncCall::AND { lhs, rhs, .. } | BlackBoxFuncCall::XOR { lhs, rhs, .. } => {
vec![*lhs, *rhs]
}
BlackBoxFuncCall::BigIntAdd { .. }
| BlackBoxFuncCall::BigIntNeg { .. }
| BlackBoxFuncCall::BigIntMul { .. }
| BlackBoxFuncCall::BigIntDiv { .. }
| BlackBoxFuncCall::BigIntToLeBytes { .. } => Vec::new(),
BlackBoxFuncCall::FixedBaseScalarMul { low, high, .. } => vec![*low, *high],
BlackBoxFuncCall::EmbeddedCurveAdd {
input1_x, input1_y, input2_x, input2_y, ..
} => vec![*input1_x, *input1_y, *input2_x, *input2_y],
BlackBoxFuncCall::EmbeddedCurveDouble { input_x, input_y, .. } => {
vec![*input_x, *input_y]
}
BlackBoxFuncCall::RANGE { input } => vec![*input],
BlackBoxFuncCall::SchnorrVerify {
public_key_x,
Expand Down Expand Up @@ -249,7 +311,10 @@ impl BlackBoxFuncCall {
| BlackBoxFuncCall::Blake2s { outputs, .. }
| BlackBoxFuncCall::Blake3 { outputs, .. }
| BlackBoxFuncCall::Keccak256 { outputs, .. }
| BlackBoxFuncCall::Keccakf1600 { outputs, .. } => outputs.to_vec(),
| BlackBoxFuncCall::Keccakf1600 { outputs, .. }
| BlackBoxFuncCall::Keccak256VariableLength { outputs, .. }
| BlackBoxFuncCall::Poseidon2Permutation { outputs, .. }
| BlackBoxFuncCall::Sha256Compression { outputs, .. } => outputs.to_vec(),
BlackBoxFuncCall::AND { output, .. }
| BlackBoxFuncCall::XOR { output, .. }
| BlackBoxFuncCall::SchnorrVerify { output, .. }
Expand All @@ -258,12 +323,17 @@ impl BlackBoxFuncCall {
| BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } => vec![*output],
BlackBoxFuncCall::FixedBaseScalarMul { outputs, .. }
| BlackBoxFuncCall::PedersenCommitment { outputs, .. }
| BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. }
| BlackBoxFuncCall::EmbeddedCurveDouble { outputs, .. } => vec![outputs.0, outputs.1],
BlackBoxFuncCall::RANGE { .. } | BlackBoxFuncCall::RecursiveAggregation { .. } => {
| BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. } => vec![outputs.0, outputs.1],
BlackBoxFuncCall::RANGE { .. }
| BlackBoxFuncCall::RecursiveAggregation { .. }
| BlackBoxFuncCall::BigIntFromLeBytes { .. }
| BlackBoxFuncCall::BigIntAdd { .. }
| BlackBoxFuncCall::BigIntNeg { .. }
| BlackBoxFuncCall::BigIntMul { .. }
| BlackBoxFuncCall::BigIntDiv { .. } => {
vec![]
}
BlackBoxFuncCall::Keccak256VariableLength { outputs, .. } => outputs.to_vec(),
BlackBoxFuncCall::BigIntToLeBytes { outputs, .. } => outputs.to_vec(),
}
}
}
Expand Down
72 changes: 26 additions & 46 deletions acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use acir::{
opcodes::{BlackBoxFuncCall, FunctionInput},
Circuit, Opcode,
},
native_types::{Expression, Witness},
FieldElement,
native_types::Witness,
};
use std::collections::{BTreeMap, HashSet};

Expand Down Expand Up @@ -105,9 +104,11 @@ impl RangeOptimizer {
let mut new_order_list = Vec::with_capacity(order_list.len());
let mut optimized_opcodes = Vec::with_capacity(self.circuit.opcodes.len());
for (idx, opcode) in self.circuit.opcodes.into_iter().enumerate() {
let (witness, num_bits) = match extract_range_opcode(&opcode) {
Some(range_opcode) => range_opcode,
None => {
let (witness, num_bits) = match &opcode {
Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { input }) => {
(input.witness, input.num_bits)
}
_ => {
// If its not the range opcode, add it to the opcode
// list and continue;
optimized_opcodes.push(opcode);
Expand All @@ -131,44 +132,19 @@ impl RangeOptimizer {
if is_lowest_bit_size {
already_seen_witness.insert(witness);
new_order_list.push(order_list[idx]);
optimized_opcodes.push(optimized_range_opcode(witness, num_bits));
optimized_opcodes.push(opcode);
}
}

(Circuit { opcodes: optimized_opcodes, ..self.circuit }, new_order_list)
}
}

/// Extract the range opcode from the `Opcode` enum
/// Returns None, if `Opcode` is not the range opcode.
fn extract_range_opcode(opcode: &Opcode) -> Option<(Witness, u32)> {
match opcode {
Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { input }) => {
Some((input.witness, input.num_bits))
}
_ => None,
}
}

fn optimized_range_opcode(witness: Witness, num_bits: u32) -> Opcode {
if num_bits == 1 {
Opcode::AssertZero(Expression {
mul_terms: vec![(FieldElement::one(), witness, witness)],
linear_combinations: vec![(-FieldElement::one(), witness)],
q_c: FieldElement::zero(),
})
} else {
Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE {
input: FunctionInput { witness, num_bits },
})
}
}

#[cfg(test)]
mod tests {
use std::collections::BTreeSet;

use crate::compiler::optimizers::redundant_range::{extract_range_opcode, RangeOptimizer};
use crate::compiler::optimizers::redundant_range::RangeOptimizer;
use acir::{
circuit::{
opcodes::{BlackBoxFuncCall, FunctionInput},
Expand Down Expand Up @@ -218,11 +194,12 @@ mod tests {
let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions);
assert_eq!(optimized_circuit.opcodes.len(), 1);

let (witness, num_bits) =
extract_range_opcode(&optimized_circuit.opcodes[0]).expect("expected one range opcode");

assert_eq!(witness, Witness(1));
assert_eq!(num_bits, 16);
assert_eq!(
optimized_circuit.opcodes[0],
Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE {
input: FunctionInput { witness: Witness(1), num_bits: 16 }
})
);
}

#[test]
Expand All @@ -240,15 +217,18 @@ mod tests {
let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions);
assert_eq!(optimized_circuit.opcodes.len(), 2);

let (witness_a, num_bits_a) =
extract_range_opcode(&optimized_circuit.opcodes[0]).expect("expected two range opcode");
let (witness_b, num_bits_b) =
extract_range_opcode(&optimized_circuit.opcodes[1]).expect("expected two range opcode");

assert_eq!(witness_a, Witness(1));
assert_eq!(witness_b, Witness(2));
assert_eq!(num_bits_a, 16);
assert_eq!(num_bits_b, 23);
assert_eq!(
optimized_circuit.opcodes[0],
Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE {
input: FunctionInput { witness: Witness(1), num_bits: 16 }
})
);
assert_eq!(
optimized_circuit.opcodes[1],
Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE {
input: FunctionInput { witness: Witness(2), num_bits: 23 }
})
);
}

#[test]
Expand Down
Loading

0 comments on commit d40c81b

Please sign in to comment.