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
// trait resresenting abstract algebra concept
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use rand_core::RngCore;

/// group trait which supports additive and scalar arithmetic
/// additive and scalar arithmetic hold associative and distributive property
/// any element has its inverse and these is the identity in group
/// existence of inverse is ensured for only additive arithmetic
pub trait Group:
    PartialEq
    + Eq
    + Add<Output = Self>
    + AddAssign
    + Neg<Output = Self>
    + Sub<Output = Self>
    + SubAssign
    + Mul<Self::Scalar, Output = Self>
    + MulAssign<Self::Scalar>
    + Sized
{
    // scalar domain
    type Scalar: Group;

    // generator of group
    const ADDITIVE_GENERATOR: Self;
    // additive identity of group
    // a * e = a for any a
    const ADDITIVE_IDENTITY: Self;

    // return zero element
    fn zero() -> Self;

    // get inverse of group element
    fn invert(self) -> Option<Self>
    where
        Self: Sized;

    // get randome element
    fn random(rand: impl RngCore) -> Self;
}

/// ring trait which supports additive and multiplicative arithmetics
/// both arithmetics hold associative and distributive property
/// default element is multiplicative generator
pub trait Ring: Group + Mul<Output = Self> + MulAssign + PartialOrd + Ord + Default {
    const MULTIPLICATIVE_IDENTITY: Self;

    // return one element
    fn one() -> Self;
}

/// field trait which ensures the existence of inverse for both multiplicative and additive arithmetic
/// hence field supports division for any element
pub trait Field: Ring + Div<Output = Self> + DivAssign {}