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
69
70
71
72
73
74
use std::hash::Hash;

use crate::element::EdwardsAffine;
use ark_std::fmt::{Display, Formatter, Result as FmtResult};
use ark_std::Zero;

use zeroize::Zeroize;

use crate::Element;

#[derive(Copy, Clone)]
pub struct AffineElement {
    pub(crate) inner: EdwardsAffine,
}

impl Hash for AffineElement {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        self.inner.hash(state);
    }
}

impl Default for AffineElement {
    fn default() -> Self {
        Element::default().into()
    }
}

impl core::iter::Sum<AffineElement> for Element {
    fn sum<I: Iterator<Item = AffineElement>>(iter: I) -> Self {
        iter.fold(Self::zero(), core::ops::Add::add)
    }
}

impl<'a> core::iter::Sum<&'a AffineElement> for Element {
    fn sum<I: Iterator<Item = &'a AffineElement>>(iter: I) -> Self {
        iter.fold(Self::zero(), core::ops::Add::add)
    }
}

impl PartialEq for AffineElement {
    fn eq(&self, other: &AffineElement) -> bool {
        // Section 4.5 of Decaf paper
        self.inner.x * other.inner.y == self.inner.y * other.inner.x
    }
}

impl Eq for AffineElement {}

impl std::fmt::Debug for AffineElement {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let element: Element = self.into();
        f.write_fmt(format_args!(
            "decaf377::AffineElement({})",
            hex::encode(&element.vartime_compress().0[..])
        ))
    }
}

impl Display for AffineElement {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        let element: Element = self.into();
        write!(
            f,
            "decaf377::AffineElement({})",
            hex::encode(&element.vartime_compress().0[..])
        )
    }
}

impl Zeroize for AffineElement {
    fn zeroize(&mut self) {
        self.inner.zeroize()
    }
}