Skip to content

Commit

Permalink
Add ability to use a statically generated ecmult context.
Browse files Browse the repository at this point in the history
This vastly shrinks the size of the context required for signing on devices with
memory-mapped Flash.

Tables are generated by the new gen_context tool into a header.
  • Loading branch information
tdaede committed May 20, 2015
1 parent 729badf commit e1e4b66
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 2 deletions.
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
14 changes: 14 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ noinst_HEADERS += src/hash_impl.h
noinst_HEADERS += src/field.h
noinst_HEADERS += src/field_impl.h
noinst_HEADERS += src/bench.h
noinst_HEADERS += src/ecmult_static_context.h

pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libsecp256k1.pc
Expand Down Expand Up @@ -74,4 +75,17 @@ tests_LDFLAGS = -static
TESTS = tests
endif

if USE_ECMULT_STATIC_CONTEXT
noinst_PROGRAMS += gen_context
gen_context_SOURCES = src/gen_context.c
gen_context_CPPFLAGS = -DVERIFY $(SECP_INCLUDES) $(SECP_TEST_INCLUDES)
gen_context_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS)
gen_context_LDFLAGS = -static

BUILT_SOURCES = src/ecmult_static_context.h

src/ecmult_static_context.h: gen_context
./gen_context
endif

EXTRA_DIST = autogen.sh
8 changes: 8 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,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_context,
AS_HELP_STRING([--enable-ecmult-static-context],[enable ecmult static context for signing (default is no)]),
[use_ecmult_static_context=$enableval],
[use_ecmult_static_context=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 +310,8 @@ if test x"$use_endomorphism" = x"yes"; then
AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization])
fi

AC_DEFINE(USE_ECMULT_STATIC_CONTEXT, 1, [Define this symbol to use a statically generated ecmult context])

AC_C_BIGENDIAN()

AC_MSG_NOTICE([Using assembly optimizations: $set_asm])
Expand All @@ -321,6 +328,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_CONTEXT], [test x"$use_ecmult_static_context" = 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
13 changes: 11 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_CONTEXT
#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_CONTEXT
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_CONTEXT
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;
#endif
secp256k1_ecmult_gen_blind(ctx, NULL);
}

Expand All @@ -95,7 +102,9 @@ static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *d
}

static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t *ctx) {
#ifndef USE_ECMULT_STATIC_CONTEXT
free(ctx->prec);
#endif
secp256k1_scalar_clear(&ctx->blind);
secp256k1_gej_clear(&ctx->initial);
ctx->prec = NULL;
Expand Down
49 changes: 49 additions & 0 deletions src/gen_context.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**********************************************************************
* Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/

#if defined HAVE_CONFIG_H
#include "libsecp256k1-config.h"
#endif

#undef USE_ECMULT_STATIC_CONTEXT
#include "secp256k1.c"

int main(int argc, char **argv) {
secp256k1_ecmult_gen_context_t ctx;
uint8_t* ctx_bytes;
int ctx_len;
int i;
FILE* fp;

(void)argc;
(void)argv;

fp = fopen("src/ecmult_static_context.h","w");

fprintf(fp, "#ifndef _SECP256K1_ECMULT_STATIC_CONTEXT_\n");
fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n");
fprintf(fp, "static const uint8_t secp256k1_ecmult_static_context[] = {\n");

secp256k1_ecmult_gen_context_init(&ctx);
secp256k1_ecmult_gen_context_build(&ctx);
ctx_bytes = (uint8_t*)ctx.prec;
ctx_len = sizeof(*ctx.prec);
for (i = 0; i < ctx_len; i++) {
fprintf(fp, "0x%02x", ctx_bytes[i]);
if (i < (ctx_len - 1)) {
fprintf(fp, ",");
}
if ((i % 20) == 19) {
fprintf(fp, "\n");
}
}

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

return 0;
}

0 comments on commit e1e4b66

Please sign in to comment.