Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add const_assert_eq! and const_assert_ne! macros #293

Merged
merged 1 commit into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
extern crate alloc;

#[macro_use]
mod nlimbs;
mod macros;

#[cfg(feature = "generic-array")]
mod array;
Expand Down
79 changes: 79 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! Macro definitions which are a part of the public API.

/// Internal implementation detail of [`const_assert_eq`] and [`const_assert_ne`].
#[doc(hidden)]
#[macro_export]
macro_rules! const_assert_n {
($n:expr, $($arg:tt)*) => {{
// TODO(tarcieri): gensym a name so it's unique per invocation of the macro?
mod __const_assert {
pub(super) struct Assert<const N: usize>;

impl<const N: usize> Assert<N> {
pub(super) const ASSERT: () = assert!($($arg)*);
}
}

__const_assert::Assert::<$n>::ASSERT
}};
}

/// Const-friendly assertion that two values are equal.
///
/// ```
/// const _: () = crypto_bigint::const_assert_eq!(0, 0, "zero equals zero");
/// ```
#[macro_export]
macro_rules! const_assert_eq {
($left:expr, $right:expr $(,)?) => (
$crate::const_assert_n!($left, $left == $right)
);
($left:expr, $right:expr, $($arg:tt)+) => (
$crate::const_assert_n!($left, $left == $right, $($arg)+)
);
}

/// Const-friendly assertion that two values are NOT equal.
///
/// ```
/// const _: () = crypto_bigint::const_assert_ne!(0, 1, "zero is NOT equal to one");
/// ```
#[macro_export]
macro_rules! const_assert_ne {
($left:expr, $right:expr $(,)?) => (
$crate::const_assert_n!($left, $left != $right)
);
($left:expr, $right:expr, $($arg:tt)+) => (
$crate::const_assert_n!($left, $left != $right, $($arg)+)
);
}

/// Calculate the number of limbs required to represent the given number of bits.
// TODO(tarcieri): replace with `generic_const_exprs` (rust-lang/rust#76560) when stable
#[macro_export]
macro_rules! nlimbs {
($bits:expr) => {
$bits / $crate::Limb::BITS
};
}

#[cfg(test)]
mod tests {
#[cfg(target_pointer_width = "32")]
#[test]
fn nlimbs_for_bits_macro() {
assert_eq!(nlimbs!(64), 2);
assert_eq!(nlimbs!(128), 4);
assert_eq!(nlimbs!(192), 6);
assert_eq!(nlimbs!(256), 8);
}

#[cfg(target_pointer_width = "64")]
#[test]
fn nlimbs_for_bits_macro() {
assert_eq!(nlimbs!(64), 1);
assert_eq!(nlimbs!(128), 2);
assert_eq!(nlimbs!(192), 3);
assert_eq!(nlimbs!(256), 4);
}
}
29 changes: 0 additions & 29 deletions src/nlimbs.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/uint/modular/runtime_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,6 @@ impl<const LIMBS: usize> zeroize::Zeroize for DynResidue<LIMBS> {
#[cfg(test)]
mod test {
use super::*;
use crate::nlimbs;

const LIMBS: usize = nlimbs!(64);

Expand Down