From a26dbf3aa0c3f0c68c4ffcdf1670ec998d088c1e Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Fri, 11 Nov 2022 14:32:45 -0800 Subject: [PATCH 1/2] bigint: Provide a fallback implementation for `bn_mul_mont`. Provide an implementation of `bn_mul_mont` that works on all targets that don't have an assembly language implementation. Expand `prefixed_export!` to support prefixing functions defined in Rust. Function definitions don't end with a semicolon so move the semicolon insertion from `prefixed_item!` to its callers. Unify the codepaths in `bigint` so that `bn_mul_mont` is always used. (cherry picked from commit 81f4e8d07da3f2ccc57f69a91245b41e6d764a1c) Test: builds Change-Id: If2cb061684ee1a0831f186c2f4cee3f02c2a236b --- src/arithmetic/bigint.rs | 70 ++----------------- src/arithmetic/bigint/bn_mul_mont_fallback.rs | 51 ++++++++++++++ src/prefixed.rs | 28 ++++++-- 3 files changed, 77 insertions(+), 72 deletions(-) create mode 100644 src/arithmetic/bigint/bn_mul_mont_fallback.rs diff --git a/src/arithmetic/bigint.rs b/src/arithmetic/bigint.rs index 2b2cdf31f..1eb90fead 100644 --- a/src/arithmetic/bigint.rs +++ b/src/arithmetic/bigint.rs @@ -47,6 +47,8 @@ use core::{ ops::{Deref, DerefMut}, }; +mod bn_mul_mont_fallback; + pub unsafe trait Prime {} struct Width { @@ -1231,13 +1233,6 @@ impl From for N0 { fn limbs_mont_mul(r: &mut [Limb], a: &[Limb], m: &[Limb], n0: &N0) { debug_assert_eq!(r.len(), m.len()); debug_assert_eq!(a.len(), m.len()); - - #[cfg(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86_64", - target_arch = "x86" - ))] unsafe { bn_mul_mont( r.as_mut_ptr(), @@ -1248,19 +1243,6 @@ fn limbs_mont_mul(r: &mut [Limb], a: &[Limb], m: &[Limb], n0: &N0) { r.len(), ) } - - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86_64", - target_arch = "x86" - )))] - { - let mut tmp = [0; 2 * MODULUS_MAX_LIMBS]; - let tmp = &mut tmp[..(2 * a.len())]; - limbs_mul(tmp, r, a); - limbs_from_mont_in_place(r, tmp, m, n0); - } } fn limbs_from_mont_in_place(r: &mut [Limb], tmp: &mut [Limb], m: &[Limb], n0: &N0) { @@ -1292,8 +1274,8 @@ fn limbs_from_mont_in_place(r: &mut [Limb], tmp: &mut [Limb], m: &[Limb], n0: &N #[cfg(not(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86_64", - target_arch = "x86" + target_arch = "x86", + target_arch = "x86_64" )))] fn limbs_mul(r: &mut [Limb], a: &[Limb], b: &[Limb]) { debug_assert_eq!(r.len(), 2 * a.len()); @@ -1320,12 +1302,6 @@ fn limbs_mont_product(r: &mut [Limb], a: &[Limb], b: &[Limb], m: &[Limb], n0: &N debug_assert_eq!(a.len(), m.len()); debug_assert_eq!(b.len(), m.len()); - #[cfg(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86_64", - target_arch = "x86" - ))] unsafe { bn_mul_mont( r.as_mut_ptr(), @@ -1336,30 +1312,11 @@ fn limbs_mont_product(r: &mut [Limb], a: &[Limb], b: &[Limb], m: &[Limb], n0: &N r.len(), ) } - - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86_64", - target_arch = "x86" - )))] - { - let mut tmp = [0; 2 * MODULUS_MAX_LIMBS]; - let tmp = &mut tmp[..(2 * a.len())]; - limbs_mul(tmp, a, b); - limbs_from_mont_in_place(r, tmp, m, n0) - } } /// r = r**2 fn limbs_mont_square(r: &mut [Limb], m: &[Limb], n0: &N0) { debug_assert_eq!(r.len(), m.len()); - #[cfg(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86_64", - target_arch = "x86" - ))] unsafe { bn_mul_mont( r.as_mut_ptr(), @@ -1370,27 +1327,8 @@ fn limbs_mont_square(r: &mut [Limb], m: &[Limb], n0: &N0) { r.len(), ) } - - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86_64", - target_arch = "x86" - )))] - { - let mut tmp = [0; 2 * MODULUS_MAX_LIMBS]; - let tmp = &mut tmp[..(2 * r.len())]; - limbs_mul(tmp, r, r); - limbs_from_mont_in_place(r, tmp, m, n0) - } } -#[cfg(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86_64", - target_arch = "x86" -))] prefixed_extern! { // `r` and/or 'a' and/or 'b' may alias. fn bn_mul_mont( diff --git a/src/arithmetic/bigint/bn_mul_mont_fallback.rs b/src/arithmetic/bigint/bn_mul_mont_fallback.rs new file mode 100644 index 000000000..1357858d0 --- /dev/null +++ b/src/arithmetic/bigint/bn_mul_mont_fallback.rs @@ -0,0 +1,51 @@ +// Copyright 2015-2022 Brian Smith. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#![cfg(not(any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "x86", + target_arch = "x86_64" +)))] + +use super::{limbs_from_mont_in_place, limbs_mul, Limb, MODULUS_MAX_LIMBS, N0}; +use crate::c; + +prefixed_export! { + unsafe fn bn_mul_mont( + r: *mut Limb, + a: *const Limb, + b: *const Limb, + n: *const Limb, + n0: &N0, + num_limbs: c::size_t, + ) { + // The mutable pointer `r` may alias `a` and/or `b`, so the lifetimes of + // any slices for `a` or `b` must not overlap with the lifetime of any + // mutable for `r`. + + // Nothing aliases `n` + let n = unsafe { core::slice::from_raw_parts(n, num_limbs) }; + + let mut tmp = [0; 2 * MODULUS_MAX_LIMBS]; + let tmp = &mut tmp[..(2 * num_limbs)]; + { + let a: &[Limb] = unsafe { core::slice::from_raw_parts(a, num_limbs) }; + let b: &[Limb] = unsafe { core::slice::from_raw_parts(b, num_limbs) }; + limbs_mul(tmp, a, b); + } + let r: &mut [Limb] = unsafe { core::slice::from_raw_parts_mut(r, num_limbs) }; + limbs_from_mont_in_place(r, tmp, n, n0); + } +} diff --git a/src/prefixed.rs b/src/prefixed.rs index c8ac807ee..a35f9212f 100644 --- a/src/prefixed.rs +++ b/src/prefixed.rs @@ -14,7 +14,7 @@ macro_rules! prefixed_extern { $name { $( #[$meta] )* - $vis fn $name ( $( $arg_pat : $arg_ty ),* ) $( -> $ret_ty )? + $vis fn $name ( $( $arg_pat : $arg_ty ),* ) $( -> $ret_ty )?; } } @@ -33,15 +33,31 @@ macro_rules! prefixed_extern { $name { $( #[$meta] )* - $vis static mut $name: $typ + $vis static mut $name: $typ; } } } }; } -#[cfg(any(target_arch = "arm", target_arch = "aarch64"))] +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] macro_rules! prefixed_export { + // A function. + { + $( #[$meta:meta] )* + $vis:vis unsafe fn $name:ident ( $( $arg_pat:ident : $arg_ty:ty ),* $(,)? ) $body:block + } => { + prefixed_item! { + export_name + $name + { + $( #[$meta] )* + $vis unsafe fn $name ( $( $arg_pat : $arg_ty ),* ) $body + } + } + }; + + // A global variable. { $( #[$meta:meta] )* $vis:vis static mut $name:ident: $typ:ty = $initial_value:expr; @@ -51,10 +67,10 @@ macro_rules! prefixed_export { $name { $( #[$meta] )* - $vis static mut $name: $typ = $initial_value + $vis static mut $name: $typ = $initial_value; } } - } + }; } macro_rules! prefixed_item { @@ -81,6 +97,6 @@ macro_rules! prefixed_item { { $( $item:tt )+ } } => { #[$attr = $prefixed_name] - $( $item )+; + $( $item )+ }; } -- 2.39.1.519.gcb327c4b5f-goog