From 7ec0bb98628f98e6195d134416c43a0587097de0 Mon Sep 17 00:00:00 2001 From: luffykai Date: Sun, 15 Dec 2024 11:35:12 -0800 Subject: [PATCH 1/5] book section on ecc guest --- book/src/using-extensions/ecc-extension.md | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 book/src/using-extensions/ecc-extension.md diff --git a/book/src/using-extensions/ecc-extension.md b/book/src/using-extensions/ecc-extension.md new file mode 100644 index 0000000000..e5401fddd6 --- /dev/null +++ b/book/src/using-extensions/ecc-extension.md @@ -0,0 +1,54 @@ +# The ECC Extension + +The ECC extension provides support for elliptic curve operations. This guide will show you how to use it in your guest programs. See a working example [here](https://github.com/openvm-org/openvm/blob/c19c9ac60b135bb0f38fc997df5eb149db8144b4/crates/toolchain/tests/programs/examples/ec.rs). + +## Setup + +Steps to setup a guest program can be found [here](../writing-apps/write-program.md#guest-program-setup). +Additionally, to use the ECC extension, add the following dependencies to `Cargo.toml`: + +```toml +openvm-algebra-moduli-setup = { git = "https://github.com/openvm-org/openvm.git" } +openvm-ecc-sw-setup = { git = "https://github.com/openvm-org/openvm.git" } +openvm-algebra-guest = { git = "https://github.com/openvm-org/openvm.git" } +openvm-ecc-guest = { git = "https://github.com/openvm-org/openvm.git" } +``` + +Previous [section](./customizable-extensions.md) explains how to use macros like `moduli_declare!` and `sw_declare!` to declare ECC structs and their moduli. One can define their own ECC structs but we will use the Secp256k1 struct from `openvm-ecc-guest`. + +```rust +use openvm_ecc_guest::{ + k256::{Secp256k1Coord, Secp256k1Point, Secp256k1Scalar} + Group, +}; + +openvm_algebra_moduli_setup::moduli_init! { + "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F", + "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141" +} + +openvm_ecc_sw_setup::sw_init! { + Secp256k1Coord, +} +``` + +With the above we can start doing elliptic curve operations like adding points: +```rust +let x1 = Secp256k1Coord::from_u32(1); +let y1 = Secp256k1Coord::from_le_bytes(&hex!( + "EEA7767E580D75BC6FDD7F58D2A84C2614FB22586068DB63B346C6E60AF21842" +)); +let p1 = Secp256k1Point { x: x1, y: y1 }; + +let x2 = Secp256k1Coord::from_u32(2); +let y2 = Secp256k1Coord::from_le_bytes(&hex!( + "D1A847A8F879E0AEE32544DA5BA0B3BD1703A1F52867A5601FF6454DD8180499" +)); +let p2 = Secp256k1Point { x: x2, y: y2 }; + +let p3 = &p1 + &p2; +``` + +Some additional functionalities like scalar multiplication and ECDSA are also supported. + +## Run the program \ No newline at end of file From 116106a8af33cac971c7a33ab6597eb5d6bbe119 Mon Sep 17 00:00:00 2001 From: luffykai Date: Sun, 15 Dec 2024 13:45:12 -0800 Subject: [PATCH 2/5] update --- book/src/custom-extensions/ecc.md | 75 ++++++++++++++++++++++ book/src/using-extensions/ecc-extension.md | 54 ---------------- 2 files changed, 75 insertions(+), 54 deletions(-) delete mode 100644 book/src/using-extensions/ecc-extension.md diff --git a/book/src/custom-extensions/ecc.md b/book/src/custom-extensions/ecc.md index 9dc1e3453b..8357bc0436 100644 --- a/book/src/custom-extensions/ecc.md +++ b/book/src/custom-extensions/ecc.md @@ -1,5 +1,29 @@ # OpenVM ECC +The OpenVM Elliptic Curve Cryptography Extension provides support for elliptic curve operations. + +## Available traits and methods + +- `Group` trait: + This represents an element of a algebraic additive group. Therefore it should implements `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's represents a point on a Weierstrass curve, so it extends `Group`. + - `Coordinate` type is the type of the coordinates of the point, and it implements `IntMod`. + - `x`, `y`, `from_xy` methods are used to get the coordinates and construct a point. + - The point supports elliptic curve operations with `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 public key recovery. + +## Macros + For elliptic curve cryptography, the `openvm-ecc` crate provides macros similar to those in [`openvm-algebra`](./algebra.md): 1. **Declare**: Use `sw_declare!` to define elliptic curves over the previously declared moduli. For example: @@ -28,3 +52,54 @@ 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. + +## Example program + +See a working example [here](https://github.com/openvm-org/openvm/blob/c19c9ac60b135bb0f38fc997df5eb149db8144b4/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, +}; + +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, +} +``` + +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 { x: x1, y: y1 }; + + let x2 = Secp256k1Coord::from_u32(2); + let y2 = Secp256k1Coord::from_le_bytes(&hex!( + "D1A847A8F879E0AEE32544DA5BA0B3BD1703A1F52867A5601FF6454DD8180499" + )); + let p2 = Secp256k1Point { x: x2, y: y2 }; + + let p3 = &p1 + &p2; +} +``` diff --git a/book/src/using-extensions/ecc-extension.md b/book/src/using-extensions/ecc-extension.md deleted file mode 100644 index e5401fddd6..0000000000 --- a/book/src/using-extensions/ecc-extension.md +++ /dev/null @@ -1,54 +0,0 @@ -# The ECC Extension - -The ECC extension provides support for elliptic curve operations. This guide will show you how to use it in your guest programs. See a working example [here](https://github.com/openvm-org/openvm/blob/c19c9ac60b135bb0f38fc997df5eb149db8144b4/crates/toolchain/tests/programs/examples/ec.rs). - -## Setup - -Steps to setup a guest program can be found [here](../writing-apps/write-program.md#guest-program-setup). -Additionally, to use the ECC extension, add the following dependencies to `Cargo.toml`: - -```toml -openvm-algebra-moduli-setup = { git = "https://github.com/openvm-org/openvm.git" } -openvm-ecc-sw-setup = { git = "https://github.com/openvm-org/openvm.git" } -openvm-algebra-guest = { git = "https://github.com/openvm-org/openvm.git" } -openvm-ecc-guest = { git = "https://github.com/openvm-org/openvm.git" } -``` - -Previous [section](./customizable-extensions.md) explains how to use macros like `moduli_declare!` and `sw_declare!` to declare ECC structs and their moduli. One can define their own ECC structs but we will use the Secp256k1 struct from `openvm-ecc-guest`. - -```rust -use openvm_ecc_guest::{ - k256::{Secp256k1Coord, Secp256k1Point, Secp256k1Scalar} - Group, -}; - -openvm_algebra_moduli_setup::moduli_init! { - "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F", - "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141" -} - -openvm_ecc_sw_setup::sw_init! { - Secp256k1Coord, -} -``` - -With the above we can start doing elliptic curve operations like adding points: -```rust -let x1 = Secp256k1Coord::from_u32(1); -let y1 = Secp256k1Coord::from_le_bytes(&hex!( - "EEA7767E580D75BC6FDD7F58D2A84C2614FB22586068DB63B346C6E60AF21842" -)); -let p1 = Secp256k1Point { x: x1, y: y1 }; - -let x2 = Secp256k1Coord::from_u32(2); -let y2 = Secp256k1Coord::from_le_bytes(&hex!( - "D1A847A8F879E0AEE32544DA5BA0B3BD1703A1F52867A5601FF6454DD8180499" -)); -let p2 = Secp256k1Point { x: x2, y: y2 }; - -let p3 = &p1 + &p2; -``` - -Some additional functionalities like scalar multiplication and ECDSA are also supported. - -## Run the program \ No newline at end of file From 62189f693d05a7d5ed164dae2bf68b7bad7ded28 Mon Sep 17 00:00:00 2001 From: luffykai Date: Sun, 15 Dec 2024 15:13:55 -0800 Subject: [PATCH 3/5] use from xy --- book/src/custom-extensions/ecc.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/book/src/custom-extensions/ecc.md b/book/src/custom-extensions/ecc.md index 8357bc0436..9c747eedc7 100644 --- a/book/src/custom-extensions/ecc.md +++ b/book/src/custom-extensions/ecc.md @@ -68,8 +68,8 @@ One can define their own ECC structs but we will use the Secp256k1 struct from ` ```rust use openvm_ecc_guest::{ - k256::{Secp256k1Coord, Secp256k1Point, Secp256k1Scalar} - Group, + k256::{Secp256k1Coord, Secp256k1Point, Secp256k1Scalar}, + Group, weierstrass::WeierstrassPoint, }; openvm_algebra_guest::moduli_setup::moduli_init! { @@ -92,13 +92,13 @@ pub fn main() { let y1 = Secp256k1Coord::from_le_bytes(&hex!( "EEA7767E580D75BC6FDD7F58D2A84C2614FB22586068DB63B346C6E60AF21842" )); - let p1 = Secp256k1Point { x: x1, y: y1 }; + 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 { x: x2, y: y2 }; + let p2 = Secp256k1Point::from_xy_nonidentity(x2, y2).unwrap(); let p3 = &p1 + &p2; } From ad90b3a1a2d396c7de318e204306bf48b4b42e47 Mon Sep 17 00:00:00 2001 From: Jonathan Wang <31040440+jonathanpwang@users.noreply.github.com> Date: Sun, 15 Dec 2024 16:32:20 -0800 Subject: [PATCH 4/5] Apply suggestions from code review --- book/src/custom-extensions/ecc.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/book/src/custom-extensions/ecc.md b/book/src/custom-extensions/ecc.md index 9c747eedc7..e5a71a916d 100644 --- a/book/src/custom-extensions/ecc.md +++ b/book/src/custom-extensions/ecc.md @@ -1,30 +1,31 @@ # OpenVM ECC -The OpenVM Elliptic Curve Cryptography Extension provides support for elliptic curve operations. +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 algebraic additive group. Therefore it should implements `add`, `sub`, and `double`. + This represents an element of a [group](https://en.wikipedia.org/wiki/Group_(mathematics)) 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's represents a point on a Weierstrass curve, so it extends `Group`. + 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`, `from_xy` methods are used to get the coordinates and construct a point. - - The point supports elliptic curve operations with `add_ne_nonidentity` and `double_nonidentity`. + - `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 public key recovery. +- `ecdsa`: for doing ECDSA signature verification and public key recovery from signature. ## Macros -For elliptic curve cryptography, the `openvm-ecc` crate provides macros similar to those in [`openvm-algebra`](./algebra.md): +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: @@ -55,7 +56,7 @@ sw_init! { ## Example program -See a working example [here](https://github.com/openvm-org/openvm/blob/c19c9ac60b135bb0f38fc997df5eb149db8144b4/crates/toolchain/tests/programs/examples/ec.rs). +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`: From f4cc3f845a11437d383f899aea2a36af7209e214 Mon Sep 17 00:00:00 2001 From: Jonathan Wang <31040440+jonathanpwang@users.noreply.github.com> Date: Sun, 15 Dec 2024 20:01:00 -0500 Subject: [PATCH 5/5] feat: add more explanations --- book/src/SUMMARY.md | 7 ++++++- book/src/custom-extensions/ecc.md | 27 +++++++++++++++++--------- book/src/custom-extensions/overview.md | 20 +++++++++++-------- 3 files changed, 36 insertions(+), 18 deletions(-) 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 e5a71a916d..6e37c13fc1 100644 --- a/book/src/custom-extensions/ecc.md +++ b/book/src/custom-extensions/ecc.md @@ -5,19 +5,21 @@ The OpenVM Elliptic Curve Cryptography Extension provides support for elliptic c ## Available traits and methods - `Group` trait: - This represents an element of a [group](https://en.wikipedia.org/wiki/Group_(mathematics)) where the operation is addition. Therefore the trait includes functions for `add`, `sub`, and `double`. - - `IDENTITY` is the identity element of the group. + 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`. + 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)`. + 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. @@ -37,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: @@ -54,6 +57,10 @@ sw_init! { - `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). @@ -83,6 +90,8 @@ openvm_ecc_guest::sw_setup::sw_init! { } ``` +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 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).