snarkvm_curves/edwards_bls12/
parameters.rs1use crate::{
17 edwards_bls12::{Fq, Fr},
18 errors::GroupError,
19 templates::twisted_edwards_extended::{Affine, Projective},
20 traits::{AffineCurve, ModelParameters, MontgomeryParameters, TwistedEdwardsParameters},
21};
22use snarkvm_fields::field;
23use snarkvm_utilities::biginteger::BigInteger256;
24
25use std::str::FromStr;
26
27pub type EdwardsAffine = Affine<EdwardsParameters>;
28pub type EdwardsProjective = Projective<EdwardsParameters>;
29
30#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
31pub struct EdwardsParameters;
32
33impl ModelParameters for EdwardsParameters {
34 type BaseField = Fq;
35 type ScalarField = Fr;
36}
37
38impl TwistedEdwardsParameters for EdwardsParameters {
39 type MontgomeryParameters = EdwardsParameters;
40
41 const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y);
43 const COFACTOR: &'static [u64] = &[4];
45 const COFACTOR_INV: Fr = field!(
47 Fr,
48 BigInteger256([10836190823041854989, 14880086764632731920, 5023208332782666747, 239524813690824359,])
49 );
50 const EDWARDS_A: Fq =
52 field!(Fq, BigInteger256([0x8cf500000000000e, 0xe75281ef6000000e, 0x49dc37a90b0ba012, 0x55f8b2c6e710ab9,]));
53 const EDWARDS_D: Fq =
55 field!(Fq, BigInteger256([0xd047ffffffff5e30, 0xf0a91026ffff57d2, 0x9013f560d102582, 0x9fd242ca7be5700,]));
56
57 #[inline(always)]
60 fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
61 -*elem
62 }
63}
64
65impl MontgomeryParameters for EdwardsParameters {
66 type TwistedEdwardsParameters = EdwardsParameters;
67
68 const MONTGOMERY_A: Fq = field!(
71 Fq,
72 BigInteger256([
73 13800168384327121454u64,
74 6841573379969807446u64,
75 12529593083398462246u64,
76 853978956621483129u64,
77 ])
78 );
79 const MONTGOMERY_B: Fq = field!(
82 Fq,
83 BigInteger256([
84 7239382437352637935u64,
85 14509846070439283655u64,
86 5083066350480839936u64,
87 1265663645916442191u64,
88 ])
89 );
90}
91
92impl FromStr for EdwardsAffine {
93 type Err = GroupError;
94
95 fn from_str(mut s: &str) -> Result<Self, Self::Err> {
96 s = s.trim();
97 if s.is_empty() {
98 return Err(GroupError::ParsingEmptyString);
99 }
100 if s.len() < 3 {
101 return Err(GroupError::InvalidString);
102 }
103 if !(s.starts_with('(') && s.ends_with(')')) {
104 return Err(GroupError::InvalidString);
105 }
106 let mut point = Vec::new();
107 for substr in s.split(['(', ')', ',', ' ']) {
108 if !substr.is_empty() {
109 point.push(Fq::from_str(substr)?);
110 }
111 }
112 if point.len() != 2 {
113 return Err(GroupError::InvalidGroupElement);
114 }
115 let point = EdwardsAffine::new(point[0], point[1], point[0] * point[1]);
116
117 if !point.is_on_curve() { Err(GroupError::InvalidGroupElement) } else { Ok(point) }
118 }
119}
120
121const GENERATOR_X: Fq =
124 field!(Fq, BigInteger256([15976313411695170452, 17230178952810798400, 11626259175167078036, 678729006091608048]));
125
126const GENERATOR_Y: Fq =
129 field!(Fq, BigInteger256([926786653590077393, 18147000980977651608, 13077459464847727671, 1231472949076376191]));