hacspec_lib/
traits.rs

1//!
2//! This module specifies the `Numeric` trait.
3//!
4
5use crate::prelude::*;
6
7/// Common trait for all byte arrays and sequences.
8pub trait SeqTrait<T: Clone>:
9    Index<usize, Output = T> + IndexMut<usize, Output = T> + Sized
10{
11    fn len(&self) -> usize;
12    fn iter(&self) -> core::slice::Iter<T>;
13    fn create(len: usize) -> Self;
14    /// Update this sequence with `l` elements of `v`, starting at `start_in`,
15    /// at `start_out`.
16    ///
17    /// # Examples
18    ///
19    /// ```
20    /// use hacspec_lib::*;
21    ///
22    /// let mut s = Seq::<u8>::new(5);
23    /// let tmp = Seq::<u8>::from_native_slice(&[2, 3]);
24    /// s = s.update_slice(2, &tmp, 1, 1);
25    /// // assert_eq!(s, Seq::<u8>::from_array(&[0, 0, 3, 0, 0]));
26    /// ```
27    fn update_slice<A: SeqTrait<T>>(
28        self,
29        start_out: usize,
30        v: &A,
31        start_in: usize,
32        len: usize,
33    ) -> Self;
34
35    /// Update this sequence with `v` starting at `start`.
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use hacspec_lib::*;
41    ///
42    /// let mut s = Seq::<u8>::new(5);
43    /// let tmp = Seq::<u8>::from_native_slice(&[2, 3]);
44    /// s = s.update(2, &tmp);
45    /// // assert_eq!(s, Seq::<u8>::from_array(&[0, 0, 2, 3, 0]));
46    /// ```
47    #[cfg_attr(feature = "use_attributes", in_hacspec)]
48    fn update<A: SeqTrait<T>>(self, start: usize, v: &A) -> Self {
49        let len = v.len();
50        self.update_slice(start, v, 0, len)
51    }
52
53    #[cfg_attr(feature = "use_attributes", in_hacspec)]
54    fn update_start<A: SeqTrait<T>>(self, v: &A) -> Self {
55        let len = v.len();
56        self.update_slice(0, v, 0, len)
57    }
58}
59
60/// This trait extends the `Numeric` trait and is implemented by all integer
61/// types. It offers bit manipulation, instantiation from literal, and convenient
62/// constants.
63pub trait Integer: Numeric {
64    const NUM_BITS: usize;
65
66    // Some useful values.
67    // Not constants because math integers can't do that.
68    #[allow(non_snake_case)]
69    fn ZERO() -> Self;
70    #[allow(non_snake_case)]
71    fn ONE() -> Self;
72    #[allow(non_snake_case)]
73    fn TWO() -> Self;
74
75    /// Get an integer with value `val`.
76    fn from_literal(val: u128) -> Self;
77
78    /// Read a hex string (starting with 0x) into an `Integer`.
79    fn from_hex_string(s: &String) -> Self;
80
81    fn get_bit(self, i: usize) -> Self;
82
83    fn set_bit(self, b: Self, i: usize) -> Self;
84
85    fn set(self, pos: usize, y: Self, yi: usize) -> Self;
86
87    fn rotate_left(self, n: usize) -> Self;
88
89    fn rotate_right(self, n: usize) -> Self;
90}
91
92pub trait SecretInteger: Integer {
93    type PublicVersion: PublicInteger;
94    fn classify(x: Self::PublicVersion) -> Self;
95}
96pub trait SecretIntegerCopy: SecretInteger + Copy {
97    type PublicVersionCopy: PublicIntegerCopy;
98    fn classify(x: Self::PublicVersionCopy) -> Self;
99}
100
101pub trait PublicInteger: Integer {
102    type SecretVersion: Integer;
103}
104pub trait PublicIntegerCopy: PublicInteger + Copy {
105    type SecretVersionCopy: Integer + Copy;
106}
107
108pub trait UnsignedInteger: Integer {}
109pub trait UnsignedIntegerCopy: UnsignedInteger + Copy {}
110
111pub trait SignedInteger: Integer {}
112pub trait SignedIntegerCopy: SignedInteger + Copy {}
113
114pub trait UnsignedSecretInteger: UnsignedInteger + SecretInteger {
115    fn to_le_bytes(self) -> Seq<U8>;
116    fn to_be_bytes(self) -> Seq<U8>;
117    fn from_le_bytes(x: &Seq<U8>) -> Self;
118    fn from_be_bytes(x: &Seq<U8>) -> Self;
119    /// Get byte `i` of this integer.
120    #[inline]
121    #[cfg_attr(feature = "use_attributes", in_hacspec)]
122    fn get_byte(self, i: usize) -> Self {
123        (self >> (i * 8)) & ((Self::ONE() << 8) - Self::ONE())
124    }
125}
126pub trait UnsignedSecretIntegerCopy: UnsignedSecretInteger + SecretIntegerCopy {}
127
128pub trait UnsignedPublicInteger: UnsignedInteger + PublicInteger {
129    fn to_le_bytes(self) -> Seq<u8>;
130    fn to_be_bytes(self) -> Seq<u8>;
131    fn from_le_bytes(x: &Seq<u8>) -> Self;
132    fn from_be_bytes(x: &Seq<u8>) -> Self;
133}
134pub trait UnsignedPublicIntegerCopy: UnsignedPublicInteger + PublicIntegerCopy {}
135
136pub trait ModNumeric {
137    /// (self - rhs) % n.
138    fn sub_mod(self, rhs: Self, n: Self) -> Self;
139    /// `(self + rhs) % n`
140    fn add_mod(self, rhs: Self, n: Self) -> Self;
141    /// `(self * rhs) % n`
142    fn mul_mod(self, rhs: Self, n: Self) -> Self;
143    /// `(self ^ exp) % n`
144    fn pow_mod(self, exp: Self, n: Self) -> Self;
145    /// `self % n`
146    fn modulo(self, n: Self) -> Self;
147    /// `self % n` that always returns a positive integer
148    fn signed_modulo(self, n: Self) -> Self;
149    /// `|self|`
150    fn absolute(self) -> Self;
151}
152
153pub trait NumericCopy: Copy {}
154
155/// The `Numeric` trait has to be implemented by all numeric objects.
156pub trait Numeric:
157    ModNumeric
158    + Add<Self, Output = Self>
159    + Sub<Self, Output = Self>
160    + Mul<Self, Output = Self>
161    + BitXor<Self, Output = Self>
162    + BitOr<Self, Output = Self>
163    + BitAnd<Self, Output = Self>
164    + Shl<usize, Output = Self>
165    + Shr<usize, Output = Self>
166    + Not<Output = Self>
167    + Default
168    + Clone
169    + Debug
170{
171    /// Return largest value that can be represented.
172    fn max_val() -> Self;
173
174    fn wrap_add(self, rhs: Self) -> Self;
175    fn wrap_sub(self, rhs: Self) -> Self;
176    fn wrap_mul(self, rhs: Self) -> Self;
177    fn wrap_div(self, rhs: Self) -> Self;
178
179    /// `self ^ exp` where `exp` is a `u32`.
180    fn exp(self, exp: u32) -> Self;
181    /// `self ^ exp` where `exp` is a `Self`.
182    fn pow_self(self, exp: Self) -> Self;
183    /// Division.
184    fn divide(self, rhs: Self) -> Self;
185    /// Invert self modulo n.
186    fn inv(self, n: Self) -> Self;
187
188    // Comparison functions returning bool.
189    fn equal(self, other: Self) -> bool;
190    fn greater_than(self, other: Self) -> bool;
191    fn greater_than_or_equal(self, other: Self) -> bool;
192    fn less_than(self, other: Self) -> bool;
193    fn less_than_or_equal(self, other: Self) -> bool;
194
195    // Comparison functions returning a bit mask (0x0..0 or 0xF..F).
196    fn not_equal_bm(self, other: Self) -> Self;
197    fn equal_bm(self, other: Self) -> Self;
198    fn greater_than_bm(self, other: Self) -> Self;
199    fn greater_than_or_equal_bm(self, other: Self) -> Self;
200    fn less_than_bm(self, other: Self) -> Self;
201    fn less_than_or_equal_bm(self, other: Self) -> Self;
202}