Elliptic Curve Cryptography
The OpenVM Elliptic Curve Cryptography Extension provides support for elliptic curve operations through the openvm-ecc-guest
crate.
Developers can enable arbitrary Weierstrass curves by configuring this extension with the modulus for the coordinate field and the coefficients in the curve equation. Preset configurations for the secp256k1 and secp256r1 curves are provided through the K256 and P256 guest libraries.
Available traits and methods
-
Group
trait: This represents an element of a group where the operation is addition. Therefore the trait includes functions foradd
,sub
, anddouble
.IDENTITY
is the identity element of the group.
-
CyclicGroup
trait: It's a group that has a generator, so it definesGENERATOR
andNEG_GENERATOR
. -
WeierstrassPoint
trait: It represents an affine point on a Weierstrass elliptic curve and it extendsGroup
.Coordinate
type is the type of the coordinates of the point, and it implementsIntMod
.x()
,y()
are used to get the affine coordinatesfrom_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
anddouble_nonidentity
. decompress
: Sometimes an elliptic curve point is compressed and represented by itsx
coordinate and the odd/even parity of they
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
:
- Declare: Use
sw_declare!
to define elliptic curves over the previously declared moduli. For example:
#![allow(unused)] fn main() { sw_declare! { Bls12_381G1Affine { mod_type = Bls12_381Fp, b = BLS12_381_B }, P256Affine { mod_type = P256Coord, a = P256_A, b = P256_B }, } }
Each declared curve must specify the mod_type
(implementing IntMod
) and a constant b
for the Weierstrass curve equation \(y^2 = x^3 + ax + b\). a
is optional and defaults to 0 for short Weierstrass curves.
This creates Bls12_381G1Affine
and P256Affine
structs which implement the Group
and WeierstrassPoint
traits. The underlying memory layout of the structs uses the memory layout of the Bls12_381Fp
and P256Coord
structs, respectively.
- Init: Called once, the
openvm::init!
macro produces a call tosw_init!
that enumerates these curves and allows the compiler to produce optimized instructions:
#![allow(unused)] fn main() { openvm::init!(); /* This expands to sw_init! { Bls12_381G1Affine, P256Affine, } */ }
Summary:
sw_declare!
: Declares elliptic curve structures.init!
: Initializes them once, linking them to the underlying moduli.
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 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.
ECDSA
The ECC extension supports ECDSA signature verification on any elliptic curve, and pre-defined implementations are provided for the secp256k1 and secp256r1 curves.
To verify an ECDSA signature, first call the VerifyingKey::recover_from_prehash_noverify
associated function to recover the verifying key, then call the VerifyingKey::verify_prehashed
method on the recovered verifying key.