Skip to main content

ark_ec/models/double_odd/
mod.rs

1use ark_serialize::{
2    CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate,
3};
4use ark_std::io::{Read, Write};
5
6use ark_ff::{AdditiveGroup, Field, Zero};
7
8mod affine;
9pub use affine::*;
10
11mod group;
12pub use group::*;
13
14use crate::{
15    scalar_mul::{double_and_add, double_and_add_affine},
16    VariableBaseMSM,
17};
18
19/// Constants and convenience functions that collectively define the [Double-Odd curve](https://doubleodd.group).
20/// In this model, the curve equation is `y² = x(x² + ax + b)`, (b and (a² - 4b) not squares in field)
21/// for constants `a` and `b`.
22pub trait DOCurveConfig: super::CurveConfig {
23    /// Coefficient `a` of the curve equation.
24    const COEFF_A: Self::BaseField;
25    /// Coefficient `b` of the curve equation.
26    const COEFF_B: Self::BaseField;
27    /// Generator of the prime-order subgroup.
28    const GENERATOR: Affine<Self>;
29
30    fn get_c() -> Self::BaseField {
31        Self::COEFF_A.square() - Self::COEFF_B.double().double()
32    }
33
34    fn mul_projective(base: &Projective<Self>, scalar: &[u64]) -> Projective<Self> {
35        double_and_add(base, scalar)
36    }
37
38    fn mul_affine(base: &Affine<Self>, scalar: &[u64]) -> Projective<Self> {
39        double_and_add_affine(base, scalar)
40    }
41
42    fn msm(
43        bases: &[Affine<Self>],
44        scalars: &[Self::ScalarField],
45    ) -> Result<Projective<Self>, usize> {
46        (bases.len() == scalars.len())
47            .then(|| VariableBaseMSM::msm_unchecked(bases, scalars))
48            .ok_or_else(|| bases.len().min(scalars.len()))
49    }
50
51    #[inline]
52    fn serialize_with_mode<W: Write>(
53        item: &Affine<Self>,
54        mut writer: W,
55        compress: ark_serialize::Compress,
56    ) -> Result<(), SerializationError> {
57        match compress {
58            Compress::Yes => {
59                let mut buffer = ark_std::vec::Vec::new();
60                item.e.serialize_uncompressed(&mut buffer)?;
61                if buffer[0] & 1u8 == 1u8 {
62                    -item.u
63                } else {
64                    item.u
65                }
66                .serialize_uncompressed(writer)
67            },
68            Compress::No => {
69                item.e.serialize_with_mode(&mut writer, compress)?;
70                item.u.serialize_with_mode(&mut writer, compress)
71            },
72        }
73    }
74
75    fn deserialize_with_mode<R: Read>(
76        mut reader: R,
77        compress: Compress,
78        validate: Validate,
79    ) -> Result<Affine<Self>, SerializationError> {
80        let (e, u) = match compress {
81            Compress::Yes => {
82                let u: Self::BaseField = CanonicalDeserialize::deserialize_uncompressed(reader)?;
83                let e: Self::BaseField =
84                    Affine::<Self>::get_e_from_u(u).ok_or(SerializationError::InvalidData)?;
85                (e, u)
86            },
87            Compress::No => {
88                let e: Self::BaseField =
89                    CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
90                let u: Self::BaseField =
91                    CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
92                (e, u)
93            },
94        };
95
96        let mut buffer = ark_std::vec::Vec::new();
97        e.serialize_uncompressed(&mut buffer)?;
98
99        let e = if buffer[0] & 1u8 == 1u8 { -e } else { e };
100
101        let point = Affine::new_unchecked(e, u);
102        if validate == Validate::Yes {
103            point.check()?;
104        }
105        Ok(point)
106    }
107
108    #[inline]
109    fn serialized_size(compress: Compress) -> usize {
110        let zero = Self::BaseField::zero();
111        match compress {
112            Compress::Yes => zero.compressed_size(),
113            Compress::No => zero.compressed_size() * 2,
114        }
115    }
116}