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
use core::ops::Add;

use cryptix_bigint::ops::BigIntOpsExt;

use crate::{Modular, Element};

use super::*;

impl<I, M> Ring for Element<I, M> 
where 
    M: Modular<I>,
    Self: Mul<Output = Self> + AssociativeMul + DistributiveMul + AbelianGroup
{ }

impl<I, M> Mul for Element<I, M> 
where
    M: Modular<I>,
    I: BigIntOpsExt
{
    type Output = Self;

    /// calculate a * b mod m
    /// this can be achieved more efficiently with montgomery multiplication
    fn mul(self, rhs: Self) -> Self::Output {
        let res = self.0 * rhs.0;
        /* # Safety
         *
         * The wrap function will wrap the result in the correct range
         */
        Self::new_unchecked(M::P.wrap(res))
    }
}

/// # Safety
/// 
/// our element type is backed by biguint, so mod mul is associative
impl<I, M> AssociativeMul for Element<I, M> 
where 
    M: Modular<I>,
    Self: Mul<Output = Self> 
{ }

/// # Safety
/// 
/// our element type is backed by biguint, so mod mul is distributive over add
impl<I, M> DistributiveMul for Element<I, M> 
where
    M: Modular<I>,
    Self: Mul<Output = Self> + Add<Output = Self>
{ }