Remove non-Montgomery multiplication.
This commit is contained in:
parent
41abee65e6
commit
df505089ee
1
build.rs
1
build.rs
@ -63,7 +63,6 @@ const RING_SRCS: &'static [(&'static [&'static str], &'static str)] = &[
|
||||
(&[], "crypto/fipsmodule/bn/generic.c"),
|
||||
(&[], "crypto/fipsmodule/bn/montgomery.c"),
|
||||
(&[], "crypto/fipsmodule/bn/montgomery_inv.c"),
|
||||
(&[], "crypto/fipsmodule/bn/mul.c"),
|
||||
(&[], "crypto/fipsmodule/bn/shift.c"),
|
||||
(&[], "crypto/fipsmodule/cipher/e_aes.c"),
|
||||
(&[NEVER], "crypto/cipher_extra/e_aesgcmsiv.c"),
|
||||
|
@ -64,23 +64,6 @@
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
void GFp_BN_init(BIGNUM *bn) {
|
||||
memset(bn, 0, sizeof(BIGNUM));
|
||||
}
|
||||
|
||||
void GFp_BN_free(BIGNUM *bn) {
|
||||
// Keep this in sync with the |Drop| impl for |BIGNUM| in
|
||||
// |ring::rsa::bigint|.
|
||||
|
||||
if (bn == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
OPENSSL_free(bn->d);
|
||||
|
||||
bn->d = NULL;
|
||||
}
|
||||
|
||||
int GFp_BN_copy(BIGNUM *dest, const BIGNUM *src) {
|
||||
if (src == dest) {
|
||||
return 1;
|
||||
@ -98,10 +81,6 @@ int GFp_BN_copy(BIGNUM *dest, const BIGNUM *src) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void GFp_BN_zero(BIGNUM *bn) {
|
||||
bn->top = 0;
|
||||
}
|
||||
|
||||
int GFp_bn_wexpand(BIGNUM *bn, size_t words) {
|
||||
BN_ULONG *a;
|
||||
|
||||
|
@ -258,7 +258,7 @@ int GFp_BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a_mont,
|
||||
unsigned char *powerbuf = NULL;
|
||||
|
||||
const int top = n->top;
|
||||
if (!GFp_bn_mul_mont_check_top(top)) {
|
||||
if (!GFp_bn_mul_mont_check_num_limbs(top)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -72,23 +72,6 @@
|
||||
(r) = ret; \
|
||||
} while (0)
|
||||
|
||||
#define mul(r, a, w, c) \
|
||||
do { \
|
||||
BN_ULONG high, low, ret, ta = (a); \
|
||||
bn_umult_lohi(&low, &high, w, ta); \
|
||||
ret = low + (c); \
|
||||
(c) = high; \
|
||||
(c) += (ret < low) ? 1 : 0; \
|
||||
(r) = ret; \
|
||||
} while (0)
|
||||
|
||||
#define sqr(r0, r1, a) \
|
||||
do { \
|
||||
BN_ULONG tmp = (a); \
|
||||
bn_umult_lohi(&r0, &r1, tmp, tmp); \
|
||||
} while (0)
|
||||
|
||||
|
||||
BN_ULONG GFp_bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num,
|
||||
BN_ULONG w) {
|
||||
BN_ULONG c1 = 0;
|
||||
@ -116,29 +99,3 @@ BN_ULONG GFp_bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num,
|
||||
|
||||
return c1;
|
||||
}
|
||||
|
||||
BN_ULONG GFp_bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num,
|
||||
BN_ULONG w) {
|
||||
BN_ULONG c1 = 0;
|
||||
|
||||
if (num == 0) {
|
||||
return c1;
|
||||
}
|
||||
|
||||
while (num & ~3) {
|
||||
mul(rp[0], ap[0], w, c1);
|
||||
mul(rp[1], ap[1], w, c1);
|
||||
mul(rp[2], ap[2], w, c1);
|
||||
mul(rp[3], ap[3], w, c1);
|
||||
ap += 4;
|
||||
rp += 4;
|
||||
num -= 4;
|
||||
}
|
||||
while (num) {
|
||||
mul(rp[0], ap[0], w, c1);
|
||||
ap++;
|
||||
rp++;
|
||||
num--;
|
||||
}
|
||||
return c1;
|
||||
}
|
||||
|
@ -178,12 +178,6 @@ extern "C" {
|
||||
BN_ULONG GFp_bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num,
|
||||
BN_ULONG w);
|
||||
|
||||
// bn_mul_words multiples |ap| by |w| and places the result in |rp|. |ap| and
|
||||
// |rp| must both be |num| words long. It returns the carry word of the
|
||||
// operation. |ap| and |rp| may be equal but otherwise may not alias.
|
||||
BN_ULONG GFp_bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num,
|
||||
BN_ULONG w);
|
||||
|
||||
// |num| must be at least 4, at least on x86.
|
||||
//
|
||||
// In other forks, |bn_mul_mont| returns an |int| indicating whether it
|
||||
@ -200,7 +194,7 @@ OPENSSL_COMPILE_ASSERT(sizeof(int) == sizeof(size_t) ||
|
||||
int_and_size_t_abi_mismatch);
|
||||
void GFp_bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
const BN_ULONG *np, const BN_ULONG *n0, size_t num);
|
||||
int GFp_bn_mul_mont_check_top(int top);
|
||||
int GFp_bn_mul_mont_check_num_limbs(size_t top);
|
||||
|
||||
static inline void bn_umult_lohi(BN_ULONG *low_out, BN_ULONG *high_out,
|
||||
BN_ULONG a, BN_ULONG b) {
|
||||
|
@ -199,48 +199,10 @@ int GFp_BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, const BIGNUM *n,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int GFp_bn_mul_mont_check_top(int top) {
|
||||
int GFp_bn_mul_mont_check_num_limbs(size_t num_limbs) {
|
||||
// GFp_bn_mul_mont requires at least four limbs, at least for x86.
|
||||
if (top < 4) {
|
||||
if (num_limbs < 4) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Assumes a < n and b < n
|
||||
int GFp_BN_mod_mul_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
const BIGNUM *n,
|
||||
const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS]) {
|
||||
int num = n->top;
|
||||
|
||||
if (!GFp_bn_mul_mont_check_top(num)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->top == num && b->top == num) {
|
||||
if (!GFp_bn_wexpand(r, num)) {
|
||||
return 0;
|
||||
}
|
||||
GFp_bn_mul_mont(r->d, a->d, b->d, n->d, n0, num);
|
||||
r->top = num;
|
||||
GFp_bn_correct_top(r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
BIGNUM tmp;
|
||||
GFp_BN_init(&tmp);
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (!GFp_BN_mul_no_alias(&tmp, a, b) ||
|
||||
!GFp_BN_from_montgomery_word(r, &tmp, n, n0)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
GFp_BN_free(&tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,135 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <GFp/bn.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
static void GFp_bn_mul_normal(BN_ULONG *r, const BN_ULONG *a, size_t na,
|
||||
const BN_ULONG *b, size_t nb) {
|
||||
assert(r != a);
|
||||
assert(r != b);
|
||||
|
||||
if (na < nb) {
|
||||
size_t itmp = na;
|
||||
na = nb;
|
||||
nb = itmp;
|
||||
const BN_ULONG *ltmp = a;
|
||||
a = b;
|
||||
b = ltmp;
|
||||
}
|
||||
BN_ULONG *rr = &(r[na]);
|
||||
if (nb == 0) {
|
||||
memset(r, 0, na * sizeof(BN_ULONG));
|
||||
return;
|
||||
}
|
||||
rr[0] = GFp_bn_mul_words(r, a, na, b[0]);
|
||||
|
||||
for (;;) {
|
||||
if (--nb == 0) {
|
||||
return;
|
||||
}
|
||||
rr[1] = GFp_bn_mul_add_words(&(r[1]), a, na, b[1]);
|
||||
if (--nb == 0) {
|
||||
return;
|
||||
}
|
||||
rr[2] = GFp_bn_mul_add_words(&(r[2]), a, na, b[2]);
|
||||
if (--nb == 0) {
|
||||
return;
|
||||
}
|
||||
rr[3] = GFp_bn_mul_add_words(&(r[3]), a, na, b[3]);
|
||||
if (--nb == 0) {
|
||||
return;
|
||||
}
|
||||
rr[4] = GFp_bn_mul_add_words(&(r[4]), a, na, b[4]);
|
||||
rr += 4;
|
||||
r += 4;
|
||||
b += 4;
|
||||
}
|
||||
}
|
||||
|
||||
int GFp_BN_mul_no_alias(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
assert(r != a);
|
||||
assert(r != b);
|
||||
|
||||
int ret = 0;
|
||||
int top, al, bl;
|
||||
|
||||
al = a->top;
|
||||
bl = b->top;
|
||||
|
||||
if ((al == 0) || (bl == 0)) {
|
||||
GFp_BN_zero(r);
|
||||
return 1;
|
||||
}
|
||||
top = al + bl;
|
||||
|
||||
if (!GFp_bn_wexpand(r, top)) {
|
||||
goto err;
|
||||
}
|
||||
r->top = top;
|
||||
GFp_bn_mul_normal(r->d, a->d, al, b->d, bl);
|
||||
|
||||
GFp_bn_correct_top(r);
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
@ -154,24 +154,11 @@ extern "C" {
|
||||
|
||||
// Allocation and freeing.
|
||||
|
||||
// GFp_BN_init initialises a stack allocated |BIGNUM|.
|
||||
OPENSSL_EXPORT void GFp_BN_init(BIGNUM *bn);
|
||||
|
||||
// GFp_BN_free frees the data referenced by |bn| and, if |bn| was originally
|
||||
// allocated on the heap, frees |bn| also.
|
||||
OPENSSL_EXPORT void GFp_BN_free(BIGNUM *bn);
|
||||
|
||||
// GFp_BN_copy sets |dest| equal to |src| and returns one on success or zero on
|
||||
// failure.
|
||||
OPENSSL_EXPORT int GFp_BN_copy(BIGNUM *dest, const BIGNUM *src);
|
||||
|
||||
|
||||
// Basic functions.
|
||||
|
||||
// GFp_BN_zero sets |bn| to zero.
|
||||
OPENSSL_EXPORT void GFp_BN_zero(BIGNUM *bn);
|
||||
|
||||
|
||||
// Internal functions.
|
||||
//
|
||||
// These functions are useful for code that is doing low-level manipulations of
|
||||
@ -188,13 +175,6 @@ OPENSSL_EXPORT void GFp_bn_correct_top(BIGNUM *bn);
|
||||
OPENSSL_EXPORT int GFp_bn_wexpand(BIGNUM *bn, size_t words);
|
||||
|
||||
|
||||
// Simple arithmetic
|
||||
|
||||
// GFp_BN_mul_no_alias sets |r| = |a| * |b|, where |r| must not be the same pointer
|
||||
// as |a| or |b|. Returns one on success and zero otherwise.
|
||||
OPENSSL_EXPORT int GFp_BN_mul_no_alias(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
|
||||
|
||||
|
||||
// Modulo arithmetic.
|
||||
|
||||
// GFp_BN_mod_mul_mont set |r| equal to |a| * |b|, in the Montgomery domain.
|
||||
|
@ -38,6 +38,7 @@
|
||||
//! [Static checking of units in Servo]:
|
||||
//! https://blog.mozilla.org/research/2014/06/23/static-checking-of-units-in-servo/
|
||||
|
||||
#![allow(box_pointers)]
|
||||
|
||||
use {bits, bssl, c, error, limb, untrusted};
|
||||
use arithmetic::montgomery::*;
|
||||
@ -389,17 +390,39 @@ impl<AF, BF, M> ModMul<Elem<M, BF>, M> for Elem<M, AF>
|
||||
}
|
||||
}
|
||||
|
||||
pub fn elem_mul<M, AF, BF>(a: &Elem<M, AF>, b: Elem<M, BF>, m: &Modulus<M>)
|
||||
pub fn elem_mul<M, AF, BF>(a: &Elem<M, AF>, mut b: Elem<M, BF>, m: &Modulus<M>)
|
||||
-> Result<Elem<M, <(AF, BF) as ProductEncoding>::Output>,
|
||||
error::Unspecified>
|
||||
where (AF, BF): ProductEncoding {
|
||||
let mut r = b.value;
|
||||
let m_limbs = (m.value.0).0.limbs();
|
||||
let num_limbs = m_limbs.len();
|
||||
bssl::map_result(unsafe {
|
||||
GFp_BN_mod_mul_mont(&mut r.0, a.value.as_ref(), &r.0, &m.value.as_ref(),
|
||||
&m.n0)
|
||||
GFp_bn_mul_mont_check_num_limbs(num_limbs)
|
||||
})?;
|
||||
|
||||
let mut a_limbs;
|
||||
let a_limbs = if a.value.limbs().len() == num_limbs {
|
||||
a.value.limbs()
|
||||
} else {
|
||||
assert!(a.value.limbs().len() < num_limbs);
|
||||
a_limbs = vec![0; num_limbs];
|
||||
a_limbs[..a.value.limbs().len()].copy_from_slice(a.value.limbs());
|
||||
&a_limbs
|
||||
};
|
||||
|
||||
b.value.0.make_limbs(num_limbs, |b_limbs| {
|
||||
assert_eq!(a_limbs.len(), num_limbs);
|
||||
assert_eq!(b_limbs.len(), num_limbs);
|
||||
unsafe {
|
||||
GFp_bn_mul_mont(b_limbs.as_mut_ptr(), a_limbs.as_ptr(),
|
||||
b_limbs.as_ptr(), m_limbs.as_ptr(), &m.n0,
|
||||
num_limbs)
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(Elem {
|
||||
value: r,
|
||||
value: b.value,
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
})
|
||||
@ -412,9 +435,42 @@ pub fn elem_set_to_product<M, AF, BF>(
|
||||
a: &Elem<M, AF>, b: &Elem<M, BF>, m: &Modulus<M>)
|
||||
-> Result<(), error::Unspecified>
|
||||
where (AF, BF): ProductEncoding {
|
||||
let m_limbs = (m.value.0).0.limbs();
|
||||
let num_limbs = m_limbs.len();
|
||||
bssl::map_result(unsafe {
|
||||
GFp_BN_mod_mul_mont(r.value.as_mut_ref(), a.value.as_ref(),
|
||||
b.value.as_ref(), &m.value.as_ref(), &m.n0)
|
||||
GFp_bn_mul_mont_check_num_limbs(num_limbs)
|
||||
})?;
|
||||
|
||||
let mut a_limbs;
|
||||
let a_limbs = if a.value.limbs().len() == num_limbs {
|
||||
a.value.limbs()
|
||||
} else {
|
||||
assert!(a.value.limbs().len() < num_limbs);
|
||||
a_limbs = vec![0; num_limbs];
|
||||
a_limbs[..a.value.limbs().len()].copy_from_slice(a.value.limbs());
|
||||
&a_limbs
|
||||
};
|
||||
|
||||
let mut b_limbs;
|
||||
let b_limbs = if b.value.limbs().len() == num_limbs {
|
||||
b.value.limbs()
|
||||
} else {
|
||||
assert!(b.value.limbs().len() < num_limbs);
|
||||
b_limbs = vec![0; num_limbs];
|
||||
b_limbs[..b.value.limbs().len()].copy_from_slice(b.value.limbs());
|
||||
&b_limbs
|
||||
};
|
||||
|
||||
r.value.0.make_limbs(num_limbs, |r_limbs| {
|
||||
assert_eq!(r_limbs.len(), num_limbs);
|
||||
assert_eq!(a_limbs.len(), num_limbs);
|
||||
assert_eq!(b_limbs.len(), num_limbs);
|
||||
unsafe {
|
||||
GFp_bn_mul_mont(r_limbs.as_mut_ptr(), a_limbs.as_ptr(),
|
||||
b_limbs.as_ptr(), m_limbs.as_ptr(), &m.n0,
|
||||
num_limbs)
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@ -462,13 +518,19 @@ pub fn elem_squared<M, E>(a: Elem<M, E>, m: &Modulus<M>)
|
||||
-> Result<Elem<M, <(E, E) as ProductEncoding>::Output>,
|
||||
error::Unspecified>
|
||||
where (E, E): ProductEncoding {
|
||||
let m_limbs = (m.value.0).0.limbs();
|
||||
let num_limbs = m_limbs.len();
|
||||
let mut value = a.value;
|
||||
bssl::map_result(unsafe {
|
||||
GFp_BN_mod_mul_mont(value.as_mut_ref(), value.as_ref(), value.as_ref(),
|
||||
&m.value.as_ref(), &m.n0)
|
||||
value.0.make_limbs(num_limbs, |limbs| {
|
||||
assert_eq!(limbs.len(), num_limbs);
|
||||
unsafe {
|
||||
GFp_bn_mul_mont(limbs.as_mut_ptr(), limbs.as_ptr(), limbs.as_ptr(),
|
||||
m_limbs.as_ptr(), &m.n0, num_limbs)
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(Elem {
|
||||
value: value,
|
||||
value,
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
})
|
||||
@ -1203,8 +1265,10 @@ pub use self::repr_c::BIGNUM;
|
||||
|
||||
extern {
|
||||
// `r` and/or 'a' and/or 'b' may alias.
|
||||
fn GFp_BN_mod_mul_mont(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM,
|
||||
n: &BIGNUM, n0: &N0) -> c::int;
|
||||
fn GFp_bn_mul_mont(r: *mut limb::Limb, a: *const limb::Limb,
|
||||
b: *const limb::Limb, n: *const limb::Limb,
|
||||
n0: &N0, num_limbs: c::size_t);
|
||||
fn GFp_bn_mul_mont_check_num_limbs(num_limbs: c::size_t) -> c::int;
|
||||
|
||||
// The use of references here implies lack of aliasing.
|
||||
fn GFp_BN_copy(a: &mut BIGNUM, b: &BIGNUM) -> c::int;
|
||||
|
Loading…
x
Reference in New Issue
Block a user