# Proposal: Arbitrary Field Support in Noir ## Motivation Currently, Noir is composed of several interdependent components: - **Compiler** - **Standard Library (stdlib)** - **Blackbox functions** - **Proving system (Barretenberg)** - **Ecosystem libraries** (e.g., bignum) Adding support for arbitrary fields requires coordinated changes across all of these layers. Some changes are relatively minor, while others are foundational. The long-term goal is to **structure Noir in a way that makes it straightforward to add new fields (e.g., M31) into the ecosystem** without breaking existing functionality. --- ## Challenges in the Current Design A fundamental issue is the **tight coupling of circuits and libraries to the BN254 scalar field**. - Many circuits assume a fixed `Field` type, which makes them incompatible with smaller or alternative fields. - For example, the **Barrett reduction** in the bignum library is implemented directly over the BN254 field. This implementation would fail immediately when targeting M31. This design limits extensibility and requires rethinking how Noir exposes and restricts field access. --- ## Possible Approaches Two possible strategies to introduce field flexibility are: 1. **Restrict direct field access** - Expose field operations only behind `unsafe` or specialized APIs. - Prevent casual misuse of field assumptions in libraries. 2. **Default to BN254 with feature-flag switching** - Keep BN254 as the default field for backwards compatibility. - Introduce feature flags for alternate fields (e.g., `--features m31`). - Allow conditional compilation of field-specific logic. --- ## Compiler Changes The Noir compiler has two main components: 1. **Frontend** – responsible for generating a typed AST. 2. **Evaluator** – responsible for generating opcodes (ACIR and Brillig). ### Frontend Adjustments While largely field-agnostic, the frontend still requires updates: - Represent constants and data as **bignums** instead of direct field elements. - Remove hard-coded max constant check (currently capped at field size). - Update casting logic. - Adjust compile-time execution (`comptime`) to handle arbitrary fields. ### Evaluator Adjustments The evaluator is more tightly bound to field semantics. Required changes include: - Field-specific SSA optimizations. - ACIR and Brillig opcode generation for each field. - Ensuring the generated bytecode respects the target field’s modulus and arithmetic rules. --- ## Standard Library (stdlib) Changes Even “basic” circuits in Noir rely heavily on the stdlib. To support new fields, we need: - Refactoring of primitives (e.g., `array_len`) that implicitly depend on BN254. - Conditional or generic implementations of blackbox functions. - Rework of bignum and arithmetic-heavy utilities to avoid hard-coded field assumptions. --- ## Example: M31 Integration As an initial case study, we propose adding **M31 field support**: - Guarded behind a feature flag (`--features m31`). - Serves as a template for adding other fields in the future. - Demonstrates the path from compiler changes → stdlib → ecosystem adoption. --- ## Risks and Trade-Offs ### 1. **Performance Penalties** - Introducing abstractions may slow down critical arithmetic paths. - Field-generic optimizations may be less efficient than field-specialized implementations. - Mitigation: allow field-specific overrides for performance-critical routines (e.g., FFTs, reductions). ### 2. **Increased Maintenance Burden** - Every new field potentially multiplies the testing matrix across compiler, stdlib, and proving system. - Changes to one subsystem (e.g., stdlib bignum) must be validated across all supported fields. - Mitigation: enforce feature-flag isolation and CI pipelines that test each field independently. ### 3. **Proving System Dependencies** - Barretenberg and other proving backends are currently optimized for BN254. - Supporting alternative fields may require deep changes in the proving system (e.g., elliptic curve assumptions). - Mitigation: clearly scope Noir’s field support to *circuit representation and compilation* first, deferring proving backend generalization. ### 4. **Ecosystem Fragmentation** - Allowing arbitrary fields risks fragmenting the ecosystem if libraries target incompatible assumptions. - Mitigation: define strong conventions and provide default “core field sets” (BN254, M31) to encourage consistency. --- ## Conclusion Supporting arbitrary fields in Noir is a multi-step effort that touches nearly every layer of the ecosystem. By introducing feature-flagged field configurations, refactoring compiler assumptions, and incrementally expanding stdlib support, Noir can evolve into a truly field-agnostic proving stack. This not only improves extensibility but also positions Noir as a versatile tool for research and production use cases that require fields beyond BN254.