diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index b40ab41b87..c3743d2256 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -19,7 +19,12 @@ # Using Extensions -- [Customizable Extensions](./custom-extensions/overview.md) +- [Overview](./custom-extensions/overview.md) +- [Keccak](./custom-extensions/keccak.md) +- [Big Integer](./custom-extensions/bigint.md) +- [Algebra](./custom-extensions/algebra.md) +- [Elliptic Curve Cryptography](./custom-extensions/ecc.md) +- [Elliptic Curve Pairing](./custom-extensions/pairing.md) # Advanced Usage diff --git a/book/src/custom-extensions/ecc.md b/book/src/custom-extensions/ecc.md index 9dc1e3453b..6e37c13fc1 100644 --- a/book/src/custom-extensions/ecc.md +++ b/book/src/custom-extensions/ecc.md @@ -1,6 +1,33 @@ # OpenVM ECC -For elliptic curve cryptography, the `openvm-ecc` crate provides macros similar to those in [`openvm-algebra`](./algebra.md): +The OpenVM Elliptic Curve Cryptography Extension provides support for elliptic curve operations through the `openvm-ecc-guest` crate. + +## Available traits and methods + +- `Group` trait: + This represents an element of a [group]() where the operation is addition. Therefore the trait includes functions for `add`, `sub`, and `double`. + + - `IDENTITY` is the identity element of the group. + +- `CyclicGroup` trait: + It's a group that has a generator, so it defines `GENERATOR` and `NEG_GENERATOR`. + +- `WeierstrassPoint` trait: + It represents an affine point on a Weierstrass elliptic curve and it extends `Group`. + + - `Coordinate` type is the type of the coordinates of the point, and it implements `IntMod`. + - `x()`, `y()` are used to get the affine coordinates + - `from_xy` is a constructor for the point, which checks if the point is either identity or on the affine curve. + - The point supports elliptic curve operations through intrinsic functions `add_ne_nonidentity` and `double_nonidentity`. + - `decompress`: Sometimes an elliptic curve point is compressed and represented by its `x` coordinate and the odd/even parity of the `y` coordinate. `decompress` is used to decompress the point back to `(x, y)`. + +- `msm`: for multi-scalar multiplication. + +- `ecdsa`: for doing ECDSA signature verification and public key recovery from signature. + +## Macros + +For elliptic curve cryptography, the `openvm-ecc-guest` crate provides macros similar to those in [`openvm-algebra-guest`](./algebra.md): 1. **Declare**: Use `sw_declare!` to define elliptic curves over the previously declared moduli. For example: @@ -12,6 +39,7 @@ sw_declare! { ``` Each declared curve must specify the `mod_type` (implementing `IntMod`) and a constant `b` for the Weierstrass curve equation $y^2 = x^3 + b$. +This creates `Bls12_381G1Affine` and `Bn254G1Affine` structs which implement the `Group` and `WeierstrassPoint` traits. The underlying memory layout of the structs uses the memory layout of the `Bls12_381Fp` and `Bn254Fp` structs, respectively. 2. **Init**: Called once, it enumerates these curves and allows the compiler to produce optimized instructions: @@ -28,3 +56,60 @@ sw_init! { - `sw_declare!`: Declares elliptic curve structures. - `sw_init!`: Initializes them once, linking them to the underlying moduli. - `setup_sw_()`/`setup_all_curves()`: Secures runtime correctness. + +To use elliptic curve operations on a struct defined with `sw_declare!`, it is expected that the struct for the curve's coordinate field was defined using `moduli_declare!`. In particular, the coordinate field needs to be initialized and set up as described in the [algebra extension](./algebra.md) chapter. + +For the basic operations provided by the `WeierstrassPoint` trait, the scalar field is not needed. For the ECDSA functions in the `ecdsa` module, the scalar field must also be declared, initialized, and set up. + +## Example program + +See a working example [here](https://github.com/openvm-org/openvm/blob/main/crates/toolchain/tests/programs/examples/ec.rs). + +To use the ECC extension, add the following dependencies to `Cargo.toml`: + +```toml +openvm-algebra-guest = { git = "https://github.com/openvm-org/openvm.git" } +openvm-ecc-guest = { git = "https://github.com/openvm-org/openvm.git", features = ["k256"] } +``` + +One can define their own ECC structs but we will use the Secp256k1 struct from `openvm-ecc-guest` and thus the `k256` feature should be enabled. + +```rust +use openvm_ecc_guest::{ + k256::{Secp256k1Coord, Secp256k1Point, Secp256k1Scalar}, + Group, weierstrass::WeierstrassPoint, +}; + +openvm_algebra_guest::moduli_setup::moduli_init! { + "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F", + "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141" +} + +openvm_ecc_guest::sw_setup::sw_init! { + Secp256k1Coord, +} +``` + +We `moduli_init!` both the coordinate and scalar field because they were declared in the `k256` module, although we will not be using the scalar field below. + +With the above we can start doing elliptic curve operations like adding points: + +```rust +pub fn main() { + setup_all_moduli(); + setup_all_curves(); + let x1 = Secp256k1Coord::from_u32(1); + let y1 = Secp256k1Coord::from_le_bytes(&hex!( + "EEA7767E580D75BC6FDD7F58D2A84C2614FB22586068DB63B346C6E60AF21842" + )); + let p1 = Secp256k1Point::from_xy_nonidentity(x1, y1).unwrap(); + + let x2 = Secp256k1Coord::from_u32(2); + let y2 = Secp256k1Coord::from_le_bytes(&hex!( + "D1A847A8F879E0AEE32544DA5BA0B3BD1703A1F52867A5601FF6454DD8180499" + )); + let p2 = Secp256k1Point::from_xy_nonidentity(x2, y2).unwrap(); + + let p3 = &p1 + &p2; +} +``` diff --git a/book/src/custom-extensions/overview.md b/book/src/custom-extensions/overview.md index a23da253f6..2b5c427d0c 100644 --- a/book/src/custom-extensions/overview.md +++ b/book/src/custom-extensions/overview.md @@ -2,7 +2,17 @@ You can seamlessly integrate certain performance-optimized extensions maintained by the OpenVM team to enhance your arithmetic operations and cryptographic computations. -Certain arithmetic operations, particularly modular arithmetic, can be optimized significantly when the modulus is known at compile time. This approach requires a framework to inform the compiler about all the moduli and associated arithmetic structures we intend to use. To achieve this, three steps are involved: +In this chapter, we will explain how to use the following existing extensions: + +- [`openvm-keccak-guest`](./keccak.md) - Keccak256 hash function. +- [`openvm-bigint-guest`](./bigint.md) - Big integer arithmetic for 256-bit signed and unsigned integers. +- [`openvm-algebra-guest`](./algebra.md) - Modular arithmetic and complex field extensions. +- [`openvm-ecc-guest`](./ecc.md) - Elliptic curve cryptography. +- [`openvm-pairing-guest`](./pairing.md) - Elliptic curve optimal Ate pairings. + +Some extensions such as `openvm-keccak-guest` and `openvm-bigint-guest` can be enabled without specifying any additional configuration. + +On the other hand certain arithmetic operations, particularly modular arithmetic, can be optimized significantly when the modulus is known at compile time. This approach requires a framework to inform the compiler about all the moduli and associated arithmetic structures we intend to use. To achieve this, three steps are involved: 1. **Declare**: Introduce a modular arithmetic or related structure, along with its modulus and functionality. This can be done in any library or binary file. 2. **Init**: Performed exactly once in the final binary. It aggregates all previously declared structures, assigns them stable indices, and sets up linkage so that they can be referenced in generated code. @@ -10,10 +20,4 @@ Certain arithmetic operations, particularly modular arithmetic, can be optimized These steps ensure both performance and security: performance because the modulus is known at compile time, and security because runtime checks confirm that the correct structures have been initialized. -The list of existing extensions: - -- [`openvm-algebra`](./algebra.md) -- [`openvm-bigint`](./bigint.md) -- [`openvm-keccak`](./keccak.md) -- [`openvm-pairing`](./pairing.md) -- [`openvm-ecc`](./ecc.md) +Our design for the configuration procedure above was inspired by the [EVMMAX proposal](https://github.com/jwasinger/EIPs/blob/evmmax-2/EIPS/eip-6601.md).