Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to use a statically generated ecmult context. #254

Merged
merged 2 commits into from
Jul 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ bench_verify
bench_recover
bench_internal
tests
gen_context
*.exe
*.so
*.a
Expand All @@ -28,6 +29,7 @@ build-aux/
*~
src/libsecp256k1-config.h
src/libsecp256k1-config.h.in
src/ecmult_static_context.h
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
Expand Down
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ compiler:
- gcc
env:
global:
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST=
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=no ASM=no BUILD=check EXTRAFLAGS= HOST=
matrix:
- SCALAR=32bit
- SCALAR=64bit
Expand All @@ -20,6 +20,7 @@ env:
- FIELD=32bit ENDOMORPHISM=yes
- BIGNUM=no
- BIGNUM=no ENDOMORPHISM=yes
- BIGNUM=no STATICPRECOMPUTATION=yes
- BUILD=distcheck
- EXTRAFLAGS=CFLAGS=-DDETERMINISTIC
matrix:
Expand Down Expand Up @@ -55,5 +56,5 @@ before_script: ./autogen.sh
script:
- if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi
- if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi
- ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
- ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
os: linux
18 changes: 18 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,22 @@ tests_LDFLAGS = -static
TESTS = tests
endif

if USE_ECMULT_STATIC_PRECOMPUTATION
CPPFLAGS_FOR_BUILD +=-I.
CFLAGS_FOR_BUILD += -Wall -Wextra -Wno-unused-function

gen_context_OBJECTS = gen_context.o

gen_%.o: src/gen_%.c
$(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@

gen_context$(BUILD_EXEEXT): $(gen_context_OBJECTS)
$(CC_FOR_BUILD) $^ -o $@

BUILT_SOURCES = src/ecmult_static_context.h

src/ecmult_static_context.h: gen_context
./gen_context
endif

EXTRA_DIST = autogen.sh
125 changes: 125 additions & 0 deletions build-aux/m4/ax_prog_cc_for_build.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PROG_CC_FOR_BUILD
#
# DESCRIPTION
#
# This macro searches for a C compiler that generates native executables,
# that is a C compiler that surely is not a cross-compiler. This can be
# useful if you have to generate source code at compile-time like for
# example GCC does.
#
# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything
# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD).
# The value of these variables can be overridden by the user by specifying
# a compiler with an environment variable (like you do for standard CC).
#
# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object
# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if
# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are
# substituted in the Makefile.
#
# LICENSE
#
# Copyright (c) 2008 Paolo Bonzini <bonzini@gnu.org>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.

#serial 8

AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD])
AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_CPP])dnl
AC_REQUIRE([AC_EXEEXT])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl

dnl Use the standard macros, but make them use other variable names
dnl
pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl
pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl
pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl
pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl
pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl
pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl
pushdef([ac_cv_objext], ac_cv_build_objext)dnl
pushdef([ac_exeext], ac_build_exeext)dnl
pushdef([ac_objext], ac_build_objext)dnl
pushdef([CC], CC_FOR_BUILD)dnl
pushdef([CPP], CPP_FOR_BUILD)dnl
pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl
pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl
pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl
pushdef([host], build)dnl
pushdef([host_alias], build_alias)dnl
pushdef([host_cpu], build_cpu)dnl
pushdef([host_vendor], build_vendor)dnl
pushdef([host_os], build_os)dnl
pushdef([ac_cv_host], ac_cv_build)dnl
pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl
pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl
pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl
pushdef([ac_cv_host_os], ac_cv_build_os)dnl
pushdef([ac_cpp], ac_build_cpp)dnl
pushdef([ac_compile], ac_build_compile)dnl
pushdef([ac_link], ac_build_link)dnl

save_cross_compiling=$cross_compiling
save_ac_tool_prefix=$ac_tool_prefix
cross_compiling=no
ac_tool_prefix=

AC_PROG_CC
AC_PROG_CPP
AC_EXEEXT

ac_tool_prefix=$save_ac_tool_prefix
cross_compiling=$save_cross_compiling

dnl Restore the old definitions
dnl
popdef([ac_link])dnl
popdef([ac_compile])dnl
popdef([ac_cpp])dnl
popdef([ac_cv_host_os])dnl
popdef([ac_cv_host_vendor])dnl
popdef([ac_cv_host_cpu])dnl
popdef([ac_cv_host_alias])dnl
popdef([ac_cv_host])dnl
popdef([host_os])dnl
popdef([host_vendor])dnl
popdef([host_cpu])dnl
popdef([host_alias])dnl
popdef([host])dnl
popdef([LDFLAGS])dnl
popdef([CPPFLAGS])dnl
popdef([CFLAGS])dnl
popdef([CPP])dnl
popdef([CC])dnl
popdef([ac_objext])dnl
popdef([ac_exeext])dnl
popdef([ac_cv_objext])dnl
popdef([ac_cv_exeext])dnl
popdef([ac_cv_prog_cc_g])dnl
popdef([ac_cv_prog_cc_cross])dnl
popdef([ac_cv_prog_cc_works])dnl
popdef([ac_cv_prog_gcc])dnl
popdef([ac_cv_prog_CPP])dnl

dnl Finally, set Makefile variables
dnl
BUILD_EXEEXT=$ac_build_exeext
BUILD_OBJEXT=$ac_build_objext
AC_SUBST(BUILD_EXEEXT)dnl
AC_SUBST(BUILD_OBJEXT)dnl
AC_SUBST([CFLAGS_FOR_BUILD])dnl
AC_SUBST([CPPFLAGS_FOR_BUILD])dnl
AC_SUBST([LDFLAGS_FOR_BUILD])dnl
])
11 changes: 11 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ PKG_PROG_PKG_CONFIG
AC_PATH_TOOL(AR, ar)
AC_PATH_TOOL(RANLIB, ranlib)
AC_PATH_TOOL(STRIP, strip)
AX_PROG_CC_FOR_BUILD

if test "x$CFLAGS" = "x"; then
CFLAGS="-O3 -g"
Expand Down Expand Up @@ -95,6 +96,11 @@ AC_ARG_ENABLE(endomorphism,
AS_HELP_STRING([--enable-endomorphism],[enable endomorphism (default is no)]),
[use_endomorphism=$enableval],
[use_endomorphism=no])

AC_ARG_ENABLE(ecmult_static_precomputation,
AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing (default is no)]),
[use_ecmult_static_precomputation=$enableval],
[use_ecmult_static_precomputation=no])

AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto],
[Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto])
Expand Down Expand Up @@ -305,6 +311,10 @@ if test x"$use_endomorphism" = x"yes"; then
AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization])
fi

if test x"$use_ecmult_static_precomputation" = x"yes"; then
AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table])
fi

AC_C_BIGENDIAN()

AC_MSG_NOTICE([Using assembly optimizations: $set_asm])
Expand All @@ -321,6 +331,7 @@ AC_SUBST(SECP_TEST_LIBS)
AC_SUBST(SECP_TEST_INCLUDES)
AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"])
AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"])
AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$use_ecmult_static_precomputation" = x"yes"])

dnl make sure nothing new is exported so that we don't break the cache
PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"
Expand Down
32 changes: 32 additions & 0 deletions src/basic-config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/

#ifndef _SECP256K1_BASIC_CONFIG_
#define _SECP256K1_BASIC_CONFIG_

#ifdef USE_BASIC_CONFIG

#undef USE_ASM_X86_64
#undef USE_ENDOMORPHISM
#undef USE_FIELD_10X26
#undef USE_FIELD_5X52
#undef USE_FIELD_INV_BUILTIN
#undef USE_FIELD_INV_NUM
#undef USE_NUM_GMP
#undef USE_NUM_NONE
#undef USE_SCALAR_4X64
#undef USE_SCALAR_8X32
#undef USE_SCALAR_INV_BUILTIN
#undef USE_SCALAR_INV_NUM

#define USE_NUM_NONE 1
#define USE_FIELD_INV_BUILTIN 1
#define USE_SCALAR_INV_BUILTIN 1
#define USE_FIELD_10X26 1
#define USE_SCALAR_8X32 1

#endif // USE_BASIC_CONFIG
#endif // _SECP256K1_BASIC_CONFIG_
17 changes: 15 additions & 2 deletions src/ecmult_gen_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@
#include "group.h"
#include "ecmult_gen.h"
#include "hash_impl.h"

#ifdef USE_ECMULT_STATIC_PRECOMPUTATION
#include "ecmult_static_context.h"
#endif
static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t *ctx) {
ctx->prec = NULL;
}

static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *ctx) {
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
secp256k1_ge_t prec[1024];
secp256k1_gej_t gj;
secp256k1_gej_t nums_gej;
int i, j;
#endif

if (ctx->prec != NULL) {
return;
}

#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
ctx->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*ctx->prec));

/* get the generator */
Expand Down Expand Up @@ -75,6 +79,9 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *c
secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]);
}
}
#else
ctx->prec = (secp256k1_ge_storage_t (*)[64][16])secp256k1_ecmult_static_context;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this cast necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is necessary to prevent a warning. I suppose I could change the type of ctx->prec instead at compile time to be const.

#endif
secp256k1_ecmult_gen_blind(ctx, NULL);
}

Expand All @@ -87,15 +94,21 @@ static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *d
if (src->prec == NULL) {
dst->prec = NULL;
} else {
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
dst->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*dst->prec));
memcpy(dst->prec, src->prec, sizeof(*dst->prec));
#else
dst->prec = src->prec;
#endif
dst->initial = src->initial;
dst->blind = src->blind;
}
}

static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t *ctx) {
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
free(ctx->prec);
#endif
secp256k1_scalar_clear(&ctx->blind);
secp256k1_gej_clear(&ctx->initial);
ctx->prec = NULL;
Expand Down
2 changes: 1 addition & 1 deletion src/field_10x26.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ typedef struct {
} secp256k1_fe_storage_t;

#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}

#define SECP256K1_FE_STORAGE_CONST_GET(d) d.n[7], d.n[6], d.n[5], d.n[4],d.n[3], d.n[2], d.n[1], d.n[0]
#endif
63 changes: 63 additions & 0 deletions src/gen_context.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**********************************************************************
* Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/

#define USE_BASIC_CONFIG 1

#include "basic-config.h"
#include "include/secp256k1.h"
#include "field_impl.h"
#include "scalar_impl.h"
#include "group_impl.h"
#include "ecmult_gen_impl.h"

int main(int argc, char **argv) {
secp256k1_ecmult_gen_context_t ctx;
int inner;
int outer;
FILE* fp;

(void)argc;
(void)argv;

fp = fopen("src/ecmult_static_context.h","w");
if (fp == NULL) {
fprintf(stderr, "Could not open src/ecmult_static_context.h for writing!\n");
return -1;
}

fprintf(fp, "#ifndef _SECP256K1_ECMULT_STATIC_CONTEXT_\n");
fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n");
fprintf(fp, "#include \"group.h\"\n");
fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n");
fprintf(fp, "static const secp256k1_ge_storage_t secp256k1_ecmult_static_context[64][16] = {\n");

secp256k1_ecmult_gen_context_init(&ctx);
secp256k1_ecmult_gen_context_build(&ctx);
for(outer = 0; outer != 64; outer++) {
fprintf(fp,"{\n");
for(inner = 0; inner != 16; inner++) {
fprintf(fp," SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET((*ctx.prec)[outer][inner]));
if (inner != 15) {
fprintf(fp,",\n");
} else {
fprintf(fp,"\n");
}
}
if (outer != 63) {
fprintf(fp,"},\n");
} else {
fprintf(fp,"}\n");
}
}
fprintf(fp,"};\n");
secp256k1_ecmult_gen_context_clear(&ctx);

fprintf(fp, "#undef SC\n");
fprintf(fp, "#endif\n");
fclose(fp);

return 0;
}
Loading