Skip to content

Commit 4bb302d

Browse files
Add Ed25519 curve to the guest library
1 parent ad223aa commit 4bb302d

File tree

7 files changed

+110
-79
lines changed

7 files changed

+110
-79
lines changed

examples/ecc/src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ const CURVE_D: Edwards25519Coord = Edwards25519Coord::from_const_bytes([
5151
64, 199, 140, 115, 254, 111, 43, 238, 108, 3, 82,
5252
]);
5353

54+
// Note that we are defining the Edwards25519 curve for illustrative purposes only.
55+
// In practice, we would use the ed25519 module which defines the Edwards25519 curve for us.
5456
openvm_ecc_guest::te_setup::te_declare! {
5557
Edwards25519Point {
5658
mod_type = Edwards25519Coord,

extensions/ecc/guest/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,4 @@ k256 = ["dep:k256"]
4646
halo2curves = ["dep:halo2curves-axiom", "openvm-algebra-guest/halo2curves"]
4747

4848
p256 = []
49+
ed25519 = []

extensions/ecc/guest/src/ed25519.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use hex_literal::hex;
2+
#[cfg(not(target_os = "zkvm"))]
3+
use lazy_static::lazy_static;
4+
#[cfg(not(target_os = "zkvm"))]
5+
use num_bigint::BigUint;
6+
use openvm_algebra_guest::{Field, IntMod};
7+
8+
use super::group::{CyclicGroup, Group};
9+
10+
#[cfg(not(target_os = "zkvm"))]
11+
lazy_static! {
12+
pub static ref Ed25519_MODULUS: BigUint = BigUint::from_bytes_be(&hex!(
13+
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED"
14+
));
15+
pub static ref Ed25519_ORDER: BigUint = BigUint::from_bytes_be(&hex!(
16+
"1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED"
17+
));
18+
}
19+
20+
openvm_algebra_moduli_setup::moduli_declare! {
21+
Ed25519Coord { modulus = "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED" },
22+
Ed25519Scalar { modulus = "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED" },
23+
}
24+
25+
pub const ED25519_NUM_LIMBS: usize = 32;
26+
pub const ED25519_LIMB_BITS: usize = 8;
27+
pub const ED25519_BLOCK_SIZE: usize = 32;
28+
// from_const_bytes is little endian
29+
pub const CURVE_A: Ed25519Coord = Ed25519Coord::from_const_bytes(hex!(
30+
"ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F"
31+
));
32+
pub const CURVE_D: Ed25519Coord = Ed25519Coord::from_const_bytes(hex!(
33+
"A3785913CA4DEB75ABD841414D0A700098E879777940C78C73FE6F2BEE6C0352"
34+
));
35+
36+
openvm_ecc_te_setup::te_declare! {
37+
Ed25519Point { mod_type = Ed25519Coord, a = CURVE_A, d = CURVE_D },
38+
}
39+
40+
impl Field for Ed25519Coord {
41+
const ZERO: Self = <Self as IntMod>::ZERO;
42+
const ONE: Self = <Self as IntMod>::ONE;
43+
44+
type SelfRef<'a> = &'a Self;
45+
46+
fn double_assign(&mut self) {
47+
IntMod::double_assign(self);
48+
}
49+
50+
fn square_assign(&mut self) {
51+
IntMod::square_assign(self);
52+
}
53+
}
54+
55+
impl CyclicGroup for Ed25519Point {
56+
// from_const_bytes is little endian
57+
const GENERATOR: Self = Ed25519Point {
58+
x: Ed25519Coord::from_const_bytes(hex!(
59+
"1AD5258F602D56C9B2A7259560C72C695CDCD6FD31E2A4C0FE536ECDD3366921"
60+
)),
61+
y: Ed25519Coord::from_const_bytes(hex!(
62+
"5866666666666666666666666666666666666666666666666666666666666666"
63+
)),
64+
};
65+
// TODO: fix
66+
const NEG_GENERATOR: Self = Ed25519Point {
67+
x: Ed25519Coord::from_const_bytes(hex!(
68+
"1AD5258F602D56C9B2A7259560C72C695CDCD6FD31E2A4C0FE536ECDD3366921"
69+
)),
70+
y: Ed25519Coord::from_const_bytes(hex!(
71+
"5866666666666666666666666666666666666666666666666666666666666666"
72+
)),
73+
};
74+
}

extensions/ecc/guest/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ pub mod k256;
3232
#[cfg(feature = "p256")]
3333
pub mod p256;
3434

35+
#[cfg(feature = "ed25519")]
36+
pub mod ed25519;
37+
3538
/// This is custom-1 defined in RISC-V spec document
3639
pub const SW_OPCODE: u8 = 0x2b;
3740
pub const SW_FUNCT3: u8 = 0b001;

extensions/ecc/tests/programs/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ default = ["std"]
3232
std = ["serde/std", "openvm/std", "openvm-ecc-guest/std"]
3333
k256 = ["openvm-ecc-guest/k256", "dep:k256"]
3434
p256 = ["openvm-ecc-guest/p256"]
35+
ed25519 = ["openvm-ecc-guest/ed25519"]
3536

3637
[profile.release]
3738
panic = "abort"
@@ -57,3 +58,7 @@ required-features = ["k256"]
5758
[[example]]
5859
name = "ecdsa"
5960
required-features = ["k256"]
61+
62+
[[example]]
63+
name = "edwards_ec"
64+
required-features = ["ed25519"]

extensions/ecc/tests/programs/examples/edwards_ec.rs

Lines changed: 24 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,54 @@
11
#![cfg_attr(not(feature = "std"), no_main)]
22
#![cfg_attr(not(feature = "std"), no_std)]
33

4-
use core::str::FromStr;
5-
6-
use num_bigint::BigUint;
7-
use openvm_algebra_guest::{
8-
moduli_setup::{moduli_declare, moduli_init},
9-
Field, IntMod,
10-
};
4+
use hex_literal::hex;
5+
use openvm_algebra_guest::{moduli_setup::moduli_init, IntMod};
116
use openvm_ecc_guest::{
7+
ed25519::{Ed25519Coord, Ed25519Point},
128
edwards::TwistedEdwardsPoint,
13-
te_setup::{te_declare, te_init},
14-
Group,
9+
te_setup::te_init,
10+
CyclicGroup, Group,
1511
};
1612

17-
moduli_declare! {
18-
Edwards25519Coord { modulus = "57896044618658097711785492504343953926634992332820282019728792003956564819949" },
19-
}
20-
2113
moduli_init! {
2214
"57896044618658097711785492504343953926634992332820282019728792003956564819949",
2315
}
2416

25-
impl Field for Edwards25519Coord {
26-
const ZERO: Self = <Self as IntMod>::ZERO;
27-
const ONE: Self = <Self as IntMod>::ONE;
28-
29-
type SelfRef<'a> = &'a Self;
30-
31-
fn double_assign(&mut self) {
32-
IntMod::double_assign(self);
33-
}
34-
35-
fn square_assign(&mut self) {
36-
IntMod::square_assign(self);
37-
}
38-
}
39-
40-
// a = 57896044618658097711785492504343953926634992332820282019728792003956564819948
41-
// d = 37095705934669439343138083508754565189542113879843219016388785533085940283555
42-
// encoded in little endian, 32 limbs of 8 bits each
43-
const CURVE_A: Edwards25519Coord = Edwards25519Coord::from_const_bytes([
44-
236, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
45-
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127,
46-
]);
47-
const CURVE_D: Edwards25519Coord = Edwards25519Coord::from_const_bytes([
48-
163, 120, 89, 19, 202, 77, 235, 117, 171, 216, 65, 65, 77, 10, 112, 0, 152, 232, 121, 119, 121,
49-
64, 199, 140, 115, 254, 111, 43, 238, 108, 3, 82,
50-
]);
51-
52-
te_declare! {
53-
Edwards25519Point {
54-
mod_type = Edwards25519Coord,
55-
a = CURVE_A,
56-
d = CURVE_D
57-
}
58-
}
59-
6017
te_init! {
61-
Edwards25519Point,
18+
Ed25519Point,
6219
}
6320

6421
openvm::entry!(main);
6522

66-
fn string_to_coord(s: &str) -> Edwards25519Coord {
67-
Edwards25519Coord::from_le_bytes(&BigUint::from_str(s).unwrap().to_bytes_le())
68-
}
69-
7023
pub fn main() {
7124
setup_all_moduli();
7225
setup_all_te_curves();
7326

7427
// Base point of edwards25519
75-
let x1 = string_to_coord(
76-
"15112221349535400772501151409588531511454012693041857206046113283949847762202",
77-
);
78-
let y1 = string_to_coord(
79-
"46316835694926478169428394003475163141307993866256225615783033603165251855960",
80-
);
28+
let mut p1 = Ed25519Point::GENERATOR;
8129

8230
// random point on edwards25519
83-
let x2 = Edwards25519Coord::from_u32(2);
84-
let y2 = string_to_coord(
85-
"11879831548380997166425477238087913000047176376829905612296558668626594440753",
86-
);
31+
let x2 = Ed25519Coord::from_u32(2);
32+
let y2 = Ed25519Coord::from_be_bytes(&hex!(
33+
"1A43BF127BDDC4D71FF910403C11DDB5BA2BCDD2815393924657EF111E712631"
34+
));
35+
let mut p2 = Ed25519Point::from_xy(x2, y2).unwrap();
8736

8837
// This is the sum of (x1, y1) and (x2, y2).
89-
let x3 = string_to_coord(
90-
"44969869612046584870714054830543834361257841801051546235130567688769346152934",
91-
);
92-
let y3 = string_to_coord(
93-
"50796027728050908782231253190819121962159170739537197094456293084373503699602",
94-
);
38+
let x3 = Ed25519Coord::from_be_bytes(&hex!(
39+
"636C0B519B2C5B1E0D3BFD213F45AFD5DAEE3CECC9B68CF88615101BC78329E6"
40+
));
41+
let y3 = Ed25519Coord::from_be_bytes(&hex!(
42+
"704D8868CB335A7B609D04B9CD619511675691A78861F1DFF7A5EBC389C7EA92"
43+
));
9544

9645
// This is 2 * (x1, y1)
97-
let x4 = string_to_coord(
98-
"39226743113244985161159605482495583316761443760287217110659799046557361995496",
99-
);
100-
let y4 = string_to_coord(
101-
"12570354238812836652656274015246690354874018829607973815551555426027032771563",
102-
);
103-
104-
let mut p1 = Edwards25519Point::from_xy(x1.clone(), y1.clone()).unwrap();
105-
let mut p2 = Edwards25519Point::from_xy(x2, y2).unwrap();
46+
let x4 = Ed25519Coord::from_be_bytes(&hex!(
47+
"56B98CC045559AD2BBC45CAB58D842ECEE264DB9395F6014B772501B62BB7EE8"
48+
));
49+
let y4 = Ed25519Coord::from_be_bytes(&hex!(
50+
"1BCA918096D89C83A15105DF343DC9F7510494407750226DAC0A7620ACE77BEB"
51+
));
10652

10753
// Generic add can handle equal or unequal points.
10854
let p3 = &p1 + &p2;

extensions/ecc/tests/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ mod tests {
152152
let elf = build_example_program_at_path_with_features::<&str>(
153153
get_programs_dir!(),
154154
"edwards_ec",
155-
[],
155+
["ed25519"],
156156
)?;
157157
let openvm_exe = VmExe::from_elf(
158158
elf,

0 commit comments

Comments
 (0)