Skip to content

Conversation

@sisuresh
Copy link
Contributor

No description provided.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds CAP-0080, which proposes six new host functions to improve the performance of ZK applications using BN254 cryptography on Stellar. The proposal introduces a multi-scalar multiplication (MSM) function and five modular arithmetic operations (add, sub, mul, pow, inv) for BN254 scalar elements.

Changes:

  • Adds CAP-0080 specification document with host function definitions for BN254 G1 MSM and Fr field arithmetic
  • Introduces new XDR cost type Bn254G1Msm for metering MSM operations
  • Documents semantics, error conditions, and cost structures for all six proposed host functions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

The only new cost type is for G1 MSM, which we will calibrate.

## Test Cases
TODO No newline at end of file
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Test Cases section contains only "TODO" without any concrete test cases. Before this CAP can be finalized, this section should include specific test cases covering the new host functions, including edge cases for error conditions (e.g., zero-length vectors for MSM, zero input for inversion, mismatched vector lengths).

Suggested change
TODO
This section outlines test cases that should be implemented at the host-function level and, where applicable, at the Soroban contract level to validate the behavior of the new BN254 host functions and their metering.
Unless otherwise specified, “success” means the host function returns `Ok` with the expected value, and “failure” means the host function returns an error code defined in the Soroban host for invalid arguments or arithmetic errors.
### BN254 field operations (`add`, `sub`, `mul`, `pow`, `inv`)
#### Happy-path arithmetic
1. **Addition within field**
- Input: Two valid BN254 field elements `a`, `b` strictly less than the BN254 modulus.
- Example: `a = 1`, `b = 2`.
- Expected: `add(a, b)` succeeds and returns the canonical encoding of `3 mod p`.
2. **Addition with wraparound**
- Input: `a = p - 1`, `b = 2` (where `p` is the BN254 field modulus), both given in canonical encoding.
- Expected: `add(a, b)` succeeds and returns the canonical encoding of `1 mod p`.
3. **Subtraction within field**
- Input: `a = 5`, `b = 3`.
- Expected: `sub(a, b)` succeeds and returns the canonical encoding of `2 mod p`.
4. **Subtraction with underflow**
- Input: `a = 3`, `b = 5`.
- Expected: `sub(a, b)` succeeds and returns the canonical encoding of `p - 2`.
5. **Multiplication**
- Input: `a = 2`, `b = 3`.
- Expected: `mul(a, b)` succeeds and returns the canonical encoding of `6 mod p`.
6. **Exponentiation with small exponents**
- Input: `base = 5`, `exp = 0`.
- Expected: `pow(base, 0)` succeeds and returns `1` (multiplicative identity).
- Input: `base = 5`, `exp = 1`.
- Expected: `pow(base, 1)` succeeds and returns `base`.
- Input: `base = 5`, `exp = 2`.
- Expected: `pow(base, 2)` succeeds and returns canonical encoding of `25 mod p`.
7. **Inversion of non-zero element**
- Input: `x = 2`.
- Expected: `inv(x)` succeeds and returns a value `y` such that `mul(x, y)` returns `1`.
#### Error handling and invalid inputs for field operations
8. **Inversion of zero**
- Input: `x = 0` (canonical zero element).
- Expected: `inv(x)` fails with an appropriate error indicating inversion of zero is not defined.
9. **Non-canonical encoding: value equal to modulus**
- Input: `x = p` encoded as a 32-byte or 64-byte value (per the CAP’s serialization rules) that is not strictly less than `p`.
- Expected: Any field operation (`add`, `sub`, `mul`, `pow`, `inv`) using `x` fails with an “invalid field element” error.
10. **Out-of-range encoding: value greater than modulus**
- Input: `x = p + 1` encoded as a field element.
- Expected: Any field operation using `x` fails with an “invalid field element” error.
11. **Incorrect length encodings**
- Input: Byte array that is shorter or longer than the required field element length.
- Expected: Operation fails with “invalid encoding length” or equivalent error.
12. **Power with large exponent**
- Input: `base` is a valid non-zero field element, `exp` is a large positive integer (e.g., 256‑bit number).
- Expected: Operation succeeds, respects metering limits, and returns a correctly reduced result.
### BN254 G1 multi-scalar multiplication (MSM)
These tests assume there is a host function that takes:
- A vector of BN254 scalars.
- A vector of BN254 G1 points.
- And returns a BN254 G1 point representing the MSM result.
#### Happy-path MSM
13. **Single scalar-point pair**
- Input: Scalars = `[s1]`, Points = `[P1]`, where `s1` and `P1` are valid.
- Expected: Result equals `s1 * P1` (scalar multiplication) encoded canonically.
14. **Multiple scalar-point pairs**
- Input: Scalars = `[s1, s2, s3]`, Points = `[P1, P2, P3]`, all valid.
- Expected: Result equals `s1 * P1 + s2 * P2 + s3 * P3` in BN254 G1.
15. **Including identity point**
- Input: Scalars = `[s1, s2]`, Points = `[P1, O]`, where `O` is the encoded point-at-infinity.
- Expected: Result equals `s1 * P1 + s2 * O = s1 * P1`.
16. **Zero scalar**
- Input: Scalars = `[0, s2]`, Points = `[P1, P2]`.
- Expected: Result equals `0 * P1 + s2 * P2 = s2 * P2`.
#### Edge cases and error conditions for MSM
17. **Zero-length vectors**
- Input: Scalars = `[]`, Points = `[]`.
- Expected: Host function fails with an error indicating empty input not allowed, or returns the identity point if the CAP specifies that as valid behavior. The CAP’s intended behavior must be explicitly tested.
18. **Mismatched vector lengths (more scalars than points)**
- Input: Scalars = `[s1, s2]`, Points = `[P1]`.
- Expected: Host function fails with an error indicating “length mismatch”.
19. **Mismatched vector lengths (more points than scalars)**
- Input: Scalars = `[s1]`, Points = `[P1, P2]`.
- Expected: Host function fails with an error indicating “length mismatch”.
20. **Invalid scalar encoding**
- Input: Scalars vector contains an element that is:
- Out of range (≥ scalar field modulus), or
- Incorrect length.
- Expected: MSM host function fails with an “invalid scalar” error; no partial result is returned.
21. **Invalid point encoding**
- Input: Points vector contains:
- A malformed encoding (wrong length, invalid compression flag), or
- A point not on the BN254 curve (fails curve equation check).
- Expected: MSM host function fails with an “invalid point” error; no partial result is returned.
22. **All-zero scalars**
- Input: Scalars = `[0, 0, 0]`, Points = `[P1, P2, P3]`.
- Expected: Result equals the identity point (point-at-infinity).
23. **Duplicated points**
- Input: Scalars = `[s, s]`, Points = `[P, P]`.
- Expected: Result equals `(s + s) * P`; helps verify correctness of addition vs. repeated scalar multiplication.
24. **Maximum-length vectors within metering budget**
- Input: Scalars and Points vectors filled to the maximum allowed length before hitting metering or argument-size limits.
- Expected: Operation succeeds, is metered linearly in the vector length (`Bn254G1Msm` cost type), and returns a valid point.
25. **Exceeding maximum allowable vector length**
- Input: Scalars and Points vectors longer than any documented or implementation-enforced limit (if such limits exist).
- Expected: Host function fails with an appropriate “too many elements” or similar error, and metering charges must not exceed documented bounds for rejected calls.
### Metering and protocol behavior
26. **Cost type `Bn254G1Msm` linearity**
- Input: Invoke the MSM host function with vectors of length `n` and `2n` where both are well within limits and otherwise identical in structure.
- Expected: Measured cost for the `2n` call is approximately double (within calibration tolerances) the cost for the `n` call, confirming linear metering with respect to vector length.
27. **Failure does not lead to unbounded cost**
- Input: Construct MSM calls that will fail early due to:
- Invalid scalar encoding.
- Invalid point encoding.
- Mismatched vector lengths.
- Expected: The host function aborts with an error and charges only the work performed up to validation failure, complying with metering guarantees (no unbounded or unexpected cost).
28. **Protocol version gating**
- Input: Attempt to invoke the new BN254 host functions in:
- A ledger with protocol version `< 26`.
- A ledger with protocol version `≥ 26`.
- Expected:
- For `< 26`: Calls fail with “unknown host function” or equivalent error.
- For `≥ 26`: Calls behave according to the tests above.
### Soroban contract-level tests
29. **Contract using BN254 field ops**
- Implement a simple Soroban contract that:
- Accepts two field elements as inputs.
- Calls the BN254 `add`, `sub`, and `mul` host functions.
- Returns the triple `(a + b, a - b, a * b)`.
- Tests:
- Valid inputs hit the happy-path arithmetic test expectations.
- Invalid encodings propagate host errors as contract failures.
30. **Contract performing MSM verification**
- Implement a Soroban contract that:
- Takes a vector of scalars and points and a claimed result point.
- Uses the MSM host function to recompute the result and compares it to the claimed point.
- Tests:
- For correct inputs, verification returns success.
- For modified scalar/point/result, verification fails.
- Edge cases (zero-length vectors, mismatched lengths, invalid encodings) cause the contract to fail with propagated host errors.
31. **State-insensitive determinism**
- Input: Invoke the same contract methods (field ops and MSM) multiple times across different ledgers but with identical inputs.
- Expected: Results are deterministic and identical across runs, with no dependence on ledger state beyond protocol version gating.
These test cases should be implemented in the core protocol test suite and in Soroban integration tests to ensure that the new BN254 host functions are correct, robust against invalid inputs, and properly metered.

Copilot uses AI. Check for mistakes.
@@ -291,7 +291,9 @@ enum ContractCostType {
// Cost of performing BN254 scalar element exponentiation
Bn254FrPow = 83,
// Cost of performing BN254 scalar element inversion
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an extra space before the comment. This line should start with four spaces for indentation, followed by two forward slashes, one space, and then the comment text, consistent with the formatting on line 115.

Suggested change
// Cost of performing BN254 scalar element inversion
// Cost of performing BN254 scalar element inversion

Copilot uses AI. Check for mistakes.
@sisuresh sisuresh merged commit 030663f into stellar:master Jan 23, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants