clock_curve_math/bigint/
arithmetic.rs

1//! BigInt arithmetic operations trait.
2
3use core::cmp::Ordering;
4
5use super::BigInt;
6
7/// Trait for big integer arithmetic operations.
8///
9/// All operations must execute in constant time for security-critical use cases.
10pub trait BigIntOps {
11    /// Constant-time addition.
12    fn add(&self, rhs: &Self) -> Self;
13
14    /// Constant-time subtraction.
15    fn sub(&self, rhs: &Self) -> Self;
16
17    /// Constant-time multiplication.
18    ///
19    /// Note: This may produce a double-width result that needs reduction.
20    fn mul(&self, rhs: &Self) -> Self;
21
22    /// Wide multiplication returning the full 512-bit result as (low, high) BigInts.
23    fn mul_wide(&self, rhs: &Self) -> (Self, Self)
24    where
25        Self: Sized;
26
27    /// Constant-time left shift.
28    fn shl(&self, bits: u32) -> Self;
29
30    /// Constant-time right shift.
31    fn shr(&self, bits: u32) -> Self;
32
33    /// Constant-time comparison.
34    fn cmp(&self, rhs: &Self) -> Ordering;
35
36    /// Constant-time zero check.
37    fn is_zero(&self) -> bool;
38
39    /// Get the bit at the specified position (constant-time).
40    ///
41    /// Returns 1 if the bit is set, 0 otherwise.
42    /// Bit positions start from 0 (least significant bit).
43    fn get_bit(&self, bit_position: u32) -> u64;
44
45    /// Get the number of bits needed to represent this BigInt.
46    ///
47    /// Returns the position of the highest set bit plus one.
48    /// Returns 0 for zero.
49    fn bit_length(&self) -> u32;
50}
51
52impl BigIntOps for BigInt {
53    fn add(&self, rhs: &Self) -> Self {
54        self.add(rhs)
55    }
56
57    fn sub(&self, rhs: &Self) -> Self {
58        self.sub(rhs)
59    }
60
61    fn mul(&self, rhs: &Self) -> Self {
62        self.mul(rhs)
63    }
64
65    fn mul_wide(&self, rhs: &Self) -> (Self, Self) {
66        self.mul_wide(rhs)
67    }
68
69    fn shl(&self, bits: u32) -> Self {
70        self.shl(bits)
71    }
72
73    fn shr(&self, bits: u32) -> Self {
74        self.shr(bits)
75    }
76
77    fn cmp(&self, rhs: &Self) -> Ordering {
78        self.cmp(rhs)
79    }
80
81    fn is_zero(&self) -> bool {
82        self.is_zero()
83    }
84
85    fn get_bit(&self, bit_position: u32) -> u64 {
86        self.get_bit(bit_position)
87    }
88
89    fn bit_length(&self) -> u32 {
90        self.bit_length()
91    }
92}