curv/arithmetic/
traits.rs

1/*
2    Cryptography utilities
3
4    Copyright 2018 by Kzen Networks
5
6    This file is part of Cryptography utilities library
7    (https://github.com/KZen-networks/cryptography-utils)
8
9    Cryptography utilities is free software: you can redistribute
10    it and/or modify it under the terms of the GNU General Public
11    License as published by the Free Software Foundation, either
12    version 3 of the License, or (at your option) any later version.
13
14    @license GPL-3.0+ <https://github.com/KZen-networks/cryptography-utils/blob/master/LICENSE>
15*/
16
17use super::errors::ParseBigIntError;
18
19/// Reuse common traits from [num_integer] crate
20pub use num_integer::{Integer, Roots};
21/// Reuse common traits from [num_traits] crate
22pub use num_traits::{One, Zero};
23
24#[deprecated(
25    since = "0.6.0",
26    note = "BigInt now implements zeroize::Zeroize trait, you should use it instead"
27)]
28pub trait ZeroizeBN {
29    fn zeroize_bn(&mut self);
30}
31
32/// Converts BigInt to/from various forms of representation.
33pub trait Converter: Sized {
34    /// Returns bytes representation of the number.
35    ///
36    /// ## Examples
37    /// ```
38    /// # use curv::arithmetic::{BigInt, Converter};
39    /// assert_eq!(BigInt::from(31).to_bytes(), &[31]);
40    /// assert_eq!(BigInt::from(1_000_000).to_bytes(), &[15, 66, 64]);
41    /// ```
42    fn to_bytes(&self) -> Vec<u8>;
43    /// Constructs BigInt from its byte representation
44    ///
45    /// ```
46    /// # use curv::arithmetic::{BigInt, Converter};
47    /// assert_eq!(BigInt::from_bytes(&[15, 66, 64]), BigInt::from(1_000_000))
48    /// ```
49    fn from_bytes(bytes: &[u8]) -> Self;
50
51    /// Returns bytes representation of the number in an array with length chosen by the user
52    /// if the array is larger than the bytes it pads it with zeros in the most significant bytes
53    /// If the array is too small for the integer it returns None.
54    ///
55    /// ## Examples
56    /// ```
57    /// # use curv::arithmetic::{BigInt, Converter};
58    /// assert_eq!(BigInt::from(31).to_bytes_array(), Some([31]));
59    /// assert_eq!(BigInt::from(31).to_bytes_array(), Some([0, 31]));
60    /// assert_eq!(BigInt::from(1_000_000).to_bytes_array(), Some([15, 66, 64]));
61    /// assert_eq!(BigInt::from(1_000_000).to_bytes_array::<2>(), None);
62    /// assert_eq!(BigInt::from(1_000_000).to_bytes_array(), Some([0, 15, 66, 64]));
63    /// ```
64    fn to_bytes_array<const N: usize>(&self) -> Option<[u8; N]> {
65        let bytes = self.to_bytes();
66        if bytes.len() > N {
67            return None;
68        }
69        let mut array = [0u8; N];
70        array[N - bytes.len()..].copy_from_slice(&bytes);
71        Some(array)
72    }
73
74    /// Converts BigInt to hex representation.
75    ///
76    /// If the number is negative, it will be serialized by absolute value, and minus character
77    /// will be prepended to resulting string.
78    ///
79    /// ## Examples
80    /// ```
81    /// # use curv::arithmetic::{BigInt, Converter};
82    /// assert_eq!(BigInt::from(31).to_hex(), "1f");
83    /// assert_eq!(BigInt::from(1_000_000).to_hex(), "f4240");
84    /// ```
85    fn to_hex(&self) -> String {
86        self.to_str_radix(16)
87    }
88    /// Parses given hex string.
89    ///
90    /// Follows the same format as was described in [to_hex](Self::to_hex).
91    ///
92    /// ## Examples
93    /// ```
94    /// # use curv::arithmetic::{BigInt, Converter};
95    /// assert_eq!(BigInt::from_hex("1f").unwrap(), BigInt::from(31));
96    /// assert_eq!(BigInt::from_hex("-1f").unwrap(), BigInt::from(-31));
97    /// assert_eq!(BigInt::from_hex("f4240").unwrap(), BigInt::from(1_000_000));
98    /// assert_eq!(BigInt::from_hex("-f4240").unwrap(), BigInt::from(-1_000_000));
99    /// ```
100    fn from_hex(n: &str) -> Result<Self, ParseBigIntError> {
101        Self::from_str_radix(n, 16)
102    }
103
104    /// Converts BigInt to radix representation.
105    ///
106    /// If the number is negative, it will be serialized by absolute value, and minus character
107    /// will be prepended to resulting string.
108    ///
109    /// ## Examples
110    /// ```
111    /// # use curv::arithmetic::{BigInt, Converter};
112    /// assert_eq!(BigInt::from(31).to_str_radix(16), "1f");
113    /// assert_eq!(BigInt::from(1_000_000).to_str_radix(16), "f4240");
114    /// ```
115    fn to_str_radix(&self, radix: u8) -> String;
116    /// Parses given radix string.
117    ///
118    /// Radix must be in `[2; 36]` range. Otherwise, function will **panic**.
119    ///
120    /// ## Examples
121    /// ```
122    /// # use curv::arithmetic::{BigInt, Converter};
123    /// assert_eq!(BigInt::from_str_radix("1f", 16).unwrap(), BigInt::from(31));
124    /// assert_eq!(BigInt::from_str_radix("f4240", 16).unwrap(), BigInt::from(1_000_000));
125    /// ```
126    fn from_str_radix(s: &str, radix: u8) -> Result<Self, ParseBigIntError>;
127}
128
129/// Provides basic arithmetic operators for BigInt
130///
131/// Note that BigInt also implements std::ops::{Add, Mull, ...} traits, so you can
132/// use them instead.
133pub trait BasicOps {
134    fn pow(&self, exponent: u32) -> Self;
135    fn mul(&self, other: &Self) -> Self;
136    fn sub(&self, other: &Self) -> Self;
137    fn add(&self, other: &Self) -> Self;
138    fn abs(&self) -> Self;
139}
140
141/// Modular arithmetic for BigInt
142pub trait Modulo: Sized {
143    /// Calculates base^(exponent) (mod m)
144    ///
145    /// Exponent must not be negative. Function will panic otherwise.
146    fn mod_pow(base: &Self, exponent: &Self, m: &Self) -> Self;
147    /// Calculates a * b (mod m)
148    fn mod_mul(a: &Self, b: &Self, modulus: &Self) -> Self;
149    /// Calculates a - b (mod m)
150    fn mod_sub(a: &Self, b: &Self, modulus: &Self) -> Self;
151    /// Calculates a + b (mod m)
152    fn mod_add(a: &Self, b: &Self, modulus: &Self) -> Self;
153    /// Calculates a^-1 (mod m). Returns None if `a` and `m` are not coprimes.
154    fn mod_inv(a: &Self, m: &Self) -> Option<Self>;
155    /// Calculates a mod m
156    fn modulus(&self, modulus: &Self) -> Self;
157}
158
159/// Generating random BigInt
160pub trait Samplable {
161    /// Generates random number within `[0; upper)` range
162    ///
163    /// ## Panics
164    /// Panics if `upper <= 0`
165    fn sample_below(upper: &Self) -> Self;
166    /// Generates random number within `[lower; upper)` range
167    ///
168    /// ## Panics
169    /// Panics if `upper <= lower`
170    fn sample_range(lower: &Self, upper: &Self) -> Self;
171    /// Generates random number within `(lower; upper)` range
172    ///
173    /// ## Panics
174    /// Panics if `upper <= lower`
175    fn strict_sample_range(lower: &Self, upper: &Self) -> Self;
176    /// Generates number within `[0; 2^bit_size)` range
177    fn sample(bit_size: usize) -> Self;
178    /// Generates number within `[2^(bit_size-1); 2^bit_size)` range
179    fn strict_sample(bit_size: usize) -> Self;
180}
181
182/// Set of predicates allowing to examine BigInt
183pub trait NumberTests {
184    /// Returns `true` if `n` is zero
185    ///
186    /// Alternatively, [BasicOps::sign] method can be used to check sign of the number.
187    fn is_zero(n: &Self) -> bool;
188    /// Returns `true` if `n` is negative
189    ///
190    /// Alternatively, [BasicOps::sign] method can be used to check sign of the number.
191    fn is_negative(n: &Self) -> bool;
192}
193
194/// Extended GCD algorithm
195pub trait EGCD
196where
197    Self: Sized,
198{
199    /// For given a, b calculates gcd(a,b), p, q such as `gcd(a,b) = a*p + b*q`
200    ///
201    /// ## Example
202    /// ```
203    /// # use curv::arithmetic::*;
204    /// let (a, b) = (BigInt::from(10), BigInt::from(15));
205    /// let (s, p, q) = BigInt::egcd(&a, &b);
206    /// assert_eq!(&s, &BigInt::from(5));
207    /// assert_eq!(s, a*p + b*q);
208    /// ```
209    fn egcd(a: &Self, b: &Self) -> (Self, Self, Self);
210}
211
212/// Bits manipulation in BigInt
213pub trait BitManipulation {
214    /// Sets/unsets bit in the number
215    ///
216    /// ## Example
217    /// ```
218    /// # use curv::arithmetic::*;
219    /// let mut n = BigInt::from(0b100);
220    /// n.set_bit(3, true);
221    /// assert_eq!(n, BigInt::from(0b1100));
222    /// n.set_bit(0, true);
223    /// assert_eq!(n, BigInt::from(0b1101));
224    /// n.set_bit(2, false);
225    /// assert_eq!(n, BigInt::from(0b1001));
226    /// ```
227    fn set_bit(&mut self, bit: usize, bit_val: bool);
228    /// Tests if bit is set
229    ///
230    /// ```
231    /// # use curv::arithmetic::*;
232    /// let n = BigInt::from(0b101);
233    /// assert_eq!(n.test_bit(3), false);
234    /// assert_eq!(n.test_bit(2), true);
235    /// assert_eq!(n.test_bit(1), false);
236    /// assert_eq!(n.test_bit(0), true);
237    /// ```
238    fn test_bit(&self, bit: usize) -> bool;
239    /// Length of the number in bits
240    ///
241    /// ```
242    /// # use curv::arithmetic::*;
243    /// assert_eq!(BigInt::from(0b1011).bit_length(), 4);
244    /// ```
245    fn bit_length(&self) -> usize;
246}
247
248#[deprecated(
249    since = "0.6.0",
250    note = "Use corresponding From<T> and TryFrom<T> traits implemented on BigInt"
251)]
252pub trait ConvertFrom<T> {
253    fn _from(_: &T) -> Self;
254}
255
256/// Utilities for searching / testing prime numbers
257pub trait Primes {
258    /// Finds next prime number using probabilistic algorithms
259    fn next_prime(&self) -> Self;
260    /// Probabilistically determine whether number is prime
261    ///
262    /// If number is prime, `is_probable_prime` always returns true. If number is composite,
263    /// `is_probable_prime` probably return false. The probability of returning true for a randomly
264    /// chosen non-prime is at most 4^(-reps).
265    fn is_probable_prime(&self, n: u32) -> bool;
266}