Skip to content

Conversation

@Avaneesh-axiom
Copy link
Contributor

@Avaneesh-axiom Avaneesh-axiom commented Jul 11, 2025

Overview of changes

Added a VM extension for twisted Edwards elliptic curve operations. The twisted Edwards extension is similar in structure to the existing ECC extension. The twisted Edwards extension supports nearly everything the ECC extension does: user-defined curves, affine points, point decompression, point addition, msm, and hybrid GPU tracegen. One difference is that the twisted Edwards extension does not support ecdsa, since ecdsa is specific to short Weierstrass curves.

Since twisted Edwards curves, unlike short Weierstrass curves, have a complete addition formula (meaning that the formula for adding points always works, even if the points are additive inverses of each other or if either or both points are the identity point), the twisted Edwards extension has only two opcodes: TE_ADD and SETUP_TE_ADD for each curve.

There are some restrictions on the curve coefficients of a twisted Edwards curve. In particular, the a coefficient must be a quadratic residue over the coefficient field (this gives that the new curve is isomorphic to an edwards curve) and the d coefficient must be a quadratic non-residue (this guarantees that the addition formula is complete). These two conditions are checked by an assertion in the host code whenever a twisted Edwards curve is defined.

Code-level changes

  • New twisted edwards crates: openvm_edwards_circuit, openvm_edwards_guest, openvm_ecc_te_macros, openvm_edwards_integration_tests, and openvm_edwards_transpiler were added in extensions/edwards_ec/
  • The existing ECC extension (for short Weierstrass curves) has been moved from extensions/ecc/ to extensions/weierstrass_ec/.
  • Crates renamed: openvm_ecc_circuit -> openvm_weierstrass_circuit, openvm_ecc_guest -> openvm_weierstrass_guest, openvm_ecc_integration_tests -> openvm_weierstrass_integration_tests, openvm_ecc_transpiler -> openvm_weierstrass_transpiler
  • New shared ecc crate: openvm_ecc_guest is a new crate that re-exports openvm_weierstrass_guest and openvm_edwards_guest for convenience.
  • New curve: the ed25519 module in the openvm_ecc_guest crate (enabled by the "ed25519" crate feature) provides a definition for the ed25519 curve using intrinsic operations. Note that this module cannot be moved to openvm_edwards_guest because it would cause a cyclic dependency.
  • The FromCompressed and IntrinsicCurve traits from the openvm_ecc_guest crate have been moved from the weierstrass module to crate-level in lib.rs. This is because these traits are not specific to weierstrass curves. The twisted Edwards extension will re-export these traits in openvm_te_guest.
  • ECC opcodes have been renamed to SW_EC_* while the new twisted edwards ones are TE_EC_*.

Documentation

The OpenVM book, specs, and the crate docs have been updated with the new twisted Edwards instrinsics.

CI

  • cargo audit is failing due to some new vulnerability discovered in ruint. This is causing the Lint CI job to fail.

arayikhalatyan and others added 30 commits May 7, 2025 12:06
Fixed an error in divrem negative tests. The trace pranking was done
incorrectly. 2 instructions were being called (so the trace had height
2) each time but only one of the rows was being modified. Changed it so
only one instruction is called each time
Also, made the setup_tracing the default
Implemented e1 and e3 for HeapBranch, Heap, and VecHeap adapters.
Updated the Bigint circuit correspondingly. Had to make some changes in
the interfaces of rv32im Steps. In particular

- Changed Reads type `([u8; N], [u8; N])` into `Into<[[u8;N];2]>` and
Writes type `[u8; N]` into `From<[[u8;N];1]>`. This change corresponds
to what we used to do with the previous integration API in order to make
the interfaces to match.

- Got rid of TraceAdapterContext in a lot of places. This is because the
same Step can be using different AdapterSteps that require different
TraceContexts. Or even the AdapterStep might require a `TraceContext`
that the Step doesn't have. The easy solution was to implement
AdapterSteps in a similar way as in the previous integration API. That
is, added the necessary fields to the AdapterStep structs. I am thinking
maybe deleting the `TraceContext` from the interface makes sense. I am
not sure if there is a better way to do this

Important Note: the tests don't run right now because a lot of the
read/write operations are done in address space 2 with block size 32 but
currently only block size 4 is supported by the memory.

Resolves INT-3980
Resolves INT-3801.

- Added memory access adapters. To improve:
* Allocate the trace buffer once before filling it as opposed to pushing
to `Vec` how it's done now,
* Maybe not call `get_f` too often (although I don't know how to avoid
it normally).
- Added volatile and persistent boundary chips tracegen,
- Added merkle chip tracegen as described
[here](https://docs.google.com/document/d/12cH7ZYRFWHgflpPzOILb7bg5XExdyWOL4vwrQ9HFGkQ/edit?tab=t.0#heading=h.hrg0oexxgu9).
To improve:
  * Parallelize at least something,
  * Maybe support passing this struct between segments.
- `VmChipTestBuilder` now has `::default_persistent`, so all tests in
`extensions/rv32im/circuit` pass both with volatile and persistent
memory interface.
`cargo` complains that `uuid` has a conflict checksum.
I used to handle creating new blocks in a wrong way when `align >
initial_block_size`, now I hopefully do it right.
Also added persistent base alu tests, although nothing changed for the
persistent case,
and added a dummy access in all of them that used to fail.
This resolves INT-4012 by not using memory controller's memory in E1
execution.
implemented e1 and e3 for `VecHeapTwoReads` and `eq_mod` rv32 adapters.
Implemented e1 and e3 for mod-builder. Updated the `algebra` and `ecc` extensions accordingly.
Deleted all the pairing chips
All the tests successfully run. Also, added back the address space 4 loadstore tests.

Resolves INT-3914
- add codspeed walltime measurement job
- tweak execution benchmarks to be heavier and more representative
…sts) (#1659)

This resolves INT-3913.

As a _side effect_, this removes `GuestMemory` trait -- it is a struct
now with underlying `AddressMap<PAGE_SIZE>` (I didn't make `type
GuestMemory = ...` because the vaguely called `read` and `write` methods
would be too vaguely called for `AddressMap`). `VmStateMut` is generic
over `MEM` though.

I didn't fully implement `TraceStep` and `StepExecutorE1` for the
phantom chip because the chip is relatively easy and I'm not sure it
would be better expressible in terms of `NewVmChipWrapper`.

`PhantomSubExecutor` also changed a little (now accepts `u32` instead of
`F`, for example, and also `GuestMemory` instead of what it needed
before).
Implemented e1, e3 for sha2 and keccak extensions. I feel like the trace
generation of sha2 is more readable now.
Also, implemented an arbitrary length read function (used in both e1
executions)

I think eventually we should reimplement Plonky3's trace generation for
Keccak so we don't have to allocate a separate trace matrix for the perm
cols.

TODOs:

- port the tests of keccak to the new framework
- spend some time (not much) on optimizing the keccak trace gen 

Resolves INT-3966
Resolves INT-3921
- Added a `execute_metered` function that keeps a track of
`trace_heights` during execution and suspends execution if the trace
height, number of cells or number of interactions goes above a fixed
threshold

Resolves INT-3752
We removed support for memory read/writes that aren't 4-byte aligned
(except risc-v loadh, loadb), so now the keccak guest binding must
handle the input misalignment cases
Fixes misaligned calls to sha256. 
Moved Aligned_buf to openvm platform so both `sha2` and `keccak` can access it.
All the integration tests should pass now. Merged with Native's PR so
some of the tests could compile, I think for simplicity this can be
merged after the native's PR.

---------

Co-authored-by: Ayush Shukla <ayush@axiom.xyz>
Co-authored-by: Jonathan Wang <31040440+jonathanpwang@users.noreply.github.com>
…ctions (#1677)

- this is targeting `feat/new-exec-native-ext` since it was built on top
of it
Fixed todos related to porting public values chip and native adapter.
I'm guessing these are used in recursion

---------

Co-authored-by: Arayi Khalatyan <127004086+arayikhalatyan@users.noreply.github.com>
Bumped to v1.0.1 (same as main)
- added a missing pc increment step in `ModularIsEqualStep`
- total cells = max_cells_per_chip * total_chips
Rewrite native Poseidon2 chip for execution/tacegen.

---------

Co-authored-by: Alexander Golovanov <Golovanov12345@gmail.com>
We sometimes call `set_initial_memory` even with `Volatile` interface
chip. Don't know if this alone is a good design, but inside this
function we reset the tracing memory to use 8 as `initial_block_size`
and then checked that in the volatile case the memory is empty, but the
initial block size was already overwritten. This change fixes it.
- Add `InterpretedInstance` for E1/E2.
- Enforce `ExecutionControl` to be stateless.
- `InterpretedInstance` E2 is not tested because context initialization
is tricky. Will address in the future PR.

close INT-4043

---------

Co-authored-by: Jonathan Wang <31040440+jonathanpwang@users.noreply.github.com>
- use unpadded height when calculating max height and total cells during
segmentation
- use default segmentation thresholds from reth benchmark
also fixes `openvm-circuit` integration tests

- [x] fix `test_vm_hint`

---------

Co-authored-by: Alexander Golovanov <Golovanov12345@gmail.com>
Co-authored-by: Ayush Shukla <ayush@axiom.xyz>
Co-authored-by: Arayi <arayik@intrinsictech.xyz>
Maillew and others added 4 commits December 29, 2025 18:22
## Overview of new design
Implemented a new design for constraining the SHA-2 family of hash
functions (specifically SHA-256, SHA-512, SHA-384). The new design adds
incremental hasher functionality, which means we can compute the hash of
a stream of bytes. More specifically, the new `Sha256`, `Sha512`, and
`Sha384` structs provided in the SHA-2 guest library provide the
`update(&[u8])` and `finalize() -> [u8; HASH_SIZE]` methods. We can
instantiate a hasher object, `let hasher = Sha256::new()` and then call
`hasher.update(data)` as many times as we want on it. The `data`
parameter can be a slice of any size. When we would like to retrieve the
hash, we can call `hasher.finalize()`.

### Main Idea
The `Sha256` struct in the SHA-2 guest library maintains an array of
bytes that serves as the internal state of the SHA-2 hashing algorithm.
This array is updated using a new opcode: `SHA256_UPDATE dst src input`
which takes in one block of input and pointers to the src/dst hasher
states (the guest library sets `src == dst` for updating the state
in-place). The `Sha256` struct will buffer up to one block of input, and
it will call `SHA2_UPDATE` when necessary to absorb the input into the
state.

The `Sha512` and `Sha384` structs are implemented similarly.

### Interoperability
The `Sha256`, `Sha512`, `Sha384` structs implement the `sha2::Digest`
trait, allowing them to be used as a drop-in replacement for the popular
`sha2` crate's `sha2::{Sha256, Sha512, Sha384}` hasher objects.

### Documentation
The OpenVM book, specs, and the crate docs have been updated.
Additionally, a brief justification of soundness for the main
constraints has been added.

### Tests
All the SHA-2 guest library integration tests and the SHA-2 circuit unit
tests pass on CI.
Both CPU and GPU trace generation is tested among these tests.

closes INT-4972 INT-5023 INT-5024 INT-5025 INT-5026

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Jonathan Wang <31040440+jonathanpwang@users.noreply.github.com>
Co-authored-by: Ayush Shukla <shuklaayush247@gmail.com>
Co-authored-by: Alexander Golovanov <Golovanov12345@gmail.com>
Co-authored-by: Arayi Khalatyan <127004086+arayikhalatyan@users.noreply.github.com>
Co-authored-by: Ayush Shukla <ayush@axiom.xyz>
Co-authored-by: Xinding Wei <weixinding@gmail.com>
Co-authored-by: Lun-Kai Hsu <kaikaikai1219@gmail.com>
Co-authored-by: Arayi <arayik@intrinsictech.xyz>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: crStiv <cryptostiv7@gmail.com>
Co-authored-by: HrikB <23041116+HrikB@users.noreply.github.com>
Co-authored-by: Yi Sun <yi-sun@users.noreply.github.com>
Co-authored-by: stephenh-axiom-xyz <stephenh@intrinsictech.xyz>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Teo Kitanovski <teokitan@outlook.com>
Co-authored-by: Valery Cherepanov <qumidium@gmail.com>
Co-authored-by: Peyman Jabbarzade <peyman.jabarzade@gmail.com>
Co-authored-by: Valery <valery@intrinsictech.xyz>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: William Lin <63217833+Maillew@users.noreply.github.com>
A description of the `HintNonQr` and `HintSqrt` phantom instructions in
the algebra extension was missing from instruction reference. This PR
adds it.
@github-actions

This comment has been minimized.

jonathanpwang and others added 5 commits December 30, 2025 09:01
## Overview of new design
Implemented a new design for constraining the SHA-2 family of hash
functions (specifically SHA-256, SHA-512, SHA-384). The new design adds
incremental hasher functionality, which means we can compute the hash of
a stream of bytes. More specifically, the new `Sha256`, `Sha512`, and
`Sha384` structs provided in the SHA-2 guest library provide the
`update(&[u8])` and `finalize() -> [u8; HASH_SIZE]` methods. We can
instantiate a hasher object, `let hasher = Sha256::new()` and then call
`hasher.update(data)` as many times as we want on it. The `data`
parameter can be a slice of any size. When we would like to retrieve the
hash, we can call `hasher.finalize()`.

### Main Idea
The `Sha256` struct in the SHA-2 guest library maintains an array of
bytes that serves as the internal state of the SHA-2 hashing algorithm.
This array is updated using a new opcode: `SHA256_UPDATE dst src input`
which takes in one block of input and pointers to the src/dst hasher
states (the guest library sets `src == dst` for updating the state
in-place). The `Sha256` struct will buffer up to one block of input, and
it will call `SHA2_UPDATE` when necessary to absorb the input into the
state.

The `Sha512` and `Sha384` structs are implemented similarly.

### Interoperability
The `Sha256`, `Sha512`, `Sha384` structs implement the `sha2::Digest`
trait, allowing them to be used as a drop-in replacement for the popular
`sha2` crate's `sha2::{Sha256, Sha512, Sha384}` hasher objects.

### Documentation
The OpenVM book, specs, and the crate docs have been updated.
Additionally, a brief justification of soundness for the main
constraints has been added.

### Tests
All the SHA-2 guest library integration tests and the SHA-2 circuit unit
tests pass on CI.
Both CPU and GPU trace generation is tested among these tests.

closes INT-4972 INT-5023 INT-5024 INT-5025 INT-5026

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Jonathan Wang <31040440+jonathanpwang@users.noreply.github.com>
Co-authored-by: Ayush Shukla <shuklaayush247@gmail.com>
Co-authored-by: Alexander Golovanov <Golovanov12345@gmail.com>
Co-authored-by: Arayi Khalatyan <127004086+arayikhalatyan@users.noreply.github.com>
Co-authored-by: Ayush Shukla <ayush@axiom.xyz>
Co-authored-by: Xinding Wei <weixinding@gmail.com>
Co-authored-by: Lun-Kai Hsu <kaikaikai1219@gmail.com>
Co-authored-by: Arayi <arayik@intrinsictech.xyz>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: crStiv <cryptostiv7@gmail.com>
Co-authored-by: HrikB <23041116+HrikB@users.noreply.github.com>
Co-authored-by: Yi Sun <yi-sun@users.noreply.github.com>
Co-authored-by: stephenh-axiom-xyz <stephenh@intrinsictech.xyz>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Teo Kitanovski <teokitan@outlook.com>
Co-authored-by: Valery Cherepanov <qumidium@gmail.com>
Co-authored-by: Peyman Jabbarzade <peyman.jabarzade@gmail.com>
Co-authored-by: Valery <valery@intrinsictech.xyz>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: William Lin <63217833+Maillew@users.noreply.github.com>
A description of the `HintNonQr` and `HintSqrt` phantom instructions in
the algebra extension was missing from instruction reference. This PR
adds it.
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@Avaneesh-axiom Avaneesh-axiom force-pushed the feat/edwards-curve-new-execution branch from 08cf3d3 to 21d3de1 Compare December 31, 2025 05:20
@Avaneesh-axiom Avaneesh-axiom force-pushed the feat/edwards-curve-new-execution branch 2 times, most recently from 48b6fb0 to b33037e Compare December 31, 2025 05:59
@Avaneesh-axiom Avaneesh-axiom force-pushed the feat/edwards-curve-new-execution branch from b33037e to d7cd935 Compare December 31, 2025 06:26
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@Avaneesh-axiom Avaneesh-axiom force-pushed the feat/edwards-curve-new-execution branch from 442cc91 to 5030438 Compare December 31, 2025 06:55
@github-actions

This comment has been minimized.

@github-actions
Copy link

group app.proof_time_ms app.cycles app.cells_used leaf.proof_time_ms leaf.cycles leaf.cells_used
verify_fibair 234 322,610 2,058,654 - - -
fibonacci 1,072 1,500,269 2,102,750 - - -
regex 2,288 4,137,512 17,686,228 - - -
ecrecover 726 122,919 2,266,420 - - -
pairing 1,478 1,745,757 25,464,050 - - -

Commit: 79a8ceb

Benchmark Workflow

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.