openzeppelin_crypto/field/
group.rs

1//! This module provides a generic interface for groups with additive notation.
2
3use core::{
4    fmt::{Debug, Display},
5    hash::Hash,
6    iter::Sum,
7    ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
8};
9
10use num_traits::Zero;
11use zeroize::Zeroize;
12
13use crate::field::Field;
14
15/// Defines an abstract group with additive notation.
16/// Support addition and subtraction with itself and multiplication by scalar.
17/// Scalar and group can be different types.
18///
19/// E.g., points on an elliptic curve define an additive group and can be
20/// multiplied by a scalar.
21pub trait AdditiveGroup:
22    Eq
23    + 'static
24    + Sized
25    + Copy
26    + Clone
27    + Default
28    + Send
29    + Sync
30    + Hash
31    + Debug
32    + Display
33    + Zeroize
34    + Zero
35    + Neg<Output = Self>
36    + Add<Self, Output = Self>
37    + Sub<Self, Output = Self>
38    + Mul<<Self as AdditiveGroup>::Scalar, Output = Self>
39    + AddAssign<Self>
40    + SubAssign<Self>
41    + MulAssign<<Self as AdditiveGroup>::Scalar>
42    + for<'a> Add<&'a Self, Output = Self>
43    + for<'a> Sub<&'a Self, Output = Self>
44    + for<'a> Mul<&'a <Self as AdditiveGroup>::Scalar, Output = Self>
45    + for<'a> AddAssign<&'a Self>
46    + for<'a> SubAssign<&'a Self>
47    + for<'a> MulAssign<&'a <Self as AdditiveGroup>::Scalar>
48    + for<'a> Add<&'a mut Self, Output = Self>
49    + for<'a> Sub<&'a mut Self, Output = Self>
50    + for<'a> Mul<&'a mut <Self as AdditiveGroup>::Scalar, Output = Self>
51    + for<'a> AddAssign<&'a mut Self>
52    + for<'a> SubAssign<&'a mut Self>
53    + for<'a> MulAssign<&'a mut <Self as AdditiveGroup>::Scalar>
54    + Sum<Self>
55    + for<'a> Sum<&'a Self>
56{
57    /// Scalar associated with the group.
58    type Scalar: Field;
59
60    /// Additive identity of the group.
61    const ZERO: Self;
62
63    /// Doubles `self`.
64    #[must_use]
65    fn double(&self) -> Self {
66        let mut copy = *self;
67        copy.double_in_place();
68        copy
69    }
70
71    /// Doubles `self` in place.
72    fn double_in_place(&mut self) -> &mut Self {
73        self.add_assign(*self);
74        self
75    }
76
77    /// Negates `self` in place.
78    fn neg_in_place(&mut self) -> &mut Self {
79        *self = -(*self);
80        self
81    }
82}