1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::Curve;

pub trait HasAffineX: Curve {
    fn x(point: &Self::Point) -> Option<Self::CoordinateArray>;
}

pub trait HasAffineXAndParity: Curve + HasAffineX {
    fn x_and_parity(point: &Self::Point) -> Option<(Self::CoordinateArray, Parity)>;
    fn from_x_and_parity(x: &Self::CoordinateArray, y_parity: Parity) -> Option<Self::Point>;
}

pub trait HasAffineY: Curve {
    fn y(point: &Self::Point) -> Option<Self::CoordinateArray>;
}

pub trait HasAffineXY: Curve + HasAffineX + HasAffineY {
    fn x_and_y(point: &Self::Point) -> Option<(Self::CoordinateArray, Self::CoordinateArray)>;
    fn from_x_and_y(x: &Self::CoordinateArray, y: &Self::CoordinateArray) -> Option<Self::Point>;
}

pub trait AlwaysHasAffineY: Curve {
    fn y(point: &Self::Point) -> Self::CoordinateArray;
}

pub trait AlwaysHasAffineYAndSign: Curve + AlwaysHasAffineY {
    fn y_and_sign(point: &Self::Point) -> (Sign, Self::CoordinateArray);
    fn from_y_and_sign(x_sign: Sign, y: &Self::CoordinateArray) -> Option<Self::Point>;
}

/// Sign of coordinate
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum Sign {
    Negative = 0,
    NonNegative = 1,
}

impl Sign {
    /// Checks whether coordinate is negative
    pub fn is_negative(&self) -> bool {
        *self == Self::Negative
    }
}

/// Parity of coordinate
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum Parity {
    Odd = 0,
    Even = 1,
}

impl Parity {
    /// Checks whether coordinate is odd
    pub fn is_odd(&self) -> bool {
        *self == Self::Odd
    }

    /// Checks whether coordinate is even
    pub fn is_even(&self) -> bool {
        *self == Self::Even
    }
}