Skip to content

Commit

Permalink
Add Uint::bit_ct
Browse files Browse the repository at this point in the history
  • Loading branch information
recmo committed Oct 14, 2024
1 parent bac98dd commit c63cc29
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ named feature flag.
* [`bn-rs`](https://docs.rs/bn-rs/latest/bn_rs/): Implements conversion to/from the [`BN`](https://docs.rs/bn-rs/latest/bn_rs/struct.BN.html) and [`BigNumber`](https://docs.rs/bn-rs/latest/bn_rs/struct.BigNumber.html).
* [`bytemuck`](https://docs.rs/bytemuck): Implements the [`Pod`](https://docs.rs/bytemuck/latest/bytemuck/trait.Pod.html) and [`Zeroable`](https://docs.rs/bytemuck/latest/bytemuck/trait.Zeroable.html) traits for [`Uint`] where the size is a multiple of 64, up to 1024. This allows `Uint` to be used where a `Pod` trait bound exists.
* [`num-traits`](https://docs.rs/num-traits): Implements about forty applicable traits.
* [`subtle`](https://docs.rs/subtle): Implements [`ConditionallySelectable`](https://docs.rs/subtle/latest/subtle/trait.ConditionallySelectable.html),[`ConditionallyNegatable`](https://docs.rs/subtle/latest/subtle/trait.ConditionallyNegatable.html), [`ConstantTimeEq`](https://docs.rs/subtle/latest/subtle/trait.ConstantTimeEq.html)/[`ConstantTimeGreater`](https://docs.rs/subtle/latest/subtle/trait.ConstantTimeGreater.html)/[`ConstantTimeLess`](https://docs.rs/subtle/latest/subtle/trait.ConstantTimeLess.html).
* [`subtle`](https://docs.rs/subtle): Implements [`Uint::bit_ct`], [`ConditionallySelectable`](https://docs.rs/subtle/latest/subtle/trait.ConditionallySelectable.html),[`ConditionallyNegatable`](https://docs.rs/subtle/latest/subtle/trait.ConditionallyNegatable.html), [`ConstantTimeEq`](https://docs.rs/subtle/latest/subtle/trait.ConstantTimeEq.html)/[`ConstantTimeGreater`](https://docs.rs/subtle/latest/subtle/trait.ConstantTimeGreater.html)/[`ConstantTimeLess`](https://docs.rs/subtle/latest/subtle/trait.ConstantTimeLess.html).
* [`der`](https://docs.rs/der): Implements [`Encode`](https://docs.rs/der/latest/der/trait.Encode.html)/[`Decode`](https://docs.rs/der/latest/der/trait.Decode.html) and [`TryFrom`]/[`From`] casting for [`Any`](https://docs.rs/der/latest/der/asn1/struct.Any.html), [`AnyRef`](https://docs.rs/der/latest/der/asn1/struct.AnyRef.html), [`Int`](https://docs.rs/der/latest/der/asn1/struct.Int.html), [`IntRef`](https://docs.rs/der/latest/der/asn1/struct.IntRef.html), [`Uint`](https://docs.rs/der/latest/der/asn1/struct.Uint.html), [`UintRef`](https://docs.rs/der/latest/der/asn1/struct.UintRef.html).

## Building and testing
Expand Down
28 changes: 28 additions & 0 deletions src/support/subtle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ use subtle::{
Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
};

impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
/// Returns a [`Choice`] if the bit at index is set.
///
/// Constant time version of [`bit`]
///
/// # Panics
///
/// Panics if `index >= Self::BITS`.
#[must_use]
pub fn bit_ct(&self, index: usize) -> Choice {
assert!(index < BITS);
let (limbs, bits) = (index / 64, index % 64);
(self.limbs[limbs] & (1 << bits)).ct_eq(&(1 << bits))
}
}

impl<const BITS: usize, const LIMBS: usize> ConditionallySelectable for Uint<BITS, LIMBS> {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
let mut limbs = [0_u64; LIMBS];
Expand Down Expand Up @@ -74,6 +90,18 @@ mod tests {
use proptest::proptest;
use subtle::ConditionallyNegatable;

#[test]
fn test_bit() {
const_for!(BITS in SIZES {
const LIMBS: usize = nlimbs(BITS);
proptest!(|(n: Uint<BITS, LIMBS>, i in 0..BITS)| {
let r = n.bit_ct(i);
let e = n.bit(i);
assert_eq!(bool::from(r), e);
});
});
}

#[test]
fn test_select() {
const_for!(BITS in SIZES {
Expand Down

0 comments on commit c63cc29

Please sign in to comment.