diff --git a/src/bb/bytes.rs b/src/bb/bytes.rs index 73564019d0..55e05d2d2c 100644 --- a/src/bb/bytes.rs +++ b/src/bb/bytes.rs @@ -59,8 +59,7 @@ pub fn bytes_are_equal(a: &[u8], b: &[u8]) -> BoolMask { #[allow(clippy::into_iter_on_ref)] let rem = a_rem .into_iter() - .copied() - .map(Word::from) + .map(Word::from_u8) .zip(b_rem.into_iter().copied().map(Word::from)) .fold(0, |acc, (a, b)| acc | (a ^ b)); acc |= rem; diff --git a/src/bb/ops.rs b/src/bb/ops.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/bb/word/aarch64.rs b/src/bb/word/aarch64.rs new file mode 100644 index 0000000000..d0e09581bb --- /dev/null +++ b/src/bb/word/aarch64.rs @@ -0,0 +1,32 @@ +use super::{super::BoolMask, Word, WordOps}; +use crate::polyfill; +use core::{arch::asm, mem}; + +impl WordOps for Word { + fn from_u8(a: &u8) -> Self { + let mut r: Self; + unsafe { + asm!( + "ldrb {r:w}, [{a_ptr}]", // zero-extended to 32-bits, then 64-bits. + a_ptr = in(reg) polyfill::ptr::from_ref(a), + r = lateout(reg) r, + options(nostack, readonly) + ); + } + r + } + + fn is_zero(self) -> BoolMask { + let r: u64; + unsafe { + asm!( + "subs {r}, {a}, #1", + "sbc {r}, {r}, {r}", // r - r - carry = 0 - carry = -carry. + a = in(reg) self, + r = lateout(reg) r, + options(nomem, nostack, pure) + ); + } + unsafe { mem::transmute::(r) } + } +} diff --git a/src/bb/word/fallback.rs b/src/bb/word/fallback.rs index fb8a092257..20ce194edc 100644 --- a/src/bb/word/fallback.rs +++ b/src/bb/word/fallback.rs @@ -1,6 +1,11 @@ use super::{super::BoolMask, Word, WordOps}; impl WordOps for Word { + #[inline(always)] + fn from_u8(a: &u8) -> Self { + Self::from(*a) + } + #[inline] fn is_zero(self) -> BoolMask { use crate::limb::{Limb, LimbMask}; // XXX: Backwards dependency. diff --git a/src/bb/word/mod.rs b/src/bb/word/mod.rs index 1cfe429085..ccbe2d2d39 100644 --- a/src/bb/word/mod.rs +++ b/src/bb/word/mod.rs @@ -13,6 +13,7 @@ // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. use super::{BoolMask, LeakyWord}; +use cfg_if::cfg_if; /// A native word that may hold a secret. /// @@ -28,6 +29,7 @@ use super::{BoolMask, LeakyWord}; pub(crate) type Word = LeakyWord; pub(crate) trait WordOps: Copy { + fn from_u8(a: &u8) -> Self; fn is_zero(self) -> BoolMask; } @@ -47,4 +49,10 @@ impl From for Word { } */ -mod fallback; +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + } else { + mod fallback; + } +}