Skip to content

Commit

Permalink
Merge branch 'master' into tf/noir-artifacts
Browse files Browse the repository at this point in the history
* master: (43 commits)
  feat(experimental): Implement macro calls & splicing into `Expr` values (#5203)
  feat: add BoundedVec::map (#5250)
  chore: add no predicate to poseidon2 (#5252)
  feat: add `set` and `set_unchecked` methods to `Vec` and `BoundedVec` (#5241)
  fix: Disable `if` optimization (#5240)
  chore: redo typo PR by dropbigfish (#5234)
  chore: add property tests for ABI encoding (#5216)
  chore: thread generics through ACIR/brillig gen (#5120)
  chore: copy across typo PR script from aztec-packages (#5235)
  chore(docs): fixing trailing slash issue (#5233)
  fix: add support for nested arrays returned by oracles (#5132)
  chore: Parse macros (#5229)
  chore: Optimize the elaborator (#5230)
  fix(elaborator): Fix regression introduced by lazy-global changes (#5223)
  fix(elaborator): Fix duplicate methods error (#5225)
  chore: fixing all relative paths (#5220)
  chore: push code related to ABI gen into `noirc_driver` (#5218)
  chore: avoid `bn254_blackbox_solver` polluting feature flags (#5141)
  chore!: remove `distinct` keyword (#5219)
  feat: Sync from aztec-packages (#5222)
  ...
  • Loading branch information
TomAFrench committed Jun 17, 2024
2 parents 3415520 + d9b4712 commit 8602cb6
Show file tree
Hide file tree
Showing 367 changed files with 5,610 additions and 3,059 deletions.
2 changes: 1 addition & 1 deletion .aztec-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1d785fd1087d7387fc29213ca3be50b2fc9c4725
86a33140f9a65e518003b3f4c60f97d132f85b89
27 changes: 0 additions & 27 deletions .github/workflows/test-js-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,32 +221,6 @@ jobs:
- name: Run browser tests
run: yarn workspace @noir-lang/noirc_abi test:browser

test-noir-js-backend-barretenberg:
needs: [build-noirc-abi]
name: noir-js-backend-barretenberg
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download wasm package artifact
uses: actions/download-artifact@v4
with:
name: noirc_abi_wasm
path: ./tooling/noirc_abi_wasm

- name: Install Yarn dependencies
uses: ./.github/actions/setup

- name: Build noir_js_types
run: yarn workspace @noir-lang/types build

- name: Run barretenberg wrapper tests
run: |
yarn workspace @noir-lang/backend_barretenberg test
test-noir-js:
needs: [build-nargo, build-acvm-js, build-noirc-abi]
name: Noir JS
Expand Down Expand Up @@ -546,7 +520,6 @@ jobs:
- test-acvm_js-node
- test-acvm_js-browser
- test-noirc-abi
- test-noir-js-backend-barretenberg
- test-noir-js
- test-noir-wasm
- test-noir-codegen
Expand Down
35 changes: 21 additions & 14 deletions Cargo.lock

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

12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ noirc_artifacts = { path = "tooling/noirc_artifacts" }
bb_abstraction_leaks = { path = "tooling/bb_abstraction_leaks" }
acvm_cli = { path = "tooling/acvm_cli" }

# Arkworks
ark-bn254 = { version = "^0.4.0", default-features = false, features = ["curve"] }
ark-bls12-381 = { version = "^0.4.0", default-features = false, features = ["curve"] }
grumpkin = { version = "0.1.0", package = "noir_grumpkin", features = ["std"] }
ark-ec = { version = "^0.4.0", default-features = false }
ark-ff = { version = "^0.4.0", default-features = false }
ark-std = { version = "^0.4.0", default-features = false }

# Misc utils crates
iter-extended = { path = "utils/iter-extended" }

Expand Down Expand Up @@ -133,6 +141,10 @@ similar-asserts = "1.5.0"
tempfile = "3.6.0"
jsonrpc = { version = "0.16.0", features = ["minreq_http"] }
flate2 = "1.0.24"
rand = "0.8.5"
proptest = "1.2.0"
proptest-derive = "0.4.0"


im = { version = "15.1", features = ["serde"] }
tracing = "0.1.40"
Expand Down
4 changes: 2 additions & 2 deletions acvm-repo/acir/src/circuit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ impl FromStr for OpcodeLocation {
}
}

impl<F: AcirField> Circuit<F> {
impl<F> Circuit<F> {
pub fn num_vars(&self) -> u32 {
self.current_witness_index + 1
}
Expand Down Expand Up @@ -425,7 +425,7 @@ mod tests {
};
let program = Program { functions: vec![circuit], unconstrained_functions: Vec::new() };

fn read_write<F: AcirField + Serialize + for<'a> Deserialize<'a>>(
fn read_write<F: Serialize + for<'a> Deserialize<'a>>(
program: Program<F>,
) -> (Program<F>, Program<F>) {
let bytes = Program::serialize_program(&program);
Expand Down
130 changes: 33 additions & 97 deletions acvm-repo/acir/src/native_types/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,12 @@ impl<F: AcirField> std::fmt::Display for Expression<F> {
}
}

impl<F: AcirField> Expression<F> {
// TODO: possibly remove, and move to noir repo.
pub const fn can_defer_constraint(&self) -> bool {
false
}

impl<F> Expression<F> {
/// Returns the number of multiplication terms
pub fn num_mul_terms(&self) -> usize {
self.mul_terms.len()
}

pub fn from_field(q_c: F) -> Self {
Self { q_c, ..Default::default() }
}

pub fn one() -> Self {
Self::from_field(F::one())
}

pub fn zero() -> Self {
Self::default()
}

/// Adds a new linear term to the `Expression`.
pub fn push_addition_term(&mut self, coefficient: F, variable: Witness) {
self.linear_combinations.push((coefficient, variable));
Expand All @@ -85,6 +68,19 @@ impl<F: AcirField> Expression<F> {
self.mul_terms.is_empty() && self.linear_combinations.is_empty()
}

/// Returns a `FieldElement` if the expression represents a constant polynomial.
/// Otherwise returns `None`.
///
/// Examples:
/// - f(x,y) = x would return `None`
/// - f(x,y) = x + 6 would return `None`
/// - f(x,y) = 2*y + 6 would return `None`
/// - f(x,y) = x + y would return `None`
/// - f(x,y) = 5 would return `FieldElement(5)`
pub fn to_const(&self) -> Option<&F> {
self.is_const().then_some(&self.q_c)
}

/// Returns `true` if highest degree term in the expression is one or less.
///
/// - `mul_term` in an expression contains degree-2 terms
Expand Down Expand Up @@ -122,21 +118,29 @@ impl<F: AcirField> Expression<F> {
self.is_linear() && self.linear_combinations.len() == 1
}

/// Sorts opcode in a deterministic order
/// XXX: We can probably make this more efficient by sorting on each phase. We only care if it is deterministic
pub fn sort(&mut self) {
self.mul_terms.sort_by(|a, b| a.1.cmp(&b.1).then(a.2.cmp(&b.2)));
self.linear_combinations.sort_by(|a, b| a.1.cmp(&b.1));
}
}

impl<F: AcirField> Expression<F> {
pub fn from_field(q_c: F) -> Self {
Self { q_c, ..Default::default() }
}

pub fn zero() -> Self {
Self::default()
}

pub fn is_zero(&self) -> bool {
*self == Self::zero()
}

/// Returns a `FieldElement` if the expression represents a constant polynomial.
/// Otherwise returns `None`.
///
/// Examples:
/// - f(x,y) = x would return `None`
/// - f(x,y) = x + 6 would return `None`
/// - f(x,y) = 2*y + 6 would return `None`
/// - f(x,y) = x + y would return `None`
/// - f(x,y) = 5 would return `FieldElement(5)`
pub fn to_const(&self) -> Option<F> {
self.is_const().then_some(self.q_c)
pub fn one() -> Self {
Self::from_field(F::one())
}

/// Returns a `Witness` if the `Expression` can be represented as a degree-1
Expand All @@ -161,74 +165,6 @@ impl<F: AcirField> Expression<F> {
None
}

/// Sorts opcode in a deterministic order
/// XXX: We can probably make this more efficient by sorting on each phase. We only care if it is deterministic
pub fn sort(&mut self) {
self.mul_terms.sort_by(|a, b| a.1.cmp(&b.1).then(a.2.cmp(&b.2)));
self.linear_combinations.sort_by(|a, b| a.1.cmp(&b.1));
}

/// Checks if this expression can fit into one arithmetic identity
/// TODO: This needs to be reworded, arithmetic identity only makes sense in the context
/// TODO of PLONK, whereas we want expressions to be generic.
/// TODO: We just need to reword it to say exactly what its doing and
/// TODO then reference the fact that this is what plonk will accept.
/// TODO alternatively, we can define arithmetic identity in the context of expressions
/// TODO and then reference that.
pub fn fits_in_one_identity(&self, width: usize) -> bool {
// A Polynomial with more than one mul term cannot fit into one opcode
if self.mul_terms.len() > 1 {
return false;
};
// A Polynomial with more terms than fan-in cannot fit within a single opcode
if self.linear_combinations.len() > width {
return false;
}

// A polynomial with no mul term and a fan-in that fits inside of the width can fit into a single opcode
if self.mul_terms.is_empty() {
return true;
}

// A polynomial with width-2 fan-in terms and a single non-zero mul term can fit into one opcode
// Example: Axy + Dz . Notice, that the mul term places a constraint on the first two terms, but not the last term
// XXX: This would change if our arithmetic polynomial equation was changed to Axyz for example, but for now it is not.
if self.linear_combinations.len() <= (width - 2) {
return true;
}

// We now know that we have a single mul term. We also know that the mul term must match up with two other terms
// A polynomial whose mul terms are non zero which do not match up with two terms in the fan-in cannot fit into one opcode
// An example of this is: Axy + Bx + Cy + ...
// Notice how the bivariate monomial xy has two univariate monomials with their respective coefficients
// XXX: note that if x or y is zero, then we could apply a further optimization, but this would be done in another algorithm.
// It would be the same as when we have zero coefficients - Can only work if wire is constrained to be zero publicly
let mul_term = &self.mul_terms[0];

// The coefficient should be non-zero, as this method is ran after the compiler removes all zero coefficient terms
assert_ne!(mul_term.0, F::zero());

let mut found_x = false;
let mut found_y = false;

for term in self.linear_combinations.iter() {
let witness = &term.1;
let x = &mul_term.1;
let y = &mul_term.2;
if witness == x {
found_x = true;
};
if witness == y {
found_y = true;
};
if found_x & found_y {
break;
}
}

found_x & found_y
}

/// Returns `self + k*b`
pub fn add_mul(&self, k: F, b: &Self) -> Self {
if k.is_zero() {
Expand Down
Loading

0 comments on commit 8602cb6

Please sign in to comment.