Skip to content

Commit

Permalink
Add Ed25519 curve to the guest library
Browse files Browse the repository at this point in the history
  • Loading branch information
Avaneesh-axiom committed Jan 24, 2025
1 parent ad223aa commit 963e4f7
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 79 deletions.
2 changes: 2 additions & 0 deletions examples/ecc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ const CURVE_D: Edwards25519Coord = Edwards25519Coord::from_const_bytes([
64, 199, 140, 115, 254, 111, 43, 238, 108, 3, 82,
]);

// Note that we are defining the Edwards25519 curve for illustrative purposes only.
// In practice, we would use the ed25519 module which defines the Edwards25519 curve for us.
openvm_ecc_guest::te_setup::te_declare! {
Edwards25519Point {
mod_type = Edwards25519Coord,
Expand Down
1 change: 1 addition & 0 deletions extensions/ecc/guest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ k256 = ["dep:k256"]
halo2curves = ["dep:halo2curves-axiom", "openvm-algebra-guest/halo2curves"]

p256 = []
ed25519 = []
80 changes: 80 additions & 0 deletions extensions/ecc/guest/src/ed25519.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use hex_literal::hex;
#[cfg(not(target_os = "zkvm"))]
use lazy_static::lazy_static;
#[cfg(not(target_os = "zkvm"))]
use num_bigint::BigUint;
use openvm_algebra_guest::{Field, IntMod};

use super::group::{CyclicGroup, Group};

#[cfg(not(target_os = "zkvm"))]
lazy_static! {
pub static ref Ed25519_MODULUS: BigUint = BigUint::from_bytes_be(&hex!(
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED"
));
pub static ref Ed25519_ORDER: BigUint = BigUint::from_bytes_be(&hex!(
"1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED"
));
pub static ref Ed25519_A: BigUint = BigUint::from_bytes_be(&hex!(
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC"
));
pub static ref Ed25519_D: BigUint = BigUint::from_bytes_be(&hex!(
"52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3"
));
}

openvm_algebra_moduli_setup::moduli_declare! {
Ed25519Coord { modulus = "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED" },
Ed25519Scalar { modulus = "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED" },
}

pub const ED25519_NUM_LIMBS: usize = 32;
pub const ED25519_LIMB_BITS: usize = 8;
pub const ED25519_BLOCK_SIZE: usize = 32;
// from_const_bytes is little endian
pub const CURVE_A: Ed25519Coord = Ed25519Coord::from_const_bytes(hex!(
"ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F"
));
pub const CURVE_D: Ed25519Coord = Ed25519Coord::from_const_bytes(hex!(
"A3785913CA4DEB75ABD841414D0A700098E879777940C78C73FE6F2BEE6C0352"
));

openvm_ecc_te_setup::te_declare! {
Ed25519Point { mod_type = Ed25519Coord, a = CURVE_A, d = CURVE_D },
}

impl Field for Ed25519Coord {
const ZERO: Self = <Self as IntMod>::ZERO;
const ONE: Self = <Self as IntMod>::ONE;

type SelfRef<'a> = &'a Self;

fn double_assign(&mut self) {
IntMod::double_assign(self);
}

fn square_assign(&mut self) {
IntMod::square_assign(self);
}
}

impl CyclicGroup for Ed25519Point {
// from_const_bytes is little endian
const GENERATOR: Self = Ed25519Point {
x: Ed25519Coord::from_const_bytes(hex!(
"1AD5258F602D56C9B2A7259560C72C695CDCD6FD31E2A4C0FE536ECDD3366921"
)),
y: Ed25519Coord::from_const_bytes(hex!(
"5866666666666666666666666666666666666666666666666666666666666666"
)),
};
// TODO: fix
const NEG_GENERATOR: Self = Ed25519Point {
x: Ed25519Coord::from_const_bytes(hex!(
"1AD5258F602D56C9B2A7259560C72C695CDCD6FD31E2A4C0FE536ECDD3366921"
)),
y: Ed25519Coord::from_const_bytes(hex!(
"5866666666666666666666666666666666666666666666666666666666666666"
)),
};
}
3 changes: 3 additions & 0 deletions extensions/ecc/guest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ pub mod k256;
#[cfg(feature = "p256")]
pub mod p256;

#[cfg(feature = "ed25519")]
pub mod ed25519;

/// This is custom-1 defined in RISC-V spec document
pub const SW_OPCODE: u8 = 0x2b;
pub const SW_FUNCT3: u8 = 0b001;
Expand Down
5 changes: 5 additions & 0 deletions extensions/ecc/tests/programs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ default = ["std"]
std = ["serde/std", "openvm/std", "openvm-ecc-guest/std"]
k256 = ["openvm-ecc-guest/k256", "dep:k256"]
p256 = ["openvm-ecc-guest/p256"]
ed25519 = ["openvm-ecc-guest/ed25519"]

[profile.release]
panic = "abort"
Expand All @@ -57,3 +58,7 @@ required-features = ["k256"]
[[example]]
name = "ecdsa"
required-features = ["k256"]

[[example]]
name = "edwards_ec"
required-features = ["ed25519"]
102 changes: 24 additions & 78 deletions extensions/ecc/tests/programs/examples/edwards_ec.rs
Original file line number Diff line number Diff line change
@@ -1,108 +1,54 @@
#![cfg_attr(not(feature = "std"), no_main)]
#![cfg_attr(not(feature = "std"), no_std)]

use core::str::FromStr;

use num_bigint::BigUint;
use openvm_algebra_guest::{
moduli_setup::{moduli_declare, moduli_init},
Field, IntMod,
};
use hex_literal::hex;
use openvm_algebra_guest::{moduli_setup::moduli_init, IntMod};
use openvm_ecc_guest::{
ed25519::{Ed25519Coord, Ed25519Point},
edwards::TwistedEdwardsPoint,
te_setup::{te_declare, te_init},
Group,
te_setup::te_init,
CyclicGroup, Group,
};

moduli_declare! {
Edwards25519Coord { modulus = "57896044618658097711785492504343953926634992332820282019728792003956564819949" },
}

moduli_init! {
"57896044618658097711785492504343953926634992332820282019728792003956564819949",
}

impl Field for Edwards25519Coord {
const ZERO: Self = <Self as IntMod>::ZERO;
const ONE: Self = <Self as IntMod>::ONE;

type SelfRef<'a> = &'a Self;

fn double_assign(&mut self) {
IntMod::double_assign(self);
}

fn square_assign(&mut self) {
IntMod::square_assign(self);
}
}

// a = 57896044618658097711785492504343953926634992332820282019728792003956564819948
// d = 37095705934669439343138083508754565189542113879843219016388785533085940283555
// encoded in little endian, 32 limbs of 8 bits each
const CURVE_A: Edwards25519Coord = Edwards25519Coord::from_const_bytes([
236, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127,
]);
const CURVE_D: Edwards25519Coord = Edwards25519Coord::from_const_bytes([
163, 120, 89, 19, 202, 77, 235, 117, 171, 216, 65, 65, 77, 10, 112, 0, 152, 232, 121, 119, 121,
64, 199, 140, 115, 254, 111, 43, 238, 108, 3, 82,
]);

te_declare! {
Edwards25519Point {
mod_type = Edwards25519Coord,
a = CURVE_A,
d = CURVE_D
}
}

te_init! {
Edwards25519Point,
Ed25519Point,
}

openvm::entry!(main);

fn string_to_coord(s: &str) -> Edwards25519Coord {
Edwards25519Coord::from_le_bytes(&BigUint::from_str(s).unwrap().to_bytes_le())
}

pub fn main() {
setup_all_moduli();
setup_all_te_curves();

// Base point of edwards25519
let x1 = string_to_coord(
"15112221349535400772501151409588531511454012693041857206046113283949847762202",
);
let y1 = string_to_coord(
"46316835694926478169428394003475163141307993866256225615783033603165251855960",
);
let mut p1 = Ed25519Point::GENERATOR;

// random point on edwards25519
let x2 = Edwards25519Coord::from_u32(2);
let y2 = string_to_coord(
"11879831548380997166425477238087913000047176376829905612296558668626594440753",
);
let x2 = Ed25519Coord::from_u32(2);
let y2 = Ed25519Coord::from_be_bytes(&hex!(
"1A43BF127BDDC4D71FF910403C11DDB5BA2BCDD2815393924657EF111E712631"
));
let mut p2 = Ed25519Point::from_xy(x2, y2).unwrap();

// This is the sum of (x1, y1) and (x2, y2).
let x3 = string_to_coord(
"44969869612046584870714054830543834361257841801051546235130567688769346152934",
);
let y3 = string_to_coord(
"50796027728050908782231253190819121962159170739537197094456293084373503699602",
);
let x3 = Ed25519Coord::from_be_bytes(&hex!(
"636C0B519B2C5B1E0D3BFD213F45AFD5DAEE3CECC9B68CF88615101BC78329E6"
));
let y3 = Ed25519Coord::from_be_bytes(&hex!(
"704D8868CB335A7B609D04B9CD619511675691A78861F1DFF7A5EBC389C7EA92"
));

// This is 2 * (x1, y1)
let x4 = string_to_coord(
"39226743113244985161159605482495583316761443760287217110659799046557361995496",
);
let y4 = string_to_coord(
"12570354238812836652656274015246690354874018829607973815551555426027032771563",
);

let mut p1 = Edwards25519Point::from_xy(x1.clone(), y1.clone()).unwrap();
let mut p2 = Edwards25519Point::from_xy(x2, y2).unwrap();
let x4 = Ed25519Coord::from_be_bytes(&hex!(
"56B98CC045559AD2BBC45CAB58D842ECEE264DB9395F6014B772501B62BB7EE8"
));
let y4 = Ed25519Coord::from_be_bytes(&hex!(
"1BCA918096D89C83A15105DF343DC9F7510494407750226DAC0A7620ACE77BEB"
));

// Generic add can handle equal or unequal points.
let p3 = &p1 + &p2;
Expand Down
2 changes: 1 addition & 1 deletion extensions/ecc/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ mod tests {
let elf = build_example_program_at_path_with_features::<&str>(
get_programs_dir!(),
"edwards_ec",
[],
["ed25519"],
)?;
let openvm_exe = VmExe::from_elf(
elf,
Expand Down

0 comments on commit 963e4f7

Please sign in to comment.