Remove num/gmp support

The whole "num" API and its libgmp-based implementation are now unused. Remove them.
This commit is contained in:
Pieter Wuille 2020-10-11 16:04:58 -07:00
parent 20448b8d09
commit 1f233b3fa0
21 changed files with 6 additions and 815 deletions

View File

@ -1,6 +1,5 @@
env:
WIDEMUL: auto
BIGNUM: auto
STATICPRECOMPUTATION: yes
ECMULTGENPRECISION: auto
ASM: no
@ -59,9 +58,8 @@ task:
- env: {WIDEMUL: int128, RECOVERY: yes, EXPERIMENTAL: yes, SCHNORRSIG: yes}
- env: {WIDEMUL: int128, ECDH: yes, EXPERIMENTAL: yes, SCHNORRSIG: yes}
- env: {WIDEMUL: int128, ASM: x86_64}
- env: {BIGNUM: no}
- env: {BIGNUM: no, RECOVERY: yes, EXPERIMENTAL: yes, SCHNORRSIG: yes}
- env: {BIGNUM: no, STATICPRECOMPUTATION: no}
- env: { RECOVERY: yes, EXPERIMENTAL: yes, SCHNORRSIG: yes}
- env: { STATICPRECOMPUTATION: no}
- env: {BUILD: distcheck, WITH_VALGRIND: no, CTIMETEST: no, BENCH: no}
- env: {CPPFLAGS: -DDETERMINISTIC}
- env: {CFLAGS: -O0, CTIMETEST: no}
@ -69,7 +67,6 @@ task:
CFLAGS: "-fsanitize=undefined -fno-omit-frame-pointer"
LDFLAGS: "-fsanitize=undefined -fno-omit-frame-pointer"
UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1"
BIGNUM: no
ASM: x86_64
ECDH: yes
RECOVERY: yes
@ -80,7 +77,6 @@ task:
- env: { ECMULTGENPRECISION: 8 }
- env:
RUN_VALGRIND: yes
BIGNUM: no
ASM: x86_64
ECDH: yes
RECOVERY: yes
@ -115,12 +111,6 @@ task:
CC: i686-linux-gnu-gcc
- env:
CC: clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include
matrix:
- env:
BIGNUM: gmp
- env:
BIGNUM: no
<< : *MERGE_BASE
test_script:
- ./ci/cirrus.sh
<< : *CAT_LOGS
@ -178,7 +168,7 @@ task:
# If we haven't restored from cached (and just run brew install), this is a no-op.
- brew link valgrind
brew_script:
- brew install automake libtool gmp gcc@9
- brew install automake libtool gcc@9
<< : *MERGE_BASE
test_script:
- ./ci/cirrus.sh
@ -195,7 +185,6 @@ task:
HOST: s390x-linux-gnu
BUILD:
WITH_VALGRIND: no
BIGNUM: no
ECDH: yes
RECOVERY: yes
EXPERIMENTAL: yes

View File

@ -14,8 +14,6 @@ noinst_HEADERS += src/scalar_8x32_impl.h
noinst_HEADERS += src/scalar_low_impl.h
noinst_HEADERS += src/group.h
noinst_HEADERS += src/group_impl.h
noinst_HEADERS += src/num_gmp.h
noinst_HEADERS += src/num_gmp_impl.h
noinst_HEADERS += src/ecdsa.h
noinst_HEADERS += src/ecdsa_impl.h
noinst_HEADERS += src/eckey.h
@ -26,8 +24,6 @@ noinst_HEADERS += src/ecmult_const.h
noinst_HEADERS += src/ecmult_const_impl.h
noinst_HEADERS += src/ecmult_gen.h
noinst_HEADERS += src/ecmult_gen_impl.h
noinst_HEADERS += src/num.h
noinst_HEADERS += src/num_impl.h
noinst_HEADERS += src/field_10x26.h
noinst_HEADERS += src/field_10x26_impl.h
noinst_HEADERS += src/field_5x52.h

View File

@ -75,19 +75,6 @@ if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then
fi
])
dnl
AC_DEFUN([SECP_GMP_CHECK],[
if test x"$has_gmp" != x"yes"; then
CPPFLAGS_TEMP="$CPPFLAGS"
CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS"
LIBS_TEMP="$LIBS"
LIBS="$GMP_LIBS $LIBS"
AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS="$GMP_LIBS -lgmp"; AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])])])
CPPFLAGS="$CPPFLAGS_TEMP"
LIBS="$LIBS_TEMP"
fi
])
AC_DEFUN([SECP_VALGRIND_CHECK],[
if test x"$has_valgrind" != x"yes"; then
CPPFLAGS_TEMP="$CPPFLAGS"

View File

@ -14,7 +14,7 @@ valgrind --version || true
./configure \
--enable-experimental="$EXPERIMENTAL" \
--with-test-override-wide-multiply="$WIDEMUL" --with-bignum="$BIGNUM" --with-asm="$ASM" \
--with-test-override-wide-multiply="$WIDEMUL" --with-asm="$ASM" \
--enable-ecmult-static-precomputation="$STATICPRECOMPUTATION" --with-ecmult-gen-precision="$ECMULTGENPRECISION" \
--enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \
--enable-module-schnorrsig="$SCHNORRSIG" \

View File

@ -8,6 +8,6 @@ RUN apt-get update
RUN apt-get install --no-install-recommends --no-upgrade -y \
git ca-certificates \
make automake libtool pkg-config dpkg-dev valgrind qemu-user \
gcc clang libc6-dbg libgmp-dev \
gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libgmp-dev:i386 \
gcc clang libc6-dbg \
gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 \
gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x

View File

@ -48,17 +48,12 @@ case $host_os in
# in expected paths because they may conflict with system files. Ask
# Homebrew where each one is located, then adjust paths accordingly.
openssl_prefix=`$BREW --prefix openssl 2>/dev/null`
gmp_prefix=`$BREW --prefix gmp 2>/dev/null`
valgrind_prefix=`$BREW --prefix valgrind 2>/dev/null`
if test x$openssl_prefix != x; then
PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
export PKG_CONFIG_PATH
CRYPTO_CPPFLAGS="-I$openssl_prefix/include"
fi
if test x$gmp_prefix != x; then
GMP_CPPFLAGS="-I$gmp_prefix/include"
GMP_LIBS="-L$gmp_prefix/lib"
fi
if test x$valgrind_prefix != x; then
VALGRIND_CPPFLAGS="-I$valgrind_prefix/include"
fi
@ -164,9 +159,6 @@ AC_ARG_ENABLE(external_default_callbacks,
# Legal values are int64 (for [u]int64_t), int128 (for [unsigned] __int128), and auto (the default).
AC_ARG_WITH([test-override-wide-multiply], [] ,[set_widemul=$withval], [set_widemul=auto])
AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto],
[bignum implementation to use [default=auto]])],[req_bignum=$withval], [req_bignum=auto])
AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto],
[assembly optimizations to use (experimental: arm) [default=auto]])],[req_asm=$withval], [req_asm=auto])
@ -245,32 +237,6 @@ else
esac
fi
if test x"$req_bignum" = x"auto"; then
SECP_GMP_CHECK
if test x"$has_gmp" = x"yes"; then
set_bignum=gmp
fi
if test x"$set_bignum" = x; then
set_bignum=no
fi
else
set_bignum=$req_bignum
case $set_bignum in
gmp)
SECP_GMP_CHECK
if test x"$has_gmp" != x"yes"; then
AC_MSG_ERROR([gmp bignum explicitly requested but libgmp not available])
fi
;;
no)
;;
*)
AC_MSG_ERROR([invalid bignum implementation selection])
;;
esac
fi
# Select assembly optimization
use_external_asm=no
@ -308,24 +274,6 @@ auto)
;;
esac
# Select bignum implementation
case $set_bignum in
gmp)
AC_DEFINE(HAVE_LIBGMP, 1, [Define this symbol if libgmp is installed])
AC_DEFINE(USE_NUM_GMP, 1, [Define this symbol to use the gmp implementation for num])
AC_DEFINE(USE_FIELD_INV_NUM, 1, [Define this symbol to use the num-based field inverse implementation])
AC_DEFINE(USE_SCALAR_INV_NUM, 1, [Define this symbol to use the num-based scalar inverse implementation])
;;
no)
AC_DEFINE(USE_NUM_NONE, 1, [Define this symbol to use no num implementation])
AC_DEFINE(USE_FIELD_INV_BUILTIN, 1, [Define this symbol to use the native field inverse implementation])
AC_DEFINE(USE_SCALAR_INV_BUILTIN, 1, [Define this symbol to use the native scalar inverse implementation])
;;
*)
AC_MSG_ERROR([invalid bignum implementation])
;;
esac
# Set ecmult window size
if test x"$req_ecmult_window" = x"auto"; then
set_ecmult_window=15
@ -390,11 +338,6 @@ else
enable_openssl_tests=no
fi
if test x"$set_bignum" = x"gmp"; then
SECP_LIBS="$SECP_LIBS $GMP_LIBS"
SECP_INCLUDES="$SECP_INCLUDES $GMP_CPPFLAGS"
fi
if test x"$enable_valgrind" = x"yes"; then
SECP_INCLUDES="$SECP_INCLUDES $VALGRIND_CPPFLAGS"
fi
@ -571,7 +514,6 @@ echo " module extrakeys = $enable_module_extrakeys"
echo " module schnorrsig = $enable_module_schnorrsig"
echo
echo " asm = $set_asm"
echo " bignum = $set_bignum"
echo " ecmult window size = $set_ecmult_window"
echo " ecmult gen prec. bits = $set_ecmult_gen_precision"
# Hide test-only options unless they're used.

View File

@ -13,19 +13,10 @@
#undef USE_ECMULT_STATIC_PRECOMPUTATION
#undef USE_EXTERNAL_ASM
#undef USE_EXTERNAL_DEFAULT_CALLBACKS
#undef USE_FIELD_INV_BUILTIN
#undef USE_FIELD_INV_NUM
#undef USE_NUM_GMP
#undef USE_NUM_NONE
#undef USE_SCALAR_INV_BUILTIN
#undef USE_SCALAR_INV_NUM
#undef USE_FORCE_WIDEMUL_INT64
#undef USE_FORCE_WIDEMUL_INT128
#undef ECMULT_WINDOW_SIZE
#define USE_NUM_NONE 1
#define USE_FIELD_INV_BUILTIN 1
#define USE_SCALAR_INV_BUILTIN 1
#define USE_WIDEMUL_64 1
#define ECMULT_WINDOW_SIZE 15

View File

@ -9,7 +9,6 @@
#include "util.h"
#include "hash_impl.h"
#include "num_impl.h"
#include "field_impl.h"
#include "group_impl.h"
#include "scalar_impl.h"

View File

@ -10,7 +10,6 @@
#include "assumptions.h"
#include "util.h"
#include "hash_impl.h"
#include "num_impl.h"
#include "field_impl.h"
#include "group_impl.h"
#include "scalar_impl.h"

View File

@ -7,7 +7,6 @@
#ifndef SECP256K1_ECMULT_H
#define SECP256K1_ECMULT_H
#include "num.h"
#include "group.h"
#include "scalar.h"
#include "scratch.h"

View File

@ -12,7 +12,6 @@
#endif
#include "util.h"
#include "num.h"
#if defined(SECP256K1_WIDEMUL_INT128)
#include "field_5x52_impl.h"

View File

@ -7,7 +7,6 @@
#ifndef SECP256K1_GROUP_H
#define SECP256K1_GROUP_H
#include "num.h"
#include "field.h"
/** A group element of the secp256k1 curve, in affine coordinates. */

View File

@ -7,7 +7,6 @@
#ifndef SECP256K1_GROUP_IMPL_H
#define SECP256K1_GROUP_IMPL_H
#include "num.h"
#include "field.h"
#include "group.h"

View File

@ -1,74 +0,0 @@
/***********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_NUM_H
#define SECP256K1_NUM_H
#ifndef USE_NUM_NONE
#if defined HAVE_CONFIG_H
#include "libsecp256k1-config.h"
#endif
#if defined(USE_NUM_GMP)
#include "num_gmp.h"
#else
#error "Please select num implementation"
#endif
/** Copy a number. */
static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a);
/** Convert a number's absolute value to a binary big-endian string.
* There must be enough place. */
static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a);
/** Set a number to the value of a binary big-endian string. */
static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen);
/** Compute a modular inverse. The input must be less than the modulus. */
static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m);
/** Compute the jacobi symbol (a|b). b must be positive and odd. */
static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b);
/** Compare the absolute value of two numbers. */
static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b);
/** Test whether two number are equal (including sign). */
static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b);
/** Add two (signed) numbers. */
static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b);
/** Subtract two (signed) numbers. */
static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b);
/** Multiply two (signed) numbers. */
static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b);
/** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1,
even if r was negative. */
static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m);
/** Right-shift the passed number by bits bits. */
static void secp256k1_num_shift(secp256k1_num *r, int bits);
/** Check whether a number is zero. */
static int secp256k1_num_is_zero(const secp256k1_num *a);
/** Check whether a number is one. */
static int secp256k1_num_is_one(const secp256k1_num *a);
/** Check whether a number is strictly negative. */
static int secp256k1_num_is_neg(const secp256k1_num *a);
/** Change a number's sign. */
static void secp256k1_num_negate(secp256k1_num *r);
#endif
#endif /* SECP256K1_NUM_H */

View File

@ -1,20 +0,0 @@
/***********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_NUM_REPR_H
#define SECP256K1_NUM_REPR_H
#include <gmp.h>
#define NUM_LIMBS ((256+GMP_NUMB_BITS-1)/GMP_NUMB_BITS)
typedef struct {
mp_limb_t data[2*NUM_LIMBS];
int neg;
int limbs;
} secp256k1_num;
#endif /* SECP256K1_NUM_REPR_H */

View File

@ -1,288 +0,0 @@
/***********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_NUM_REPR_IMPL_H
#define SECP256K1_NUM_REPR_IMPL_H
#include <string.h>
#include <stdlib.h>
#include <gmp.h>
#include "util.h"
#include "num.h"
#ifdef VERIFY
static void secp256k1_num_sanity(const secp256k1_num *a) {
VERIFY_CHECK(a->limbs == 1 || (a->limbs > 1 && a->data[a->limbs-1] != 0));
}
#else
#define secp256k1_num_sanity(a) do { } while(0)
#endif
static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a) {
*r = *a;
}
static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a) {
unsigned char tmp[65];
int len = 0;
int shift = 0;
if (a->limbs>1 || a->data[0] != 0) {
len = mpn_get_str(tmp, 256, (mp_limb_t*)a->data, a->limbs);
}
while (shift < len && tmp[shift] == 0) shift++;
VERIFY_CHECK(len-shift <= (int)rlen);
memset(r, 0, rlen - len + shift);
if (len > shift) {
memcpy(r + rlen - len + shift, tmp + shift, len - shift);
}
memset(tmp, 0, sizeof(tmp));
}
static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen) {
int len;
VERIFY_CHECK(alen > 0);
VERIFY_CHECK(alen <= 64);
len = mpn_set_str(r->data, a, alen, 256);
if (len == 0) {
r->data[0] = 0;
len = 1;
}
VERIFY_CHECK(len <= NUM_LIMBS*2);
r->limbs = len;
r->neg = 0;
while (r->limbs > 1 && r->data[r->limbs-1]==0) {
r->limbs--;
}
}
static void secp256k1_num_add_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) {
mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs);
r->limbs = a->limbs;
if (c != 0) {
VERIFY_CHECK(r->limbs < 2*NUM_LIMBS);
r->data[r->limbs++] = c;
}
}
static void secp256k1_num_sub_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) {
mp_limb_t c = mpn_sub(r->data, a->data, a->limbs, b->data, b->limbs);
(void)c;
VERIFY_CHECK(c == 0);
r->limbs = a->limbs;
while (r->limbs > 1 && r->data[r->limbs-1]==0) {
r->limbs--;
}
}
static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m) {
secp256k1_num_sanity(r);
secp256k1_num_sanity(m);
if (r->limbs >= m->limbs) {
mp_limb_t t[2*NUM_LIMBS];
mpn_tdiv_qr(t, r->data, 0, r->data, r->limbs, m->data, m->limbs);
memset(t, 0, sizeof(t));
r->limbs = m->limbs;
while (r->limbs > 1 && r->data[r->limbs-1]==0) {
r->limbs--;
}
}
if (r->neg && (r->limbs > 1 || r->data[0] != 0)) {
secp256k1_num_sub_abs(r, m, r);
r->neg = 0;
}
}
static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m) {
int i;
mp_limb_t g[NUM_LIMBS+1];
mp_limb_t u[NUM_LIMBS+1];
mp_limb_t v[NUM_LIMBS+1];
mp_size_t sn;
mp_size_t gn;
secp256k1_num_sanity(a);
secp256k1_num_sanity(m);
/** mpn_gcdext computes: (G,S) = gcdext(U,V), where
* * G = gcd(U,V)
* * G = U*S + V*T
* * U has equal or more limbs than V, and V has no padding
* If we set U to be (a padded version of) a, and V = m:
* G = a*S + m*T
* G = a*S mod m
* Assuming G=1:
* S = 1/a mod m
*/
VERIFY_CHECK(m->limbs <= NUM_LIMBS);
VERIFY_CHECK(m->data[m->limbs-1] != 0);
for (i = 0; i < m->limbs; i++) {
u[i] = (i < a->limbs) ? a->data[i] : 0;
v[i] = m->data[i];
}
sn = NUM_LIMBS+1;
gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs);
(void)gn;
VERIFY_CHECK(gn == 1);
VERIFY_CHECK(g[0] == 1);
r->neg = a->neg ^ m->neg;
if (sn < 0) {
mpn_sub(r->data, m->data, m->limbs, r->data, -sn);
r->limbs = m->limbs;
while (r->limbs > 1 && r->data[r->limbs-1]==0) {
r->limbs--;
}
} else {
r->limbs = sn;
}
memset(g, 0, sizeof(g));
memset(u, 0, sizeof(u));
memset(v, 0, sizeof(v));
}
static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b) {
int ret;
mpz_t ga, gb;
secp256k1_num_sanity(a);
secp256k1_num_sanity(b);
VERIFY_CHECK(!b->neg && (b->limbs > 0) && (b->data[0] & 1));
mpz_inits(ga, gb, NULL);
mpz_import(gb, b->limbs, -1, sizeof(mp_limb_t), 0, 0, b->data);
mpz_import(ga, a->limbs, -1, sizeof(mp_limb_t), 0, 0, a->data);
if (a->neg) {
mpz_neg(ga, ga);
}
ret = mpz_jacobi(ga, gb);
mpz_clears(ga, gb, NULL);
return ret;
}
static int secp256k1_num_is_one(const secp256k1_num *a) {
return (a->limbs == 1 && a->data[0] == 1);
}
static int secp256k1_num_is_zero(const secp256k1_num *a) {
return (a->limbs == 1 && a->data[0] == 0);
}
static int secp256k1_num_is_neg(const secp256k1_num *a) {
return (a->limbs > 1 || a->data[0] != 0) && a->neg;
}
static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b) {
if (a->limbs > b->limbs) {
return 1;
}
if (a->limbs < b->limbs) {
return -1;
}
return mpn_cmp(a->data, b->data, a->limbs);
}
static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b) {
if (a->limbs > b->limbs) {
return 0;
}
if (a->limbs < b->limbs) {
return 0;
}
if ((a->neg && !secp256k1_num_is_zero(a)) != (b->neg && !secp256k1_num_is_zero(b))) {
return 0;
}
return mpn_cmp(a->data, b->data, a->limbs) == 0;
}
static void secp256k1_num_subadd(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b, int bneg) {
if (!(b->neg ^ bneg ^ a->neg)) { /* a and b have the same sign */
r->neg = a->neg;
if (a->limbs >= b->limbs) {
secp256k1_num_add_abs(r, a, b);
} else {
secp256k1_num_add_abs(r, b, a);
}
} else {
if (secp256k1_num_cmp(a, b) > 0) {
r->neg = a->neg;
secp256k1_num_sub_abs(r, a, b);
} else {
r->neg = b->neg ^ bneg;
secp256k1_num_sub_abs(r, b, a);
}
}
}
static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) {
secp256k1_num_sanity(a);
secp256k1_num_sanity(b);
secp256k1_num_subadd(r, a, b, 0);
}
static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) {
secp256k1_num_sanity(a);
secp256k1_num_sanity(b);
secp256k1_num_subadd(r, a, b, 1);
}
static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) {
mp_limb_t tmp[2*NUM_LIMBS+1];
secp256k1_num_sanity(a);
secp256k1_num_sanity(b);
VERIFY_CHECK(a->limbs + b->limbs <= 2*NUM_LIMBS+1);
if ((a->limbs==1 && a->data[0]==0) || (b->limbs==1 && b->data[0]==0)) {
r->limbs = 1;
r->neg = 0;
r->data[0] = 0;
return;
}
if (a->limbs >= b->limbs) {
mpn_mul(tmp, a->data, a->limbs, b->data, b->limbs);
} else {
mpn_mul(tmp, b->data, b->limbs, a->data, a->limbs);
}
r->limbs = a->limbs + b->limbs;
if (r->limbs > 1 && tmp[r->limbs - 1]==0) {
r->limbs--;
}
VERIFY_CHECK(r->limbs <= 2*NUM_LIMBS);
mpn_copyi(r->data, tmp, r->limbs);
r->neg = a->neg ^ b->neg;
memset(tmp, 0, sizeof(tmp));
}
static void secp256k1_num_shift(secp256k1_num *r, int bits) {
if (bits % GMP_NUMB_BITS) {
/* Shift within limbs. */
mpn_rshift(r->data, r->data, r->limbs, bits % GMP_NUMB_BITS);
}
if (bits >= GMP_NUMB_BITS) {
int i;
/* Shift full limbs. */
for (i = 0; i < r->limbs; i++) {
int index = i + (bits / GMP_NUMB_BITS);
if (index < r->limbs && index < 2*NUM_LIMBS) {
r->data[i] = r->data[index];
} else {
r->data[i] = 0;
}
}
}
while (r->limbs>1 && r->data[r->limbs-1]==0) {
r->limbs--;
}
}
static void secp256k1_num_negate(secp256k1_num *r) {
r->neg ^= 1;
}
#endif /* SECP256K1_NUM_REPR_IMPL_H */

View File

@ -1,24 +0,0 @@
/***********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_NUM_IMPL_H
#define SECP256K1_NUM_IMPL_H
#if defined HAVE_CONFIG_H
#include "libsecp256k1-config.h"
#endif
#include "num.h"
#if defined(USE_NUM_GMP)
#include "num_gmp_impl.h"
#elif defined(USE_NUM_NONE)
/* Nothing. */
#else
#error "Please select num implementation"
#endif
#endif /* SECP256K1_NUM_IMPL_H */

View File

@ -7,7 +7,6 @@
#ifndef SECP256K1_SCALAR_H
#define SECP256K1_SCALAR_H
#include "num.h"
#include "util.h"
#if defined HAVE_CONFIG_H
@ -88,14 +87,6 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar *a);
* Returns -1 if the number was negated, 1 otherwise */
static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag);
#ifndef USE_NUM_NONE
/** Convert a scalar to a number. */
static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a);
/** Get the order of the group as a number. */
static void secp256k1_scalar_order_get_num(secp256k1_num *r);
#endif
/** Compare two scalars. */
static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b);

View File

@ -31,34 +31,6 @@
static const secp256k1_scalar secp256k1_scalar_one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1);
static const secp256k1_scalar secp256k1_scalar_zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
#ifndef USE_NUM_NONE
static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a) {
unsigned char c[32];
secp256k1_scalar_get_b32(c, a);
secp256k1_num_set_bin(r, c, 32);
}
/** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */
static void secp256k1_scalar_order_get_num(secp256k1_num *r) {
#if defined(EXHAUSTIVE_TEST_ORDER)
static const unsigned char order[32] = {
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,EXHAUSTIVE_TEST_ORDER
};
#else
static const unsigned char order[32] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41
};
#endif
secp256k1_num_set_bin(r, order, 32);
}
#endif
static int secp256k1_scalar_set_b32_seckey(secp256k1_scalar *r, const unsigned char *bin) {
int overflow;
secp256k1_scalar_set_b32(r, bin, &overflow);

View File

@ -9,7 +9,6 @@
#include "assumptions.h"
#include "util.h"
#include "num_impl.h"
#include "field_impl.h"
#include "scalar_impl.h"
#include "group_impl.h"

View File

@ -636,130 +636,6 @@ void run_rand_int(void) {
}
}
/***** NUM TESTS *****/
#ifndef USE_NUM_NONE
void random_num_negate(secp256k1_num *num) {
if (secp256k1_testrand_bits(1)) {
secp256k1_num_negate(num);
}
}
void random_num_order_test(secp256k1_num *num) {
secp256k1_scalar sc;
random_scalar_order_test(&sc);
secp256k1_scalar_get_num(num, &sc);
}
void random_num_order(secp256k1_num *num) {
secp256k1_scalar sc;
random_scalar_order(&sc);
secp256k1_scalar_get_num(num, &sc);
}
void test_num_negate(void) {
secp256k1_num n1;
secp256k1_num n2;
random_num_order_test(&n1); /* n1 = R */
random_num_negate(&n1);
secp256k1_num_copy(&n2, &n1); /* n2 = R */
secp256k1_num_sub(&n1, &n2, &n1); /* n1 = n2-n1 = 0 */
CHECK(secp256k1_num_is_zero(&n1));
secp256k1_num_copy(&n1, &n2); /* n1 = R */
secp256k1_num_negate(&n1); /* n1 = -R */
CHECK(!secp256k1_num_is_zero(&n1));
secp256k1_num_add(&n1, &n2, &n1); /* n1 = n2+n1 = 0 */
CHECK(secp256k1_num_is_zero(&n1));
secp256k1_num_copy(&n1, &n2); /* n1 = R */
secp256k1_num_negate(&n1); /* n1 = -R */
CHECK(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2));
secp256k1_num_negate(&n1); /* n1 = R */
CHECK(secp256k1_num_eq(&n1, &n2));
}
void test_num_add_sub(void) {
int i;
secp256k1_scalar s;
secp256k1_num n1;
secp256k1_num n2;
secp256k1_num n1p2, n2p1, n1m2, n2m1;
random_num_order_test(&n1); /* n1 = R1 */
if (secp256k1_testrand_bits(1)) {
random_num_negate(&n1);
}
random_num_order_test(&n2); /* n2 = R2 */
if (secp256k1_testrand_bits(1)) {
random_num_negate(&n2);
}
secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */
secp256k1_num_add(&n2p1, &n2, &n1); /* n2p1 = R2 + R1 */
secp256k1_num_sub(&n1m2, &n1, &n2); /* n1m2 = R1 - R2 */
secp256k1_num_sub(&n2m1, &n2, &n1); /* n2m1 = R2 - R1 */
CHECK(secp256k1_num_eq(&n1p2, &n2p1));
CHECK(!secp256k1_num_eq(&n1p2, &n1m2));
secp256k1_num_negate(&n2m1); /* n2m1 = -R2 + R1 */
CHECK(secp256k1_num_eq(&n2m1, &n1m2));
CHECK(!secp256k1_num_eq(&n2m1, &n1));
secp256k1_num_add(&n2m1, &n2m1, &n2); /* n2m1 = -R2 + R1 + R2 = R1 */
CHECK(secp256k1_num_eq(&n2m1, &n1));
CHECK(!secp256k1_num_eq(&n2p1, &n1));
secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */
CHECK(secp256k1_num_eq(&n2p1, &n1));
/* check is_one */
secp256k1_scalar_set_int(&s, 1);
secp256k1_scalar_get_num(&n1, &s);
CHECK(secp256k1_num_is_one(&n1));
/* check that 2^n + 1 is never 1 */
secp256k1_scalar_get_num(&n2, &s);
for (i = 0; i < 250; ++i) {
secp256k1_num_add(&n1, &n1, &n1); /* n1 *= 2 */
secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = n1 + 1 */
CHECK(!secp256k1_num_is_one(&n1p2));
}
}
void test_num_mod(void) {
int i;
secp256k1_scalar s;
secp256k1_num order, n;
/* check that 0 mod anything is 0 */
random_scalar_order_test(&s);
secp256k1_scalar_get_num(&order, &s);
secp256k1_scalar_set_int(&s, 0);
secp256k1_scalar_get_num(&n, &s);
secp256k1_num_mod(&n, &order);
CHECK(secp256k1_num_is_zero(&n));
/* check that anything mod 1 is 0 */
secp256k1_scalar_set_int(&s, 1);
secp256k1_scalar_get_num(&order, &s);
secp256k1_scalar_get_num(&n, &s);
secp256k1_num_mod(&n, &order);
CHECK(secp256k1_num_is_zero(&n));
/* check that increasing the number past 2^256 does not break this */
random_scalar_order_test(&s);
secp256k1_scalar_get_num(&n, &s);
/* multiply by 2^8, which'll test this case with high probability */
for (i = 0; i < 8; ++i) {
secp256k1_num_add(&n, &n, &n);
}
secp256k1_num_mod(&n, &order);
CHECK(secp256k1_num_is_zero(&n));
}
void run_num_smalltests(void) {
int i;
for (i = 0; i < 100*count; i++) {
test_num_negate();
test_num_add_sub();
test_num_mod();
}
}
#endif
/***** MODINV TESTS *****/
/* Compute the modular inverse of (odd) x mod 2^64. */
@ -1202,10 +1078,6 @@ void scalar_test(void) {
secp256k1_scalar s;
secp256k1_scalar s1;
secp256k1_scalar s2;
#ifndef USE_NUM_NONE
secp256k1_num snum, s1num, s2num;
secp256k1_num order, half_order;
#endif
unsigned char c[32];
/* Set 's' to a random scalar, with value 'snum'. */
@ -1218,16 +1090,6 @@ void scalar_test(void) {
random_scalar_order_test(&s2);
secp256k1_scalar_get_b32(c, &s2);
#ifndef USE_NUM_NONE
secp256k1_scalar_get_num(&snum, &s);
secp256k1_scalar_get_num(&s1num, &s1);
secp256k1_scalar_get_num(&s2num, &s2);
secp256k1_scalar_order_get_num(&order);
half_order = order;
secp256k1_num_shift(&half_order, 1);
#endif
{
int i;
/* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */
@ -1267,80 +1129,6 @@ void scalar_test(void) {
CHECK(secp256k1_scalar_eq(&n, &s));
}
#ifndef USE_NUM_NONE
{
/* Test that adding the scalars together is equal to adding their numbers together modulo the order. */
secp256k1_num rnum;
secp256k1_num r2num;
secp256k1_scalar r;
secp256k1_num_add(&rnum, &snum, &s2num);
secp256k1_num_mod(&rnum, &order);
secp256k1_scalar_add(&r, &s, &s2);
secp256k1_scalar_get_num(&r2num, &r);
CHECK(secp256k1_num_eq(&rnum, &r2num));
}
{
/* Test that multiplying the scalars is equal to multiplying their numbers modulo the order. */
secp256k1_scalar r;
secp256k1_num r2num;
secp256k1_num rnum;
secp256k1_num_mul(&rnum, &snum, &s2num);
secp256k1_num_mod(&rnum, &order);
secp256k1_scalar_mul(&r, &s, &s2);
secp256k1_scalar_get_num(&r2num, &r);
CHECK(secp256k1_num_eq(&rnum, &r2num));
/* The result can only be zero if at least one of the factors was zero. */
CHECK(secp256k1_scalar_is_zero(&r) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_zero(&s2)));
/* The results can only be equal to one of the factors if that factor was zero, or the other factor was one. */
CHECK(secp256k1_num_eq(&rnum, &snum) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_one(&s2)));
CHECK(secp256k1_num_eq(&rnum, &s2num) == (secp256k1_scalar_is_zero(&s2) || secp256k1_scalar_is_one(&s)));
}
{
secp256k1_scalar neg;
secp256k1_num negnum;
secp256k1_num negnum2;
/* Check that comparison with zero matches comparison with zero on the number. */
CHECK(secp256k1_num_is_zero(&snum) == secp256k1_scalar_is_zero(&s));
/* Check that comparison with the half order is equal to testing for high scalar. */
CHECK(secp256k1_scalar_is_high(&s) == (secp256k1_num_cmp(&snum, &half_order) > 0));
secp256k1_scalar_negate(&neg, &s);
secp256k1_num_sub(&negnum, &order, &snum);
secp256k1_num_mod(&negnum, &order);
/* Check that comparison with the half order is equal to testing for high scalar after negation. */
CHECK(secp256k1_scalar_is_high(&neg) == (secp256k1_num_cmp(&negnum, &half_order) > 0));
/* Negating should change the high property, unless the value was already zero. */
CHECK((secp256k1_scalar_is_high(&s) == secp256k1_scalar_is_high(&neg)) == secp256k1_scalar_is_zero(&s));
secp256k1_scalar_get_num(&negnum2, &neg);
/* Negating a scalar should be equal to (order - n) mod order on the number. */
CHECK(secp256k1_num_eq(&negnum, &negnum2));
secp256k1_scalar_add(&neg, &neg, &s);
/* Adding a number to its negation should result in zero. */
CHECK(secp256k1_scalar_is_zero(&neg));
secp256k1_scalar_negate(&neg, &neg);
/* Negating zero should still result in zero. */
CHECK(secp256k1_scalar_is_zero(&neg));
}
{
/* Test secp256k1_scalar_mul_shift_var. */
secp256k1_scalar r;
secp256k1_num one;
secp256k1_num rnum;
secp256k1_num rnum2;
unsigned char cone[1] = {0x01};
unsigned int shift = 256 + secp256k1_testrand_int(257);
secp256k1_scalar_mul_shift_var(&r, &s1, &s2, shift);
secp256k1_num_mul(&rnum, &s1num, &s2num);
secp256k1_num_shift(&rnum, shift - 1);
secp256k1_num_set_bin(&one, cone, 1);
secp256k1_num_add(&rnum, &rnum, &one);
secp256k1_num_shift(&rnum, 1);
secp256k1_scalar_get_num(&rnum2, &r);
CHECK(secp256k1_num_eq(&rnum, &rnum2));
}
{
/* test secp256k1_scalar_shr_int */
secp256k1_scalar r;
@ -1354,7 +1142,6 @@ void scalar_test(void) {
CHECK(expected == low);
}
}
#endif
{
/* Test commutativity of add. */
@ -1490,48 +1277,6 @@ void run_scalar_tests(void) {
CHECK(secp256k1_scalar_is_zero(&o));
}
#ifndef USE_NUM_NONE
{
/* Test secp256k1_scalar_set_b32 boundary conditions */
secp256k1_num order;
secp256k1_scalar scalar;
unsigned char bin[32];
unsigned char bin_tmp[32];
int overflow = 0;
/* 2^256-1 - order */
static const secp256k1_scalar all_ones_minus_order = SECP256K1_SCALAR_CONST(
0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000001UL,
0x45512319UL, 0x50B75FC4UL, 0x402DA173UL, 0x2FC9BEBEUL
);
/* A scalar set to 0s should be 0. */
memset(bin, 0, 32);
secp256k1_scalar_set_b32(&scalar, bin, &overflow);
CHECK(overflow == 0);
CHECK(secp256k1_scalar_is_zero(&scalar));
/* A scalar with value of the curve order should be 0. */
secp256k1_scalar_order_get_num(&order);
secp256k1_num_get_bin(bin, 32, &order);
secp256k1_scalar_set_b32(&scalar, bin, &overflow);
CHECK(overflow == 1);
CHECK(secp256k1_scalar_is_zero(&scalar));
/* A scalar with value of the curve order minus one should not overflow. */
bin[31] -= 1;
secp256k1_scalar_set_b32(&scalar, bin, &overflow);
CHECK(overflow == 0);
secp256k1_scalar_get_b32(bin_tmp, &scalar);
CHECK(secp256k1_memcmp_var(bin, bin_tmp, 32) == 0);
/* A scalar set to all 1s should overflow. */
memset(bin, 0xFF, 32);
secp256k1_scalar_set_b32(&scalar, bin, &overflow);
CHECK(overflow == 1);
CHECK(secp256k1_scalar_eq(&scalar, &all_ones_minus_order));
}
#endif
{
/* Does check_overflow check catch all ones? */
static const secp256k1_scalar overflowed = SECP256K1_SCALAR_CONST(
@ -1554,9 +1299,7 @@ void run_scalar_tests(void) {
secp256k1_scalar one;
secp256k1_scalar r1;
secp256k1_scalar r2;
#if defined(USE_SCALAR_INV_NUM)
secp256k1_scalar zzv;
#endif
int overflow;
unsigned char chal[33][2][32] = {
{{0xff, 0xff, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00,
@ -2106,10 +1849,8 @@ void run_scalar_tests(void) {
if (!secp256k1_scalar_is_zero(&y)) {
secp256k1_scalar_inverse(&zz, &y);
CHECK(!secp256k1_scalar_check_overflow(&zz));
#if defined(USE_SCALAR_INV_NUM)
secp256k1_scalar_inverse_var(&zzv, &y);
CHECK(secp256k1_scalar_eq(&zzv, &zz));
#endif
secp256k1_scalar_mul(&z, &z, &zz);
CHECK(!secp256k1_scalar_check_overflow(&z));
CHECK(secp256k1_scalar_eq(&x, &z));
@ -6075,11 +5816,6 @@ int main(int argc, char **argv) {
run_hmac_sha256_tests();
run_rfc6979_hmac_sha256_tests();
#ifndef USE_NUM_NONE
/* num tests */
run_num_smalltests();
#endif
/* scalar tests */
run_scalar_tests();