Skip to content

Commit

Permalink
BoxedUint: impl BitAnd* (#314)
Browse files Browse the repository at this point in the history
  • Loading branch information
tarcieri authored Nov 26, 2023
1 parent 2fda5f0 commit f7589bf
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/boxed/uint.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Heap-allocated big unsigned integers.
mod add;
mod bit_and;
mod cmp;
pub(crate) mod encoding;
mod mul;
Expand Down
138 changes: 138 additions & 0 deletions src/boxed/uint/bit_and.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
//! [`BoxedUint`] bitwise AND operations.
use super::BoxedUint;
use crate::{Limb, Wrapping};
use core::ops::{BitAnd, BitAndAssign};
use subtle::{Choice, CtOption};

impl BoxedUint {
/// Computes bitwise `a & b`.
#[inline(always)]
pub fn bitand(&self, rhs: &Self) -> Self {
Self::chain(self, rhs, Limb::ZERO, |a, b, z| (a.bitand(b), z)).0
}

/// Perform wrapping bitwise `AND`.
///
/// There's no way wrapping could ever happen.
/// This function exists so that all operations are accounted for in the wrapping operations
pub fn wrapping_and(&self, rhs: &Self) -> Self {
self.bitand(rhs)
}

/// Perform checked bitwise `AND`, returning a [`CtOption`] which `is_some` always
pub fn checked_and(&self, rhs: &Self) -> CtOption<Self> {
let result = self.bitand(rhs);
CtOption::new(result, Choice::from(1))
}
}

impl BitAnd for BoxedUint {
type Output = Self;

fn bitand(self, rhs: Self) -> BoxedUint {
self.bitand(&rhs)
}
}

impl BitAnd<&BoxedUint> for BoxedUint {
type Output = BoxedUint;

#[allow(clippy::needless_borrow)]
fn bitand(self, rhs: &BoxedUint) -> BoxedUint {
(&self).bitand(rhs)
}
}

impl BitAnd<BoxedUint> for &BoxedUint {
type Output = BoxedUint;

fn bitand(self, rhs: BoxedUint) -> BoxedUint {
self.bitand(&rhs)
}
}

impl BitAnd<&BoxedUint> for &BoxedUint {
type Output = BoxedUint;

fn bitand(self, rhs: &BoxedUint) -> BoxedUint {
self.bitand(rhs)
}
}

impl BitAndAssign for BoxedUint {
#[allow(clippy::assign_op_pattern)]
fn bitand_assign(&mut self, other: Self) {
*self = BoxedUint::bitand(self, &other);
}
}

impl BitAndAssign<&BoxedUint> for BoxedUint {
#[allow(clippy::assign_op_pattern)]
fn bitand_assign(&mut self, other: &Self) {
*self = BoxedUint::bitand(self, other);
}
}

impl BitAnd for Wrapping<BoxedUint> {
type Output = Self;

fn bitand(self, rhs: Self) -> Wrapping<BoxedUint> {
Wrapping(self.0.bitand(&rhs.0))
}
}

impl BitAnd<&Wrapping<BoxedUint>> for Wrapping<BoxedUint> {
type Output = Wrapping<BoxedUint>;

fn bitand(self, rhs: &Wrapping<BoxedUint>) -> Wrapping<BoxedUint> {
Wrapping(self.0.bitand(&rhs.0))
}
}

impl BitAnd<Wrapping<BoxedUint>> for &Wrapping<BoxedUint> {
type Output = Wrapping<BoxedUint>;

fn bitand(self, rhs: Wrapping<BoxedUint>) -> Wrapping<BoxedUint> {
Wrapping(BoxedUint::bitand(&self.0, &rhs.0))
}
}

impl BitAnd<&Wrapping<BoxedUint>> for &Wrapping<BoxedUint> {
type Output = Wrapping<BoxedUint>;

fn bitand(self, rhs: &Wrapping<BoxedUint>) -> Wrapping<BoxedUint> {
Wrapping(BoxedUint::bitand(&self.0, &rhs.0))
}
}

impl BitAndAssign for Wrapping<BoxedUint> {
#[allow(clippy::assign_op_pattern)]
fn bitand_assign(&mut self, other: Self) {
*self = Wrapping(BoxedUint::bitand(&self.0, &other.0))
}
}

impl BitAndAssign<&Wrapping<BoxedUint>> for Wrapping<BoxedUint> {
#[allow(clippy::assign_op_pattern)]
fn bitand_assign(&mut self, other: &Self) {
*self = Wrapping(BoxedUint::bitand(&self.0, &other.0))
}
}

#[cfg(test)]
mod tests {
use crate::BoxedUint;

#[test]
fn checked_and_ok() {
let result = BoxedUint::zero().checked_and(&BoxedUint::one());
assert_eq!(result.unwrap(), BoxedUint::zero());
}

#[test]
fn overlapping_and_ok() {
let result = BoxedUint::max(128).unwrap().wrapping_and(&BoxedUint::one());
assert_eq!(result, BoxedUint::one());
}
}
2 changes: 1 addition & 1 deletion src/uint/bit_and.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! [`Uint`] bitwise and operations.
//! [`Uint`] bitwise AND operations.
use super::Uint;
use crate::{Limb, Wrapping};
Expand Down
2 changes: 1 addition & 1 deletion src/uint/bit_not.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! [`Uint`] bitwise not operations.
//! [`Uint`] bitwise NOT operations.
use super::Uint;
use crate::{Limb, Wrapping};
Expand Down
2 changes: 1 addition & 1 deletion src/uint/bit_or.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! [`Uint`] bitwise or operations.
//! [`Uint`] bitwise OR operations.
use super::Uint;
use crate::{Limb, Wrapping};
Expand Down
2 changes: 1 addition & 1 deletion src/uint/bit_xor.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! [`Uint`] bitwise xor operations.
//! [`Uint`] bitwise XOR operations.
use super::Uint;
use crate::{Limb, Wrapping};
Expand Down

0 comments on commit f7589bf

Please sign in to comment.