Remove now-unused BIGNUM functions, and bn_test.cc (the last C++ use).

These functions can be removed thanks to the new modular inversion
implementation.
This commit is contained in:
Brian Smith 2017-04-14 21:10:21 -10:00
parent e46b485c09
commit efdffc91db
19 changed files with 1 additions and 10368 deletions

View File

@ -148,11 +148,8 @@ include = [
"crypto/bn/asm/x86_64-mont.pl",
"crypto/bn/asm/x86_64-mont5.pl",
"crypto/bn/bn.c",
"crypto/bn/bn_test.cc",
"crypto/bn/bn_tests.txt",
"crypto/bn/cmp.c",
"crypto/bn/convert.c",
"crypto/bn/ctx.c",
"crypto/bn/div.c",
"crypto/bn/exponentiation.c",
"crypto/bn/gcd.c",
@ -227,14 +224,6 @@ include = [
"crypto/sha/asm/sha512-armv4.pl",
"crypto/sha/asm/sha512-armv8.pl",
"crypto/sha/asm/sha512-x86_64.pl",
"crypto/test/bn_test_convert.c",
"crypto/test/bn_test_lib.c",
"crypto/test/bn_test_lib.h",
"crypto/test/bn_test_new.c",
"crypto/test/bn_test_util.h",
"crypto/test/file_test.cc",
"crypto/test/file_test.h",
"crypto/test/scoped_types.h",
"include/GFp/aes.h",
"include/GFp/arm_arch.h",
"include/GFp/base.h",
@ -287,11 +276,10 @@ rayon = "0.7"
default = ["use_heap", "dev_urandom_fallback"]
dev_urandom_fallback = []
internal_benches = []
rsa_signing = ["bn_tests", "use_heap"]
rsa_signing = ["use_heap"]
slow_tests = []
test_logging = []
use_heap = []
bn_tests = []
# XXX: debug = false because of https://github.com/rust-lang/rust/issues/34122

View File

@ -89,7 +89,6 @@ const RING_SRCS: &'static [(&'static [&'static str], &'static str)] = &[
(&[], "crypto/bn/convert.c"),
(&[], "crypto/bn/div.c"),
(&[], "crypto/bn/exponentiation.c"),
(&[], "crypto/bn/gcd.c"),
(&[], "crypto/bn/generic.c"),
(&[], "crypto/bn/montgomery.c"),
(&[], "crypto/bn/montgomery_inv.c"),
@ -168,11 +167,7 @@ const SHA256_ARMV8: &'static str = "crypto/sha/asm/sha256-armv8.pl";
const SHA512_ARMV8: &'static str = "crypto/sha/asm/sha512-armv8.pl";
const RING_TEST_SRCS: &'static [&'static str] = &[
("crypto/bn/bn_test.cc"),
("crypto/constant_time_test.c"),
("crypto/test/bn_test_convert.c"),
("crypto/test/bn_test_new.c"),
("crypto/test/file_test.cc"),
];
#[cfg_attr(rustfmt, rustfmt_skip)]
@ -189,10 +184,6 @@ const RING_INCLUDES: &'static [&'static str] =
"crypto/limbs/limbs.h",
"crypto/limbs/limbs.inl",
"crypto/modes/internal.h",
"crypto/test/bn_test_lib.h",
"crypto/test/bn_test_util.h",
"crypto/test/file_test.h",
"crypto/test/scoped_types.h",
"include/GFp/aes.h",
"include/GFp/arm_arch.h",
"include/GFp/base.h",
@ -229,17 +220,6 @@ fn c_flags(target: &Target) -> &'static [&'static str] {
}
}
fn cxx_flags(target: &Target) -> &'static [&'static str] {
if target.env != MSVC {
static NON_MSVC_FLAGS: &'static [&'static str] = &[
"-std=c++0x" // GCC 4.6 requires "c++0x" instead of "c++11"
];
NON_MSVC_FLAGS
} else {
&[]
}
}
fn cpp_flags(target: &Target) -> &'static [&'static str] {
if target.env != MSVC {
static NON_MSVC_FLAGS: &'static [&'static str] = &[
@ -482,14 +462,6 @@ fn build_c_code(target: &Target, pregenerated: PathBuf, out_dir: &Path) {
let test_srcs = RING_TEST_SRCS.iter()
.map(PathBuf::from)
// Allow the C++-based tests to be disabled
.filter(|p| cfg!(feature = "bn_tests") ||
p.extension().unwrap().to_str().unwrap() != "cc")
// Avoid the libstdc++ vs libc++ issue for macOS/iOS, and g++ issue on
// musl by just avoiding all the C++-based tests.
.filter(|p| !(target.os() == "macos" || target.os == "ios" ||
target.env() == "musl") ||
p.extension().unwrap().to_str().unwrap() != "cc")
.collect::<Vec<_>>();
let libs = [
@ -505,18 +477,6 @@ fn build_c_code(target: &Target, pregenerated: PathBuf, out_dir: &Path) {
build_library(&target, &out_dir, lib_name, srcs, additional_srcs,
includes_modified));
if target.env() != "msvc" &&
target.env() != "musl" &&
cfg!(feature = "bn_tests") &&
!(target.os() == "macos" || target.os() == "ios") {
let libcxx = if use_libcxx(target) {
"c++"
} else {
"stdc++"
};
println!("cargo:rustc-flags=-l dylib={}", libcxx);
}
println!("cargo:rustc-link-search=native={}",
out_dir.to_str().expect("Invalid path"));
}
@ -613,15 +573,6 @@ fn cc(file: &Path, ext: &str, target: &Target, out_dir: &Path) -> Command {
let _ = c.flag(f);
}
},
"cc" => {
for f in cxx_flags(target) {
let _ = c.flag(f);
}
let _ = c.cpp(true);
if use_libcxx(target) {
let _ = c.cpp_set_stdlib(Some("c++"));
}
},
"S" => {},
e => panic!("Unsupported file extension: {:?}", e),
};
@ -696,10 +647,6 @@ fn yasm(file: &Path, arch: &str, out_file: &Path) -> Command {
c
}
fn use_libcxx(target: &Target) -> bool {
target.os() == "freebsd"
}
fn run_command_with_args<S>(command_name: S, args: &[String])
where S: AsRef<std::ffi::OsStr> + Copy
{
@ -835,7 +782,6 @@ fn is_tracked(file: &DirEntry) {
RING_INCLUDES.iter().any(cmp)
},
Some("c") |
Some("cc") |
Some("S") |
Some("asm") => {
RING_SRCS.iter().any(|&(_, ref f)| cmp(f)) ||

View File

@ -1,558 +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.]
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the Eric Young open source
* license provided above.
*
* The binary polynomial arithmetic software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
* Laboratories. */
/* Per C99, various stdint.h and inttypes.h macros (the latter used by bn.h) are
* unavailable in C++ unless some macros are defined. C++11 overruled this
* decision, but older Android NDKs still require it. */
#if !defined(__STDC_FORMAT_MACROS)
#define __STDC_FORMAT_MACROS
#endif
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <utility>
#include <GFp/bn.h>
#include <GFp/err.h>
#include <GFp/mem.h>
#include "../test/bn_test_lib.h"
#include "../crypto/test/file_test.h"
#include "../crypto/test/scoped_types.h"
#include "../test/bn_test_util.h"
/* Prototypes to avoid -Wmissing-prototypes warnings. */
extern "C" int bssl_bn_test_main(void);
static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
BIGNUM *raw = NULL;
int ret = GFp_BN_hex2bn(&raw, in);
out->reset(raw);
return ret;
}
static ScopedBIGNUM GetBIGNUM(FileTest *t, const char *attribute) {
std::string hex;
if (!t->GetAttribute(&hex, attribute)) {
return nullptr;
}
ScopedBIGNUM ret;
if (HexToBIGNUM(&ret, hex.c_str()) != static_cast<int>(hex.size())) {
t->PrintLine("Could not decode '", hex.c_str(), "'.");
return nullptr;
}
return ret;
}
static bool GetInt(FileTest *t, int *out, const char *attribute) {
ScopedBIGNUM ret = GetBIGNUM(t, attribute);
if (!ret) {
return false;
}
// This is |BN_get_word|, inlined and improved.
switch (ret->top) {
case 0:
*out = 0;
return 1;
case 1:
if (ret->d[0] > (BN_ULONG)INT_MAX) {
return false;
}
*out = static_cast<int>(ret->d[0]);
return true;
default:
return false;
}
}
static bool ExpectBIGNUMsEqual(FileTest *t, const char *operation,
const BIGNUM *expected, const BIGNUM *actual) {
if (GFp_BN_cmp(expected, actual) == 0) {
return true;
}
t->PrintLine("Got wrong value for ", operation);
return false;
}
static bool TestSum(FileTest *t) {
ScopedBIGNUM a = GetBIGNUM(t, "A");
ScopedBIGNUM b = GetBIGNUM(t, "B");
ScopedBIGNUM sum = GetBIGNUM(t, "Sum");
if (!a || !b || !sum) {
return false;
}
ScopedBIGNUM ret(GFp_BN_new());
if (!ret ||
!GFp_BN_add(ret.get(), a.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "A + B", sum.get(), ret.get()) ||
!GFp_BN_sub(ret.get(), sum.get(), a.get()) ||
!ExpectBIGNUMsEqual(t, "Sum - A", b.get(), ret.get()) ||
!GFp_BN_sub(ret.get(), sum.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "Sum - B", a.get(), ret.get())) {
return false;
}
// Test that the functions work when |r| and |a| point to the same |BIGNUM|,
// or when |r| and |b| point to the same |BIGNUM|. TODO: Test the case where
// all of |r|, |a|, and |b| point to the same |BIGNUM|.
if (!GFp_BN_copy(ret.get(), a.get()) ||
!GFp_BN_add(ret.get(), ret.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "A + B (r is a)", sum.get(), ret.get()) ||
!GFp_BN_copy(ret.get(), b.get()) ||
!GFp_BN_add(ret.get(), a.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "A + B (r is b)", sum.get(), ret.get()) ||
!GFp_BN_copy(ret.get(), sum.get()) ||
!GFp_BN_sub(ret.get(), ret.get(), a.get()) ||
!ExpectBIGNUMsEqual(t, "Sum - A (r is a)", b.get(), ret.get()) ||
!GFp_BN_copy(ret.get(), a.get()) ||
!GFp_BN_sub(ret.get(), sum.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "Sum - A (r is b)", b.get(), ret.get()) ||
!GFp_BN_copy(ret.get(), sum.get()) ||
!GFp_BN_sub(ret.get(), ret.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "Sum - B (r is a)", a.get(), ret.get()) ||
!GFp_BN_copy(ret.get(), b.get()) ||
!GFp_BN_sub(ret.get(), sum.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "Sum - B (r is b)", a.get(), ret.get())) {
return false;
}
// Test |GFp_BN_uadd| and |GFp_BN_usub| with the prerequisites they are
// documented as having. Note that these functions are frequently used when
// the prerequisites don't hold. In those cases, they are supposed to work as
// if the prerequisite hold, but we don't test that yet. TODO: test that.
if (!GFp_BN_is_negative(a.get()) &&
!GFp_BN_is_negative(b.get()) && GFp_BN_cmp(a.get(), b.get()) >= 0) {
if (!GFp_BN_uadd(ret.get(), a.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "A +u B", sum.get(), ret.get()) ||
!GFp_BN_usub(ret.get(), sum.get(), a.get()) ||
!ExpectBIGNUMsEqual(t, "Sum -u A", b.get(), ret.get()) ||
!GFp_BN_usub(ret.get(), sum.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "Sum -u B", a.get(), ret.get())) {
return false;
}
// Test that the functions work when |r| and |a| point to the same |BIGNUM|,
// or when |r| and |b| point to the same |BIGNUM|. TODO: Test the case where
// all of |r|, |a|, and |b| point to the same |BIGNUM|.
if (!GFp_BN_copy(ret.get(), a.get()) ||
!GFp_BN_uadd(ret.get(), ret.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "A +u B (r is a)", sum.get(), ret.get()) ||
!GFp_BN_copy(ret.get(), b.get()) ||
!GFp_BN_uadd(ret.get(), a.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "A +u B (r is b)", sum.get(), ret.get()) ||
!GFp_BN_copy(ret.get(), sum.get()) ||
!GFp_BN_usub(ret.get(), ret.get(), a.get()) ||
!ExpectBIGNUMsEqual(t, "Sum -u A (r is a)", b.get(), ret.get()) ||
!GFp_BN_copy(ret.get(), a.get()) ||
!GFp_BN_usub(ret.get(), sum.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "Sum -u A (r is b)", b.get(), ret.get()) ||
!GFp_BN_copy(ret.get(), sum.get()) ||
!GFp_BN_usub(ret.get(), ret.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "Sum -u B (r is a)", a.get(), ret.get()) ||
!GFp_BN_copy(ret.get(), b.get()) ||
!GFp_BN_usub(ret.get(), sum.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "Sum -u B (r is b)", a.get(), ret.get())) {
return false;
}
}
return true;
}
static bool TestLShift1(FileTest *t) {
ScopedBIGNUM a = GetBIGNUM(t, "A");
ScopedBIGNUM lshift1 = GetBIGNUM(t, "LShift1");
ScopedBIGNUM zero(GFp_BN_new());
if (!a || !lshift1 || !zero) {
return false;
}
GFp_BN_zero(zero.get());
ScopedBIGNUM ret(GFp_BN_new()), two(GFp_BN_new()), remainder(GFp_BN_new());
if (!ret || !two || !remainder ||
!GFp_BN_set_word(two.get(), 2) ||
!GFp_BN_add(ret.get(), a.get(), a.get()) ||
!ExpectBIGNUMsEqual(t, "A + A", lshift1.get(), ret.get()) ||
!GFp_BN_mul_no_alias(ret.get(), a.get(), two.get()) ||
!ExpectBIGNUMsEqual(t, "A * 2", lshift1.get(), ret.get()) ||
!GFp_BN_div(ret.get(), remainder.get(), lshift1.get(), two.get()) ||
!ExpectBIGNUMsEqual(t, "LShift1 / 2", a.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "LShift1 % 2", zero.get(), remainder.get()) ||
!GFp_BN_lshift(ret.get(), a.get(), 1) ||
!ExpectBIGNUMsEqual(t, "A << 1", lshift1.get(), ret.get()) ||
!GFp_BN_rshift1(ret.get(), lshift1.get()) ||
!ExpectBIGNUMsEqual(t, "LShift >> 1", a.get(), ret.get()) ||
!GFp_BN_rshift1(ret.get(), lshift1.get()) ||
!ExpectBIGNUMsEqual(t, "LShift >> 1", a.get(), ret.get())) {
return false;
}
// Set the LSB to 1 and test rshift1 again.
if (!GFp_BN_set_bit(lshift1.get(), 0) ||
!GFp_BN_div(ret.get(), nullptr /* rem */, lshift1.get(), two.get()) ||
!ExpectBIGNUMsEqual(t, "(LShift1 | 1) / 2", a.get(), ret.get()) ||
!GFp_BN_rshift1(ret.get(), lshift1.get()) ||
!ExpectBIGNUMsEqual(t, "(LShift | 1) >> 1", a.get(), ret.get())) {
return false;
}
return true;
}
static bool TestLShift(FileTest *t) {
ScopedBIGNUM a = GetBIGNUM(t, "A");
ScopedBIGNUM lshift = GetBIGNUM(t, "LShift");
int n = 0;
if (!a || !lshift || !GetInt(t, &n, "N")) {
return false;
}
ScopedBIGNUM ret(GFp_BN_new());
if (!ret ||
!GFp_BN_lshift(ret.get(), a.get(), n) ||
!ExpectBIGNUMsEqual(t, "A << N", lshift.get(), ret.get()) ||
!GFp_BN_rshift(ret.get(), lshift.get(), n) ||
!ExpectBIGNUMsEqual(t, "A >> N", a.get(), ret.get())) {
return false;
}
return true;
}
static bool TestRShift(FileTest *t) {
ScopedBIGNUM a = GetBIGNUM(t, "A");
ScopedBIGNUM rshift = GetBIGNUM(t, "RShift");
int n = 0;
if (!a || !rshift || !GetInt(t, &n, "N")) {
return false;
}
ScopedBIGNUM ret(GFp_BN_new());
if (!ret ||
!GFp_BN_rshift(ret.get(), a.get(), n) ||
!ExpectBIGNUMsEqual(t, "A >> N", rshift.get(), ret.get())) {
return false;
}
return true;
}
static bool TestSquare(FileTest *t) {
ScopedBIGNUM a = GetBIGNUM(t, "A");
ScopedBIGNUM square = GetBIGNUM(t, "Square");
ScopedBIGNUM zero(GFp_BN_new());
if (!a || !square || !zero) {
return false;
}
GFp_BN_zero(zero.get());
ScopedBIGNUM ret(GFp_BN_new()), remainder(GFp_BN_new());
if (!ret || !remainder ||
!GFp_BN_mul_no_alias(ret.get(), a.get(), a.get()) ||
!ExpectBIGNUMsEqual(t, "A * A", square.get(), ret.get()) ||
!GFp_BN_div(ret.get(), remainder.get(), square.get(), a.get()) ||
!ExpectBIGNUMsEqual(t, "Square / A", a.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "Square % A", zero.get(), remainder.get())) {
return false;
}
return true;
}
static bool TestProduct(FileTest *t) {
ScopedBIGNUM a = GetBIGNUM(t, "A");
ScopedBIGNUM b = GetBIGNUM(t, "B");
ScopedBIGNUM product = GetBIGNUM(t, "Product");
ScopedBIGNUM zero(GFp_BN_new());
if (!a || !b || !product || !zero) {
return false;
}
GFp_BN_zero(zero.get());
ScopedBIGNUM ret(GFp_BN_new()), remainder(GFp_BN_new());
if (!ret || !remainder ||
!GFp_BN_mul_no_alias(ret.get(), a.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "A * B", product.get(), ret.get()) ||
!GFp_BN_div(ret.get(), remainder.get(), product.get(), a.get()) ||
!ExpectBIGNUMsEqual(t, "Product / A", b.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "Product % A", zero.get(), remainder.get()) ||
!GFp_BN_div(ret.get(), remainder.get(), product.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "Product / B", a.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "Product % B", zero.get(), remainder.get())) {
return false;
}
return true;
}
static bool TestQuotient(FileTest *t) {
ScopedBIGNUM a = GetBIGNUM(t, "A");
ScopedBIGNUM b = GetBIGNUM(t, "B");
ScopedBIGNUM quotient = GetBIGNUM(t, "Quotient");
ScopedBIGNUM remainder = GetBIGNUM(t, "Remainder");
if (!a || !b || !quotient || !remainder) {
return false;
}
ScopedBIGNUM ret(GFp_BN_new()), ret2(GFp_BN_new());
if (!ret || !ret2 ||
!GFp_BN_div(ret.get(), ret2.get(), a.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "A / B", quotient.get(), ret.get()) ||
!ExpectBIGNUMsEqual(t, "A % B", remainder.get(), ret2.get()) ||
!GFp_BN_mul_no_alias(ret.get(), quotient.get(), b.get()) ||
!GFp_BN_add(ret.get(), ret.get(), remainder.get()) ||
!ExpectBIGNUMsEqual(t, "Quotient * B + Remainder", a.get(), ret.get())) {
return false;
}
// Test GFp_BN_nnmod.
if (!GFp_BN_is_negative(b.get())) {
ScopedBIGNUM nnmod(GFp_BN_new());
if (!nnmod ||
!GFp_BN_copy(nnmod.get(), remainder.get()) ||
(GFp_BN_is_negative(nnmod.get()) &&
!GFp_BN_add(nnmod.get(), nnmod.get(), b.get())) ||
!GFp_BN_nnmod(ret.get(), a.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "A % B (non-negative)", nnmod.get(),
ret.get())) {
return false;
}
}
return true;
}
static bool TestModInv(FileTest *t) {
ScopedBIGNUM a = GetBIGNUM(t, "A");
ScopedBIGNUM m = GetBIGNUM(t, "M");
ScopedBIGNUM mod_inv = GetBIGNUM(t, "ModInv");
if (!a || !m || !mod_inv) {
return false;
}
ScopedBIGNUM ret(GFp_BN_new());
int no_inverse;
if (!ret ||
!GFp_BN_mod_inverse_odd(ret.get(), &no_inverse, a.get(), m.get()) ||
no_inverse ||
!ExpectBIGNUMsEqual(t, "inv(A) (mod M)", mod_inv.get(), ret.get())) {
return false;
}
return true;
}
struct Test {
const char *name;
bool (*func)(FileTest *t);
};
static const Test kTests[] = {
{"Sum", TestSum},
{"LShift1", TestLShift1},
{"LShift", TestLShift},
{"RShift", TestRShift},
{"Square", TestSquare},
{"Product", TestProduct},
{"Quotient", TestQuotient},
{"ModInv", TestModInv},
};
static bool RunTest(FileTest *t, void *) {
for (const Test &test : kTests) {
if (t->GetType() != test.name) {
continue;
}
return test.func(t);
}
t->PrintLine("Unknown test type: ", t->GetType().c_str());
return false;
}
static int BN_is_word(const BIGNUM *bn, BN_ULONG w) {
return GFp_BN_abs_is_word(bn, w) && (w == 0 || bn->neg == 0);
}
static bool TestHex2BN() {
ScopedBIGNUM bn;
int ret = HexToBIGNUM(&bn, "0");
if (ret != 1 || !GFp_BN_is_zero(bn.get()) || GFp_BN_is_negative(bn.get())) {
fprintf(stderr, "GFp_BN_hex2bn gave a bad result.\n");
return false;
}
ret = HexToBIGNUM(&bn, "256");
if (ret != 3 || !BN_is_word(bn.get(), 0x256) ||
GFp_BN_is_negative(bn.get())) {
fprintf(stderr, "GFp_BN_hex2bn gave a bad result.\n");
return false;
}
ret = HexToBIGNUM(&bn, "-42");
if (ret != 3 || !GFp_BN_abs_is_word(bn.get(), 0x42) ||
!GFp_BN_is_negative(bn.get())) {
fprintf(stderr, "GFp_BN_hex2bn gave a bad result.\n");
return false;
}
ret = HexToBIGNUM(&bn, "-0");
if (ret != 2 || !GFp_BN_is_zero(bn.get()) || GFp_BN_is_negative(bn.get())) {
fprintf(stderr, "GFp_BN_hex2bn gave a bad result.\n");
return false;
}
ret = HexToBIGNUM(&bn, "abctrailing garbage is ignored");
if (ret != 3 || !BN_is_word(bn.get(), 0xabc) ||
GFp_BN_is_negative(bn.get())) {
fprintf(stderr, "GFp_BN_hex2bn gave a bad result.\n");
return false;
}
return true;
}
static bool TestCmpWord() {
static const BN_ULONG kMaxWord = (BN_ULONG)-1;
ScopedBIGNUM one(GFp_BN_new());
ScopedBIGNUM r(GFp_BN_new());
if (!one ||
!GFp_BN_set_word(one.get(), 1) ||
!r) {
return false;
}
if (!GFp_BN_set_word(r.get(), 0)) {
return false;
}
if (GFp_BN_cmp_word(r.get(), 0) != 0 ||
GFp_BN_cmp_word(r.get(), 1) >= 0 ||
GFp_BN_cmp_word(r.get(), kMaxWord) >= 0) {
fprintf(stderr, "GFp_BN_cmp_word compared against 0 incorrectly.\n");
return false;
}
if (!GFp_BN_set_word(r.get(), 100)) {
return false;
}
if (GFp_BN_cmp_word(r.get(), 0) <= 0 ||
GFp_BN_cmp_word(r.get(), 99) <= 0 ||
GFp_BN_cmp_word(r.get(), 100) != 0 ||
GFp_BN_cmp_word(r.get(), 101) >= 0 ||
GFp_BN_cmp_word(r.get(), kMaxWord) >= 0) {
fprintf(stderr, "GFp_BN_cmp_word compared against 100 incorrectly.\n");
return false;
}
if (!GFp_BN_set_word(r.get(), kMaxWord)) {
return false;
}
if (GFp_BN_cmp_word(r.get(), 0) <= 0 ||
GFp_BN_cmp_word(r.get(), kMaxWord - 1) <= 0 ||
GFp_BN_cmp_word(r.get(), kMaxWord) != 0) {
fprintf(stderr, "GFp_BN_cmp_word compared against kMaxWord incorrectly.\n");
return false;
}
if (!GFp_BN_add(r.get(), r.get(), one.get())) {
return false;
}
if (GFp_BN_cmp_word(r.get(), 0) <= 0 ||
GFp_BN_cmp_word(r.get(), kMaxWord) <= 0) {
fprintf(stderr, "GFp_BN_cmp_word compared against kMaxWord + 1 incorrectly.\n");
return false;
}
return true;
}
extern "C" int bssl_bn_test_main() {
if (!TestHex2BN() ||
!TestCmpWord()) {
return 1;
}
return FileTestMain(RunTest, nullptr, "crypto/bn/bn_tests.txt");
}

File diff suppressed because it is too large Load Diff

View File

@ -1,237 +0,0 @@
// Copyright (c) 2016, Google Inc.
//
// 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 AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
package main
import (
"bufio"
"errors"
"fmt"
"io"
"math/big"
"os"
"strings"
)
type test struct {
LineNumber int
Type string
Values map[string]*big.Int
}
type testScanner struct {
scanner *bufio.Scanner
lineNo int
err error
test test
}
func newTestScanner(r io.Reader) *testScanner {
return &testScanner{scanner: bufio.NewScanner(r)}
}
func (s *testScanner) scanLine() bool {
if !s.scanner.Scan() {
return false
}
s.lineNo++
return true
}
func (s *testScanner) addAttribute(line string) (key string, ok bool) {
fields := strings.SplitN(line, "=", 2)
if len(fields) != 2 {
s.setError(errors.New("invalid syntax"))
return "", false
}
key = strings.TrimSpace(fields[0])
value := strings.TrimSpace(fields[1])
valueInt, ok := new(big.Int).SetString(value, 16)
if !ok {
s.setError(fmt.Errorf("could not parse %q", value))
return "", false
}
if _, dup := s.test.Values[key]; dup {
s.setError(fmt.Errorf("duplicate key %q", key))
return "", false
}
s.test.Values[key] = valueInt
return key, true
}
func (s *testScanner) Scan() bool {
s.test = test{
Values: make(map[string]*big.Int),
}
// Scan until the first attribute.
for {
if !s.scanLine() {
return false
}
if len(s.scanner.Text()) != 0 && s.scanner.Text()[0] != '#' {
break
}
}
var ok bool
s.test.Type, ok = s.addAttribute(s.scanner.Text())
if !ok {
return false
}
s.test.LineNumber = s.lineNo
for s.scanLine() {
if len(s.scanner.Text()) == 0 {
break
}
if s.scanner.Text()[0] == '#' {
continue
}
if _, ok := s.addAttribute(s.scanner.Text()); !ok {
return false
}
}
return s.scanner.Err() == nil
}
func (s *testScanner) Test() test {
return s.test
}
func (s *testScanner) Err() error {
if s.err != nil {
return s.err
}
return s.scanner.Err()
}
func (s *testScanner) setError(err error) {
s.err = fmt.Errorf("line %d: %s", s.lineNo, err)
}
func checkKeys(t test, keys ...string) bool {
var foundErrors bool
for _, k := range keys {
if _, ok := t.Values[k]; !ok {
fmt.Fprintf(os.Stderr, "Line %d: missing key %q.\n", t.LineNumber, k)
foundErrors = true
}
}
for k, _ := range t.Values {
var found bool
for _, k2 := range keys {
if k == k2 {
found = true
break
}
}
if !found {
fmt.Fprintf(os.Stderr, "Line %d: unexpected key %q.\n", t.LineNumber, k)
foundErrors = true
}
}
return !foundErrors
}
func checkResult(t test, expr, key string, r *big.Int) {
if t.Values[key].Cmp(r) != 0 {
fmt.Fprintf(os.Stderr, "Line %d: %s did not match %s.\n\tGot %s\n", t.LineNumber, expr, key, r.Text(16))
}
}
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: %s bn_tests.txt\n", os.Args[0])
os.Exit(1)
}
in, err := os.Open(os.Args[1])
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening %s: %s.\n", os.Args[0], err)
os.Exit(1)
}
defer in.Close()
scanner := newTestScanner(in)
for scanner.Scan() {
test := scanner.Test()
switch test.Type {
case "Sum":
if checkKeys(test, "A", "B", "Sum") {
r := new(big.Int).Add(test.Values["A"], test.Values["B"])
checkResult(test, "A + B", "Sum", r)
}
case "LShift1":
if checkKeys(test, "A", "LShift1") {
r := new(big.Int).Add(test.Values["A"], test.Values["A"])
checkResult(test, "A + A", "LShift1", r)
}
case "LShift":
if checkKeys(test, "A", "N", "LShift") {
r := new(big.Int).Lsh(test.Values["A"], uint(test.Values["N"].Uint64()))
checkResult(test, "A << N", "LShift", r)
}
case "RShift":
if checkKeys(test, "A", "N", "RShift") {
r := new(big.Int).Rsh(test.Values["A"], uint(test.Values["N"].Uint64()))
checkResult(test, "A >> N", "RShift", r)
}
case "Square":
if checkKeys(test, "A", "Square") {
r := new(big.Int).Mul(test.Values["A"], test.Values["A"])
checkResult(test, "A * A", "Square", r)
}
case "Product":
if checkKeys(test, "A", "B", "Product") {
r := new(big.Int).Mul(test.Values["A"], test.Values["B"])
checkResult(test, "A * B", "Product", r)
}
case "Quotient":
if checkKeys(test, "A", "B", "Quotient", "Remainder") {
q, r := new(big.Int).QuoRem(test.Values["A"], test.Values["B"], new(big.Int))
checkResult(test, "A / B", "Quotient", q)
checkResult(test, "A % B", "Remainder", r)
}
case "ModMul":
if checkKeys(test, "A", "B", "M", "ModMul") {
r := new(big.Int).Mul(test.Values["A"], test.Values["B"])
r = r.Mod(r, test.Values["M"])
checkResult(test, "A * B (mod M)", "ModMul", r)
}
case "ModExp":
if checkKeys(test, "A", "E", "M", "ModExp") {
r := new(big.Int).Exp(test.Values["A"], test.Values["E"], test.Values["M"])
checkResult(test, "A ^ E (mod M)", "ModExp", r)
}
case "ModInv":
if checkKeys(test, "A", "M", "ModInv") {
r := new(big.Int).ModInverse(test.Values["A"], test.Values["M"])
checkResult(test, "A ^ -1 (mod M)", "ModInv", r)
}
default:
fmt.Fprintf(os.Stderr, "Line %d: unknown test type %q.\n", test.LineNumber, test.Type)
}
}
if scanner.Err() != nil {
fmt.Fprintf(os.Stderr, "Error reading tests: %s.\n", scanner.Err())
}
}

View File

@ -56,360 +56,6 @@
#include <GFp/bn.h>
#include <assert.h>
#include <limits.h>
#include <GFp/err.h>
#include "internal.h"
#if !defined(BN_ULLONG)
/* GFp_bn_div_words divides a double-width |h|,|l| by |d| and returns the
* result, which must fit in a |BN_ULONG|. */
static BN_ULONG GFp_bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
BN_ULONG dh, dl, q, ret = 0, th, tl, t;
int i, count = 2;
if (d == 0) {
return BN_MASK2;
}
i = GFp_BN_num_bits_word(d);
assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
i = BN_BITS2 - i;
if (h >= d) {
h -= d;
}
if (i) {
d <<= i;
h = (h << i) | (l >> (BN_BITS2 - i));
l <<= i;
}
dh = (d & BN_MASK2h) >> BN_BITS4;
dl = (d & BN_MASK2l);
for (;;) {
if ((h >> BN_BITS4) == dh) {
q = BN_MASK2l;
} else {
q = h / dh;
}
th = q * dh;
tl = dl * q;
for (;;) {
t = h - th;
if ((t & BN_MASK2h) ||
((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) {
break;
}
q--;
th -= dh;
tl -= dl;
}
t = (tl >> BN_BITS4);
tl = (tl << BN_BITS4) & BN_MASK2h;
th += t;
if (l < tl) {
th++;
}
l -= tl;
if (h < th) {
h += d;
q--;
}
h -= th;
if (--count == 0) {
break;
}
ret = q << BN_BITS4;
h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
l = (l & BN_MASK2l) << BN_BITS4;
}
ret |= q;
return ret;
}
#endif /* !defined(BN_ULLONG) */
static inline void GFp_bn_div_rem_words(BN_ULONG *quotient_out,
BN_ULONG *rem_out, BN_ULONG n0,
BN_ULONG n1, BN_ULONG d0) {
/* GCC and Clang generate function calls to |__udivdi3| and |__umoddi3| when
* the |BN_ULLONG|-based C code is used.
*
* GCC bugs:
* * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14224
* * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721
* * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54183
* * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58897
* * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65668
*
* Clang bugs:
* * https://llvm.org/bugs/show_bug.cgi?id=6397
* * https://llvm.org/bugs/show_bug.cgi?id=12418
*
* These issues aren't specific to x86 and x86_64, so it might be worthwhile
* to add more assembly language implementations. */
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && defined(__GNUC__)
__asm__ volatile (
"divl %4"
: "=a"(*quotient_out), "=d"(*rem_out)
: "a"(n1), "d"(n0), "rm"(d0)
: "cc" );
#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
__asm__ volatile (
"divq %4"
: "=a"(*quotient_out), "=d"(*rem_out)
: "a"(n1), "d"(n0), "rm"(d0)
: "cc" );
#else
#if defined(BN_ULLONG)
BN_ULLONG n = (((BN_ULLONG)n0) << BN_BITS2) | n1;
*quotient_out = (BN_ULONG)(n / d0);
#else
*quotient_out = GFp_bn_div_words(n0, n1, d0);
#endif
*rem_out = n1 - (*quotient_out * d0);
#endif
}
/* GFp_BN_div computes dv := num / divisor, rounding towards zero, and sets
* up rm such that dv*divisor + rm = num holds.
*
* Thus:
* dv->neg == num->neg ^ divisor->neg (unless the result is zero)
* rm->neg == num->neg (unless the remainder is zero)
* If 'dv' or 'rm' is NULL, the respective value is not returned.
*
* This was specifically designed to contain fewer branches that may leak
* sensitive information; see "New Branch Prediction Vulnerabilities in OpenSSL
* and Necessary Software Countermeasures" by Onur Acıçmez, Shay Gueron, and
* Jean-Pierre Seifert. */
int GFp_BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
const BIGNUM *divisor) {
int norm_shift, i, loop;
BN_ULONG *resp, *wnump;
BN_ULONG d0, d1;
int num_n, div_n;
/* Invalid zero-padding would have particularly bad consequences
* so don't just rely on bn_check_top() here */
if ((num->top > 0 && num->d[num->top - 1] == 0) ||
(divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
OPENSSL_PUT_ERROR(BN, BN_R_NOT_INITIALIZED);
return 0;
}
if (GFp_BN_is_zero(divisor)) {
OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
return 0;
}
BIGNUM snum;
GFp_BN_init(&snum);
BIGNUM sdiv;
GFp_BN_init(&sdiv);
BIGNUM tmp;
GFp_BN_init(&tmp);
BIGNUM res_tmp;
GFp_BN_init(&res_tmp);
BIGNUM wnum; /* Weak; do not |GFp_BN_free|. */
BIGNUM *res; /* weak pointer */
if (dv == NULL) {
res = &res_tmp;
} else {
res = dv;
}
int ret = 0;
/* First we normalise the numbers */
norm_shift = BN_BITS2 - ((GFp_BN_num_bits(divisor)) % BN_BITS2);
if (!(GFp_BN_lshift(&sdiv, divisor, norm_shift))) {
goto err;
}
sdiv.neg = 0;
norm_shift += BN_BITS2;
if (!(GFp_BN_lshift(&snum, num, norm_shift))) {
goto err;
}
snum.neg = 0;
/* Since we don't want to have special-case logic for the case where snum is
* larger than sdiv, we pad snum with enough zeroes without changing its
* value. */
if (snum.top <= sdiv.top + 1) {
if (!GFp_bn_wexpand(&snum, sdiv.top + 2)) {
goto err;
}
for (i = snum.top; i < sdiv.top + 2; i++) {
snum.d[i] = 0;
}
snum.top = sdiv.top + 2;
} else {
if (!GFp_bn_wexpand(&snum, snum.top + 1)) {
goto err;
}
snum.d[snum.top] = 0;
snum.top++;
}
div_n = sdiv.top;
num_n = snum.top;
loop = num_n - div_n;
/* Lets setup a 'window' into snum
* This is the part that corresponds to the current
* 'area' being divided */
wnum.neg = 0;
wnum.d = &(snum.d[loop]);
wnum.top = div_n;
/* only needed when |GFp_BN_ucmp| messes up the values between top and max */
wnum.dmax = snum.dmax - loop; /* so we don't step out of bounds */
/* Get the top 2 words of sdiv */
/* div_n=sdiv.top; */
d0 = sdiv.d[div_n - 1];
d1 = (div_n == 1) ? 0 : sdiv.d[div_n - 2];
/* pointer to the 'top' of snum */
wnump = &(snum.d[num_n - 1]);
/* Setup to 'res' */
res->neg = (num->neg ^ divisor->neg);
if (!GFp_bn_wexpand(res, (loop + 1))) {
goto err;
}
res->top = loop - 1;
resp = &(res->d[loop - 1]);
/* space for temp */
if (!GFp_bn_wexpand(&tmp, (div_n + 1))) {
goto err;
}
/* if res->top == 0 then clear the neg value otherwise decrease
* the resp pointer */
if (res->top == 0) {
res->neg = 0;
} else {
resp--;
}
for (i = 0; i < loop - 1; i++, wnump--, resp--) {
BN_ULONG q, l0;
/* the first part of the loop uses the top two words of snum and sdiv to
* calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv */
BN_ULONG n0, n1, rem = 0;
n0 = wnump[0];
n1 = wnump[-1];
if (n0 == d0) {
q = BN_MASK2;
} else {
/* n0 < d0 */
GFp_bn_div_rem_words(&q, &rem, n0, n1, d0);
#ifdef BN_ULLONG
BN_ULLONG t2 = (BN_ULLONG)d1 * q;
for (;;) {
if (t2 <= ((((BN_ULLONG)rem) << BN_BITS2) | wnump[-2])) {
break;
}
q--;
rem += d0;
if (rem < d0) {
break; /* don't let rem overflow */
}
t2 -= d1;
}
#else /* !BN_ULLONG */
BN_ULONG t2l, t2h;
bn_umult_lohi(&t2l, &t2h, d1, q);
for (;;) {
if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) {
break;
}
q--;
rem += d0;
if (rem < d0) {
break; /* don't let rem overflow */
}
if (t2l < d1) {
t2h--;
}
t2l -= d1;
}
#endif /* !BN_ULLONG */
}
l0 = GFp_bn_mul_words(tmp.d, sdiv.d, div_n, q);
tmp.d[div_n] = l0;
wnum.d--;
/* ingore top values of the bignums just sub the two
* BN_ULONG arrays with GFp_bn_sub_words */
if (GFp_bn_sub_words(wnum.d, wnum.d, tmp.d, div_n + 1)) {
/* Note: As we have considered only the leading
* two BN_ULONGs in the calculation of q, sdiv * q
* might be greater than wnum (but then (q-1) * sdiv
* is less or equal than wnum)
*/
q--;
if (GFp_bn_add_words(wnum.d, wnum.d, sdiv.d, div_n)) {
/* we can't have an overflow here (assuming
* that q != 0, but if q == 0 then tmp is
* zero anyway) */
(*wnump)++;
}
}
/* store part of the result */
*resp = q;
}
GFp_bn_correct_top(&snum);
if (rm != NULL) {
/* Keep a copy of the neg flag in num because if rm==num |GFp_BN_rshift|
* will overwrite it. */
int neg = num->neg;
if (!GFp_BN_rshift(rm, &snum, norm_shift)) {
goto err;
}
if (!GFp_BN_is_zero(rm)) {
rm->neg = neg;
}
}
GFp_bn_correct_top(res);
ret = 1;
err:
GFp_BN_free(&tmp);
GFp_BN_free(&snum);
GFp_BN_free(&sdiv);
GFp_BN_free(&res_tmp);
return ret;
}
int GFp_BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d) {
if (!(GFp_BN_mod(r, m, d))) {
return 0;
}
if (!r->neg) {
return 1;
}
/* now -|d| < r < 0, so we have to set r := r + |d|. */
return (d->neg ? GFp_BN_sub : GFp_BN_add)(r, r, d);
}
int GFp_BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *m) {

View File

@ -1,290 +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.]
*/
/* ====================================================================
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
*
* 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 above 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 acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
#include <GFp/bn.h>
#include <GFp/err.h>
#include "internal.h"
int GFp_BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
const BIGNUM *n) {
*out_no_inverse = 0;
if (!GFp_BN_is_odd(n)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
if (GFp_BN_is_negative(a) || GFp_BN_cmp(a, n) >= 0) {
OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
return 0;
}
BIGNUM A;
GFp_BN_init(&A);
BIGNUM B;
GFp_BN_init(&B);
BIGNUM X;
GFp_BN_init(&X);
BIGNUM Y;
GFp_BN_init(&Y);
int ret = 0;
int sign;
BIGNUM *R = out;
GFp_BN_zero(&Y);
if (!GFp_BN_set_word(&X, 1) ||
!GFp_BN_copy(&B, a) ||
!GFp_BN_copy(&A, n)) {
goto err;
}
A.neg = 0;
sign = -1;
/* From B = a mod |n|, A = |n| it follows that
*
* 0 <= B < A,
* -sign*X*a == B (mod |n|),
* sign*Y*a == A (mod |n|).
*/
/* Binary inversion algorithm; requires odd modulus. This is faster than the
* general algorithm if the modulus is sufficiently small (about 400 .. 500
* bits on 32-bit systems, but much more on 64-bit systems) */
int shift;
while (!GFp_BN_is_zero(&B)) {
/* 0 < B < |n|,
* 0 < A <= |n|,
* (1) -sign*X*a == B (mod |n|),
* (2) sign*Y*a == A (mod |n|) */
/* Now divide B by the maximum possible power of two in the integers,
* and divide X by the same value mod |n|.
* When we're done, (1) still holds. */
shift = 0;
while (!GFp_BN_is_bit_set(&B, shift)) {
/* note that 0 < B */
shift++;
if (GFp_BN_is_odd(&X)) {
if (!GFp_BN_uadd(&X, &X, n)) {
goto err;
}
}
/* now X is even, so we can easily divide it by two */
if (!GFp_BN_rshift1(&X, &X)) {
goto err;
}
}
if (shift > 0) {
if (!GFp_BN_rshift(&B, &B, shift)) {
goto err;
}
}
/* Same for A and Y. Afterwards, (2) still holds. */
shift = 0;
while (!GFp_BN_is_bit_set(&A, shift)) {
/* note that 0 < A */
shift++;
if (GFp_BN_is_odd(&Y)) {
if (!GFp_BN_uadd(&Y, &Y, n)) {
goto err;
}
}
/* now Y is even */
if (!GFp_BN_rshift1(&Y, &Y)) {
goto err;
}
}
if (shift > 0) {
if (!GFp_BN_rshift(&A, &A, shift)) {
goto err;
}
}
/* We still have (1) and (2).
* Both A and B are odd.
* The following computations ensure that
*
* 0 <= B < |n|,
* 0 < A < |n|,
* (1) -sign*X*a == B (mod |n|),
* (2) sign*Y*a == A (mod |n|),
*
* and that either A or B is even in the next iteration. */
if (GFp_BN_ucmp(&B, &A) >= 0) {
/* -sign*(X + Y)*a == B - A (mod |n|) */
if (!GFp_BN_uadd(&X, &X, &Y)) {
goto err;
}
/* NB: we could use GFp_BN_mod_add_quick(X, X, Y, n), but that
* actually makes the algorithm slower */
if (!GFp_BN_usub(&B, &B, &A)) {
goto err;
}
} else {
/* sign*(X + Y)*a == A - B (mod |n|) */
if (!GFp_BN_uadd(&Y, &Y, &X)) {
goto err;
}
/* as above, GFp_BN_mod_add_quick(Y, Y, X, n) would slow things down */
if (!GFp_BN_usub(&A, &A, &B)) {
goto err;
}
}
}
if (!GFp_BN_is_one(&A)) {
*out_no_inverse = 1;
OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
goto err;
}
/* The while loop (Euclid's algorithm) ends when
* A == gcd(a,n);
* we have
* sign*Y*a == A (mod |n|),
* where Y is non-negative. */
if (sign < 0) {
if (!GFp_BN_sub(&Y, n, &Y)) {
goto err;
}
}
/* Now Y*a == A (mod |n|). */
/* Y*a == 1 (mod |n|) */
if (!Y.neg && GFp_BN_ucmp(&Y, n) < 0) {
if (!GFp_BN_copy(R, &Y)) {
goto err;
}
} else {
if (!GFp_BN_nnmod(R, &Y, n)) {
goto err;
}
}
ret = 1;
err:
GFp_BN_free(&A);
GFp_BN_free(&B);
GFp_BN_free(&X);
GFp_BN_free(&Y);
return ret;
}

View File

@ -56,146 +56,9 @@
#include <GFp/bn.h>
#include <string.h>
#include <GFp/err.h>
#include "internal.h"
int GFp_BN_lshift(BIGNUM *r, const BIGNUM *a, int n) {
int i, nw, lb, rb;
BN_ULONG *t, *f;
BN_ULONG l;
if (n < 0) {
OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
return 0;
}
r->neg = a->neg;
nw = n / BN_BITS2;
if (!GFp_bn_wexpand(r, a->top + nw + 1)) {
return 0;
}
lb = n % BN_BITS2;
rb = BN_BITS2 - lb;
f = a->d;
t = r->d;
t[a->top + nw] = 0;
if (lb == 0) {
for (i = a->top - 1; i >= 0; i--) {
t[nw + i] = f[i];
}
} else {
for (i = a->top - 1; i >= 0; i--) {
l = f[i];
t[nw + i + 1] |= (l >> rb) & BN_MASK2;
t[nw + i] = (l << lb) & BN_MASK2;
}
}
memset(t, 0, nw * sizeof(t[0]));
r->top = a->top + nw + 1;
GFp_bn_correct_top(r);
return 1;
}
int GFp_BN_rshift(BIGNUM *r, const BIGNUM *a, int n) {
int i, j, nw, lb, rb;
BN_ULONG *t, *f;
BN_ULONG l, tmp;
if (n < 0) {
OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
return 0;
}
nw = n / BN_BITS2;
rb = n % BN_BITS2;
lb = BN_BITS2 - rb;
if (nw >= a->top || a->top == 0) {
GFp_BN_zero(r);
return 1;
}
i = (GFp_BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2;
if (r != a) {
r->neg = a->neg;
if (!GFp_bn_wexpand(r, i)) {
return 0;
}
} else {
if (n == 0) {
return 1; /* or the copying loop will go berserk */
}
}
f = &(a->d[nw]);
t = r->d;
j = a->top - nw;
r->top = i;
if (rb == 0) {
for (i = j; i != 0; i--) {
*(t++) = *(f++);
}
} else {
l = *(f++);
for (i = j - 1; i != 0; i--) {
tmp = (l >> rb) & BN_MASK2;
l = *(f++);
*(t++) = (tmp | (l << lb)) & BN_MASK2;
}
l = (l >> rb) & BN_MASK2;
if (l != 0) {
*(t) = l;
}
}
if (r->top == 0) {
r->neg = 0;
}
return 1;
}
int GFp_BN_rshift1(BIGNUM *r, const BIGNUM *a) {
BN_ULONG *ap, *rp, t, c;
int i, j;
if (GFp_BN_is_zero(a)) {
GFp_BN_zero(r);
return 1;
}
i = a->top;
ap = a->d;
j = i - (ap[i - 1] == 1);
if (a != r) {
if (!GFp_bn_wexpand(r, j)) {
return 0;
}
r->neg = a->neg;
}
rp = r->d;
t = ap[--i];
c = (t & 1) ? BN_TBIT : 0;
if (t >>= 1) {
rp[i] = t;
}
while (i > 0) {
t = ap[--i];
rp[i] = ((t >> 1) & BN_MASK2) | c;
c = (t & 1) ? BN_TBIT : 0;
}
r->top = j;
if (r->top == 0) {
r->neg = 0;
}
return 1;
}
int GFp_BN_set_bit(BIGNUM *a, int n) {
int i, j, k;

View File

@ -1 +0,0 @@
*.h linguist-language=C++

View File

@ -1,181 +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 "bn_test_util.h"
#include "bn_test_lib.h"
#include <GFp/bn.h>
#include <GFp/err.h>
#include <ctype.h>
#include <limits.h>
#include "../bn/internal.h"
static int bn_expand(BIGNUM *bn, size_t bits) {
if (bits + BN_BITS2 - 1 < bits) {
OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
return 0;
}
return GFp_bn_wexpand(bn, (bits+BN_BITS2-1)/BN_BITS2);
}
/* decode_hex decodes |in_len| bytes of hex data from |in| and updates |bn|. */
static int decode_hex(BIGNUM *bn, const char *in, int in_len) {
if (in_len > INT_MAX/4) {
OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
return 0;
}
/* |in_len| is the number of hex digits. */
if (!bn_expand(bn, in_len * 4)) {
return 0;
}
int i = 0;
while (in_len > 0) {
/* Decode one |BN_ULONG| at a time. */
int todo = BN_BYTES * 2;
if (todo > in_len) {
todo = in_len;
}
BN_ULONG word = 0;
int j;
for (j = todo; j > 0; j--) {
char c = in[in_len - j];
BN_ULONG hex;
if (c >= '0' && c <= '9') {
hex = c - '0';
} else if (c >= 'a' && c <= 'f') {
hex = c - 'a' + 10;
} else if (c >= 'A' && c <= 'F') {
hex = c - 'A' + 10;
} else {
hex = 0;
/* This shouldn't happen. The caller checks |isxdigit|. */
assert(0);
}
word = (word << 4) | hex;
}
bn->d[i++] = word;
in_len -= todo;
}
assert(i <= bn->dmax);
bn->top = i;
return 1;
}
typedef int (*decode_func) (BIGNUM *bn, const char *in, int in_len);
typedef int (*char_test_func) (int c);
static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_func want_char) {
BIGNUM *ret = NULL;
int neg = 0, i;
int num;
if (in == NULL || *in == 0) {
return 0;
}
if (*in == '-') {
neg = 1;
in++;
}
for (i = 0; want_char((unsigned char)in[i]) && i + neg < INT_MAX; i++) {}
num = i + neg;
if (outp == NULL) {
return num;
}
/* in is the start of the hex digits, and it is 'i' long */
if (*outp == NULL) {
ret = GFp_BN_new();
if (ret == NULL) {
return 0;
}
} else {
ret = *outp;
GFp_BN_zero(ret);
}
if (!decode(ret, in, i)) {
goto err;
}
GFp_bn_correct_top(ret);
if (!GFp_BN_is_zero(ret)) {
ret->neg = neg;
}
*outp = ret;
return num;
err:
if (*outp == NULL) {
GFp_BN_free(ret);
}
return 0;
}
int GFp_BN_hex2bn(BIGNUM **outp, const char *in) {
return bn_x2bn(outp, in, decode_hex, isxdigit);
}

View File

@ -1,151 +0,0 @@
/* Copyright (C) 1995-1997 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.]
*/
/* ====================================================================
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
*
* 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 above 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 acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the Eric Young open source
* license provided above.
*
* The binary polynomial arithmetic software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
* Laboratories. */
#ifndef OPENSSL_HEADER_BN_TEST_LIB_H
#define OPENSSL_HEADER_BN_TEST_LIB_H
#include <GFp/base.h>
#include <GFp/bn.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* BIGNUM functions that used to be in libcrypto, but which were removed
* because no library code uses them anymore. They are retained here so that
* bn_test.cc can use them to test functions that still remain in libcrypto. */
/* Basic functions. */
/* GFp_BN_new creates a new, allocated BIGNUM and initialises it. */
BIGNUM *GFp_BN_new(void);
/* GFp_BN_num_bytes returns the minimum number of bytes needed to represent the
* absolute value of |bn|. */
OPENSSL_EXPORT unsigned GFp_BN_num_bytes(const BIGNUM *bn);
#if defined(__cplusplus)
}
#endif
#endif /* OPENSSL_HEADER_BN_TEST_LIB_H */

View File

@ -1,82 +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 <string.h>
#include <GFp/err.h>
#include <GFp/mem.h>
#include "../test/bn_test_lib.h"
BIGNUM *GFp_BN_new(void) {
BIGNUM *bn = OPENSSL_malloc(sizeof(BIGNUM));
if (bn == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(bn, 0, sizeof(BIGNUM));
bn->flags = BN_FLG_MALLOCED;
return bn;
}
unsigned GFp_BN_num_bytes(const BIGNUM *bn) {
return (GFp_BN_num_bits(bn) + 7) / 8;
}

View File

@ -1,148 +0,0 @@
/* Copyright (C) 1995-1997 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.]
*/
/* ====================================================================
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
*
* 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 above 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 acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the Eric Young open source
* license provided above.
*
* The binary polynomial arithmetic software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
* Laboratories. */
#ifndef OPENSSL_HEADER_CRYPTO_TEST_BN_TEST_UTIL_H
#define OPENSSL_HEADER_CRYPTO_TEST_BN_TEST_UTIL_H
#include <GFp/bn.h>
#include <stdio.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* BN_hex2bn parses the leading hex number from |in|, which may be proceeded by
* a '-' to indicate a negative number and may contain trailing, non-hex data.
* If |outp| is not NULL, it constructs a BIGNUM equal to the hex number and
* stores it in |*outp|. If |*outp| is NULL then it allocates a new BIGNUM and
* updates |*outp|. It returns the number of bytes of |in| processed or zero on
* error. */
OPENSSL_EXPORT int GFp_BN_hex2bn(BIGNUM **outp, const char *in);
#if defined(__cplusplus)
}
#endif
#endif /* OPENSSL_HEADER_CRYPTO_TEST_BN_TEST_UTIL_H */

View File

@ -1,199 +0,0 @@
/* Copyright (c) 2015, Google Inc.
*
* 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 AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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. */
#if defined(_MSC_VER)
#pragma warning(disable: 4996) // This function or variable may be unsafe.
#endif
#include "file_test.h"
#include <memory>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <GFp/err.h>
FileTest::FileTest(const char *path)
: file_(nullptr),
line_(0),
start_line_(0)
{
file_ = fopen(path, "r");
if (file_ == nullptr) {
fprintf(stderr, "Could not open file %s: %s.\n", path, strerror(errno));
}
}
FileTest::~FileTest() {
if (file_ != nullptr) {
fclose(file_);
}
}
// FindDelimiter returns a pointer to the first '=' or ':' in |str| or nullptr
// if there is none.
static const char *FindDelimiter(const char *str) {
while (*str) {
if (*str == ':' || *str == '=') {
return str;
}
str++;
}
return nullptr;
}
// StripSpace returns a string containing up to |len| characters from |str| with
// leading and trailing whitespace removed.
static std::string StripSpace(const char *str, size_t len) {
// Remove leading space.
while (len > 0 && isspace(*str)) {
str++;
len--;
}
while (len > 0 && isspace(str[len-1])) {
len--;
}
return std::string(str, len);
}
FileTest::ReadResult FileTest::ReadNext() {
// If the previous test had unused attributes, it is an error.
if (!unused_attributes_.empty()) {
for (const std::string &key : unused_attributes_) {
PrintLine("Unused attribute: ", key.c_str());
}
return kReadError;
}
ClearTest();
static const size_t kBufLen = 64 + 8192*2;
std::unique_ptr<char[]> buf(new char[kBufLen]);
while (true) {
// Read the next line.
if (fgets(buf.get(), kBufLen, file_) == nullptr) {
if (feof(file_)) {
// EOF is a valid terminator for a test.
return start_line_ > 0 ? kReadSuccess : kReadEOF;
}
fprintf(stderr, "Error reading from input.\n");
return kReadError;
}
line_++;
size_t len = strlen(buf.get());
// Check for truncation.
if (len > 0 && buf[len - 1] != '\n' && !feof(file_)) {
fprintf(stderr, "Line %u too long.\n", line_);
return kReadError;
}
if (buf[0] == '\n' || buf[0] == '\0') {
// Empty lines delimit tests.
if (start_line_ > 0) {
return kReadSuccess;
}
} else if (buf[0] != '#') { // Comment lines are ignored.
// Parse the line as an attribute.
const char *delimiter = FindDelimiter(buf.get());
if (delimiter == nullptr) {
fprintf(stderr, "Line %u: Could not parse attribute.\n", line_);
return kReadError;
}
std::string key = StripSpace(buf.get(),
static_cast<size_t>(delimiter - buf.get()));
std::string value = StripSpace(
delimiter + 1, static_cast<size_t>(buf.get() + len - delimiter - 1));
unused_attributes_.insert(key);
attributes_[key] = value;
if (start_line_ == 0) {
// This is the start of a test.
type_ = key;
parameter_ = value;
start_line_ = line_;
}
}
}
}
void FileTest::PrintLine(const char *p1, const char *p2, const char *p3) {
fprintf(stderr, "Line %u: %s%s%s\n", start_line_, p1, p2, p3);
}
const std::string &FileTest::GetType() {
OnKeyUsed(type_);
return type_;
}
bool FileTest::GetAttribute(std::string *out_value, const std::string &key) {
OnKeyUsed(key);
auto iter = attributes_.find(key);
if (iter == attributes_.end()) {
PrintLine("Missing attribute '", key.c_str(), "'.");
return false;
}
*out_value = iter->second;
return true;
}
void FileTest::ClearTest() {
start_line_ = 0;
type_.clear();
parameter_.clear();
attributes_.clear();
unused_attributes_.clear();
}
void FileTest::OnKeyUsed(const std::string &key) {
unused_attributes_.erase(key);
}
int FileTestMain(bool (*run_test)(FileTest *t, void *arg), void *arg,
const char *path) {
FileTest t(path);
if (!t.is_open()) {
return 1;
}
bool failed = false;
while (true) {
FileTest::ReadResult ret = t.ReadNext();
if (ret == FileTest::kReadError) {
return 1;
} else if (ret == FileTest::kReadEOF) {
break;
}
bool result = run_test(&t, arg);
if (!result) {
// In case the test itself doesn't print output, print something so the
// line number is reported.
t.PrintLine("Test failed");
failed = true;
continue;
}
}
if (failed) {
return 1;
}
return 0;
}

View File

@ -1,138 +0,0 @@
/* Copyright (c) 2015, Google Inc.
*
* 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 AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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. */
#ifndef OPENSSL_HEADER_CRYPTO_TEST_FILE_TEST_H
#define OPENSSL_HEADER_CRYPTO_TEST_FILE_TEST_H
#include <stdint.h>
#include <stdio.h>
#if defined(_MSC_VER)
#pragma warning(push)
#endif
#include <string>
#include <map>
#include <set>
#include <vector>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
// File-based test framework.
//
// This module provides a file-based test framework. The file format is based on
// that of OpenSSL upstream's evp_test and BoringSSL's aead_test. Each input
// file is a sequence of attributes and blank lines.
//
// Each attribute has the form:
//
// Name = Value
//
// Either '=' or ':' may be used to delimit the name from the value. Both the
// name and value have leading and trailing spaces stripped.
//
// Lines beginning with # are ignored.
//
// A test is a sequence of one or more attributes followed by a blank line.
// Blank lines are otherwise ignored. For tests that process multiple kinds of
// test cases, the first attribute is parsed out as the test's type and
// parameter. Otherwise, attributes are unordered. The first attribute is also
// included in the set of attributes, so tests which do not dispatch may ignore
// this mechanism.
//
// Functions in this module freely output to |stderr| on failure. Tests should
// also do so, and it is recommended they include the corresponding test's line
// number in any output. |PrintLine| does this automatically.
//
// Each attribute in a test must be consumed. When a test completes, if any
// attributes haven't been processed, the framework reports an error.
class FileTest {
public:
explicit FileTest(const char *path);
~FileTest();
// is_open returns true if the file was successfully opened.
bool is_open() const { return file_ != nullptr; }
enum ReadResult {
kReadSuccess,
kReadEOF,
kReadError
};
// ReadNext reads the next test from the file. It returns |kReadSuccess| if
// successfully reading a test and |kReadEOF| at the end of the file. On
// error or if the previous test had unconsumed attributes, it returns
// |kReadError|.
ReadResult ReadNext();
// PrintLine is a simple printer that prints strings the concatenation of
// |*p1|, |*p2|, and |*p3|, prepending the line number and appending a
// trailing newline.
void PrintLine(const char *p1, const char *p2 = "", const char *p3 = "");
unsigned start_line() const { return start_line_; }
// GetType returns the name of the first attribute of the current test.
const std::string &GetType();
// GetAttribute looks up the attribute with key |key|. It sets |*out_value| to
// the value and returns true if it exists and returns false with an error to
// |stderr| otherwise.
bool GetAttribute(std::string *out_value, const std::string &key);
private:
void ClearTest();
void OnKeyUsed(const std::string &key);
FILE *file_;
// line_ is the number of lines read.
unsigned line_;
// start_line_ is the line number of the first attribute of the test.
unsigned start_line_;
// type_ is the name of the first attribute of the test.
std::string type_;
// parameter_ is the value of the first attribute.
std::string parameter_;
// attributes_ contains all attributes in the test, including the first.
std::map<std::string, std::string> attributes_;
// unused_attributes_ is the set of attributes that have been queried.
std::set<std::string> unused_attributes_;
FileTest(const FileTest&) = delete;
FileTest &operator=(const FileTest&) = delete;
};
// FileTestMain runs a file-based test out of |path| and returns an exit code
// suitable to return out of |main|. |run_test| should return true on pass and
// false on failure. FileTestMain also implements common handling of the 'Error'
// attribute. A test with that attribute is expected to fail. The value of the
// attribute is the reason string of the expected OpenSSL error code.
//
// Tests are guaranteed to run serially and may affect global state if need be.
// It is legal to use "tests" which, for example, import a private key into a
// list of keys. This may be used to initialize a shared set of keys for many
// tests. However, if one test fails, the framework will continue to run
// subsequent tests.
int FileTestMain(bool (*run_test)(FileTest *t, void *arg), void *arg,
const char *path);
#endif /* OPENSSL_HEADER_CRYPTO_TEST_FILE_TEST_H */

View File

@ -1,49 +0,0 @@
/* Copyright (c) 2015, Google Inc.
*
* 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 AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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. */
#ifndef OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
#define OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
// Avoid "C4548: expression before comma has no effect; expected expression
// with side-effect." in malloc.h in Visual Studio 2015 Update 1 in debug mode.
#if defined(_MSC_VER) && defined(_DEBUG)
#pragma warning(push)
#pragma warning(disable: 4548)
#endif
#include <memory>
#if defined(_MSC_VER) && defined(_DEBUG)
#pragma warning(pop)
#endif
#include <GFp/bn.h>
template<typename T, void (*func)(T*)>
struct OpenSSLDeleter {
void operator()(T *obj) {
func(obj);
}
};
// XXX: GCC 4.6 doesn't support this use of `using` yet:
// template<typename T, void (*func)(T*)>
// using ScopedOpenSSLType = std::unique_ptr<T, OpenSSLDeleter<T, func>>;
// TODO: When we drop GCC 4.6 support, revert back to what BoringSSL is doing.
#define SCOPED_OPENSSL_TYPE(Name, T, func) \
typedef std::unique_ptr<T, OpenSSLDeleter<T, func>> Name
SCOPED_OPENSSL_TYPE(ScopedBIGNUM, BIGNUM, GFp_BN_free);
#endif // OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H

View File

@ -237,14 +237,6 @@ OPENSSL_EXPORT int GFp_BN_usub_unchecked(BIGNUM *r, const BIGNUM *a,
* 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);
/* GFp_BN_div divides |numerator| by |divisor| and places the result in
* |quotient| and the remainder in |rem|. Either of |quotient| or |rem| may be
* NULL, in which case the respective value is not returned. The result is
* rounded towards zero; thus if |numerator| is negative, the remainder will be
* zero or negative. It returns one on success or zero on error. */
OPENSSL_EXPORT int GFp_BN_div(BIGNUM *quotient, BIGNUM *rem,
const BIGNUM *numerator, const BIGNUM *divisor);
/* Comparison functions */
@ -277,19 +269,6 @@ OPENSSL_EXPORT int GFp_BN_is_odd(const BIGNUM *bn);
/* Bitwise operations. */
/* GFp_BN_lshift sets |r| equal to |a| << n. The |a| and |r| arguments may be
* the same |BIGNUM|. It returns one on success and zero on allocation failure.
*/
OPENSSL_EXPORT int GFp_BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
/* GFp_BN_rshift sets |r| equal to |a| >> n, where |r| and |a| may be the same
* pointer. It returns one on success and zero on allocation failure. */
OPENSSL_EXPORT int GFp_BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
/* GFp_BN_rshift1 sets |r| equal to |a| >> 1, where |r| and |a| may be the same
* pointer. It returns one on success and zero on allocation failure. */
OPENSSL_EXPORT int GFp_BN_rshift1(BIGNUM *r, const BIGNUM *a);
/* GFp_BN_set_bit sets the |n|th, least-significant bit in |a|. For example, if
* |a| is 2 then setting bit zero will make it 3. It returns one on success or
* zero on allocation failure. */
@ -302,17 +281,6 @@ OPENSSL_EXPORT int GFp_BN_is_bit_set(const BIGNUM *a, int n);
/* Modulo arithmetic. */
/* GFp_BN_mod is a helper macro that calls |GFp_BN_div| and discards the
* quotient. */
#define GFp_BN_mod(rem, numerator, divisor) \
GFp_BN_div(NULL, (rem), (numerator), (divisor))
/* GFp_BN_nnmod is a non-negative modulo function. It acts like |GFp_BN_mod|,
* but 0 <= |rem| < |divisor| is always true. It returns one on success and
* zero on error. */
OPENSSL_EXPORT int GFp_BN_nnmod(BIGNUM *rem, const BIGNUM *numerator,
const BIGNUM *divisor);
/* GFp_BN_mod_add_quick acts like |BN_mod_add| but requires that |a| and |b| be
* non-negative and less than |m|. */
OPENSSL_EXPORT int GFp_BN_mod_add_quick(BIGNUM *r, const BIGNUM *a,

View File

@ -188,10 +188,5 @@ mod private {
#[cfg(test)]
mod tests {
#[cfg(all(feature = "use_heap",
feature = "bn_tests",
not(any(target_os = "macos", target_os = "ios", target_env = "musl"))))]
bssl_test!(test_bn, bssl_bn_test_main);
bssl_test!(test_constant_time, bssl_constant_time_test_main);
}

View File

@ -15,8 +15,6 @@
//! Generation of random field elements, in particular field elements in GFn
//! where *n* is an RSA public modulus.
//!
//! This is also used for some randomized tests in bn_tests.cc.
use {c, core, rand, error, rsa};
use limb::*;