Skip to content

Commit 3ce99d4

Browse files
authored
Add BitOperations trait (#507)
1 parent a39b404 commit 3ce99d4

File tree

7 files changed

+378
-245
lines changed

7 files changed

+378
-245
lines changed

src/const_choice.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@ impl From<ConstChoice> for Choice {
163163
}
164164
}
165165

166+
impl From<Choice> for ConstChoice {
167+
#[inline]
168+
fn from(choice: Choice) -> Self {
169+
ConstChoice::from_word_lsb(choice.unwrap_u8() as Word)
170+
}
171+
}
172+
166173
impl From<ConstChoice> for bool {
167174
fn from(choice: ConstChoice) -> Self {
168175
choice.is_true_vartime()

src/traits.rs

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pub trait Integer:
9595
+ for<'a> BitXor<&'a Self, Output = Self>
9696
+ BitXorAssign
9797
+ for<'a> BitXorAssign<&'a Self>
98+
+ BitOps
9899
+ CheckedAdd
99100
+ CheckedSub
100101
+ CheckedMul
@@ -154,24 +155,6 @@ pub trait Integer:
154155
/// The value `1`.
155156
fn one() -> Self;
156157

157-
/// Calculate the number of bits required to represent a given number.
158-
fn bits(&self) -> u32;
159-
160-
/// Calculate the number of bits required to represent a given number in variable-time with
161-
/// respect to `self`.
162-
fn bits_vartime(&self) -> u32;
163-
164-
/// Precision of this integer in bits.
165-
fn bits_precision(&self) -> u32;
166-
167-
/// Precision of this integer in bytes.
168-
fn bytes_precision(&self) -> usize;
169-
170-
/// Calculate the number of leading zeros in the binary representation of this number.
171-
fn leading_zeros(&self) -> u32 {
172-
self.bits_precision() - self.bits()
173-
}
174-
175158
/// Number of limbs in this integer.
176159
fn nlimbs(&self) -> usize;
177160

@@ -496,6 +479,69 @@ pub trait RemLimb: Sized {
496479
fn rem_limb_with_reciprocal(&self, reciprocal: &Reciprocal) -> Limb;
497480
}
498481

482+
/// Bit counting and bit operations.
483+
pub trait BitOps {
484+
/// Precision of this integer in bits.
485+
fn bits_precision(&self) -> u32;
486+
487+
/// `floor(log2(self.bits_precision()))`.
488+
fn log2_bits(&self) -> u32 {
489+
u32::BITS - self.bits_precision().leading_zeros() - 1
490+
}
491+
492+
/// Precision of this integer in bytes.
493+
fn bytes_precision(&self) -> usize;
494+
495+
/// Calculate the number of bits needed to represent this number.
496+
fn bit(&self, index: u32) -> Choice;
497+
498+
/// Sets the bit at `index` to 0 or 1 depending on the value of `bit_value`.
499+
fn set_bit(&mut self, index: u32, bit_value: Choice);
500+
501+
/// Calculate the number of bits required to represent a given number.
502+
fn bits(&self) -> u32 {
503+
self.bits_precision() - self.leading_zeros()
504+
}
505+
506+
/// Calculate the number of trailing zeros in the binary representation of this number.
507+
fn trailing_zeros(&self) -> u32;
508+
509+
/// Calculate the number of trailing ones in the binary representation of this number.
510+
fn trailing_ones(&self) -> u32;
511+
512+
/// Calculate the number of leading zeros in the binary representation of this number.
513+
fn leading_zeros(&self) -> u32;
514+
515+
/// Returns `true` if the bit at position `index` is set, `false` otherwise.
516+
///
517+
/// # Remarks
518+
/// This operation is variable time with respect to `index` only.
519+
fn bit_vartime(&self, index: u32) -> bool;
520+
521+
/// Calculate the number of bits required to represent a given number in variable-time with
522+
/// respect to `self`.
523+
fn bits_vartime(&self) -> u32 {
524+
self.bits_precision() - self.leading_zeros_vartime()
525+
}
526+
527+
/// Sets the bit at `index` to 0 or 1 depending on the value of `bit_value`,
528+
/// variable time in `self`.
529+
fn set_bit_vartime(&mut self, index: u32, bit_value: bool);
530+
531+
/// Calculate the number of leading zeros in the binary representation of this number.
532+
fn leading_zeros_vartime(&self) -> u32 {
533+
self.bits_precision() - self.bits_vartime()
534+
}
535+
536+
/// Calculate the number of trailing zeros in the binary representation of this number in
537+
/// variable-time with respect to `self`.
538+
fn trailing_zeros_vartime(&self) -> u32;
539+
540+
/// Calculate the number of trailing ones in the binary representation of this number,
541+
/// variable time in `self`.
542+
fn trailing_ones_vartime(&self) -> u32;
543+
}
544+
499545
/// Constant-time exponentiation.
500546
pub trait Pow<Exponent> {
501547
/// Raises to the `exponent` power.

src/uint.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -249,22 +249,6 @@ impl<const LIMBS: usize> Integer for Uint<LIMBS> {
249249
Self::ONE
250250
}
251251

252-
fn bits(&self) -> u32 {
253-
self.bits()
254-
}
255-
256-
fn bits_vartime(&self) -> u32 {
257-
self.bits_vartime()
258-
}
259-
260-
fn bits_precision(&self) -> u32 {
261-
Self::BITS
262-
}
263-
264-
fn bytes_precision(&self) -> usize {
265-
Self::BYTES
266-
}
267-
268252
fn nlimbs(&self) -> usize {
269253
Self::LIMBS
270254
}

0 commit comments

Comments
 (0)