use anyhow::{anyhow, Error};
use num_bigint::BigInt;
use std::fmt;
use std::str::FromStr;
#[derive(Default, Clone, PartialEq, Eq)]
pub enum Curve {
#[default] Bn254,
Bls12_381,
Goldilocks,
}
impl fmt::Display for Curve {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use Curve::*;
match self {
Bn254 => write!(f, "BN254"),
Bls12_381 => write!(f, "BLS12_381"),
Goldilocks => write!(f, "Goldilocks"),
}
}
}
impl fmt::Debug for Curve {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self}")
}
}
impl Curve {
fn prime(&self) -> BigInt {
use Curve::*;
let prime = match self {
Bn254 => {
"21888242871839275222246405745257275088548364400416034343698204186575808495617"
}
Bls12_381 => {
"52435875175126190479447740508185965837690552500527637822603658699938581184513"
}
Goldilocks => "18446744069414584321",
};
BigInt::parse_bytes(prime.as_bytes(), 10).expect("failed to parse prime")
}
}
impl FromStr for Curve {
type Err = Error;
fn from_str(curve: &str) -> Result<Self, Self::Err> {
match &curve.to_uppercase()[..] {
"BN254" => Ok(Curve::Bn254),
"BLS12_381" => Ok(Curve::Bls12_381),
"GOLDILOCKS" => Ok(Curve::Goldilocks),
_ => Err(anyhow!("failed to parse curve `{curve}`")),
}
}
}
#[derive(Clone)]
pub struct UsefulConstants {
curve: Curve,
prime: BigInt,
}
impl UsefulConstants {
pub fn new(curve: &Curve) -> UsefulConstants {
UsefulConstants { curve: curve.clone(), prime: curve.prime() }
}
pub fn curve(&self) -> &Curve {
&self.curve
}
pub fn prime(&self) -> &BigInt {
&self.prime
}
pub fn prime_size(&self) -> usize {
self.prime.bits()
}
}