Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use RISC Zero BigInt multiplier to accelerate p256 within the zkVM guest #5

Open
wants to merge 12 commits into
base: risczero
Choose a base branch
from
14 changes: 11 additions & 3 deletions p256/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ edition = "2021"
rust-version = "1.65"

[dependencies]
cfg-if = "1.0"
elliptic-curve = { version = "0.13.8", default-features = false, features = ["hazmat", "sec1"] }

# optional dependencies
once_cell = { version = "1.19", optional = true, default-features = false }
ecdsa-core = { version = "0.16", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
hex-literal = { version = "0.4", optional = true }
primeorder = { version = "0.13", optional = true, path = "../primeorder" }
Expand All @@ -28,17 +30,23 @@ sha2 = { version = "0.10", optional = true, default-features = false }

[dev-dependencies]
blobby = "0.3"
criterion = "0.5"
ecdsa-core = { version = "0.16", package = "ecdsa", default-features = false, features = ["dev"] }
hex-literal = "0.4"
primeorder = { version = "0.13.5", features = ["dev"], path = "../primeorder" }
proptest = "1"
rand_core = { version = "0.6", features = ["getrandom"] }

[target.'cfg(not(all(target_os = "zkvm", target_arch = "riscv32")))'.dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
proptest = "1.4"

[target.'cfg(all(target_os = "zkvm", target_arch = "riscv32"))'.dev-dependencies]
proptest = { version = "1.4", default-features = false, features = ["alloc"] }
hex = "0.4"

[features]
default = ["arithmetic", "ecdsa", "pem", "std"]
alloc = ["ecdsa-core?/alloc", "elliptic-curve/alloc", "primeorder?/alloc"]
std = ["alloc", "ecdsa-core?/std", "elliptic-curve/std"]
std = ["alloc", "ecdsa-core?/std", "elliptic-curve/std", "once_cell?/std"]

arithmetic = ["dep:primeorder", "elliptic-curve/arithmetic"]
bits = ["arithmetic", "elliptic-curve/bits"]
Expand Down
81 changes: 48 additions & 33 deletions p256/src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,71 @@
//!
//! [NIST SP 800-186]: https://csrc.nist.gov/publications/detail/sp/800-186/final

pub(crate) mod affine;
pub(crate) mod field;
#[cfg(feature = "hash2curve")]
mod hash2curve;
pub(crate) mod projective;
pub(crate) mod scalar;
pub(crate) mod util;

use self::{field::FieldElement, scalar::Scalar};
use crate::NistP256;
use elliptic_curve::{CurveArithmetic, PrimeCurveArithmetic};
use primeorder::{point_arithmetic, PrimeCurveParams};
use elliptic_curve::{bigint::U256, CurveArithmetic};

/// Elliptic curve point in affine coordinates.
pub type AffinePoint = primeorder::AffinePoint<NistP256>;
pub type AffinePoint = affine::AffinePoint;

/// Elliptic curve point in projective coordinates.
pub type ProjectivePoint = primeorder::ProjectivePoint<NistP256>;
pub type ProjectivePoint = projective::ProjectivePoint;

impl CurveArithmetic for NistP256 {
type AffinePoint = AffinePoint;
type ProjectivePoint = ProjectivePoint;
type Scalar = Scalar;
}

impl PrimeCurveArithmetic for NistP256 {
type CurveGroup = ProjectivePoint;
}
/// a = -3
const CURVE_EQUATION_A: FieldElement = FieldElement(U256::from_be_hex(
"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
));

const CURVE_EQUATION_B: FieldElement = FieldElement(U256::from_be_hex(
"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
));

#[cfg(test)]
mod tests {
use super::FieldElement;
use crate::{
arithmetic::{CURVE_EQUATION_A, CURVE_EQUATION_B},
AffinePoint,
};

#[test]
fn equation_a_constant() {
let equation_a = FieldElement::from_u64(3).neg();
assert_eq!(equation_a, CURVE_EQUATION_A);
}

#[test]
fn equation_b_constant() {
let equation_b = FieldElement::from_hex(
"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
);
assert_eq!(equation_b, CURVE_EQUATION_B);
}

/// Adapted from [NIST SP 800-186] § G.1.2: Curve P-256.
///
/// [NIST SP 800-186]: https://csrc.nist.gov/publications/detail/sp/800-186/final
impl PrimeCurveParams for NistP256 {
type FieldElement = FieldElement;
type PointArithmetic = point_arithmetic::EquationAIsMinusThree;

/// a = -3
const EQUATION_A: FieldElement = FieldElement::from_u64(3).neg();

const EQUATION_B: FieldElement =
FieldElement::from_hex("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b");

/// Base point of P-256.
///
/// Defined in NIST SP 800-186 § G.1.2:
///
/// ```text
/// Gₓ = 6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296
/// Gᵧ = 4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5
/// ```
const GENERATOR: (FieldElement, FieldElement) = (
FieldElement::from_hex("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"),
FieldElement::from_hex("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"),
);
#[test]
fn generator_constant() {
let generator: (FieldElement, FieldElement) = (
FieldElement::from_hex(
"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
),
FieldElement::from_hex(
"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
),
);
assert_eq!(generator.0, AffinePoint::GENERATOR.x);
assert_eq!(generator.1, AffinePoint::GENERATOR.y);
}
}
Loading