Browse Source

working on c++ benchmark

master
Mike Hamburg 9 years ago
parent
commit
59ab6ce535
6 changed files with 180 additions and 19 deletions
  1. +10
    -3
      Makefile
  2. +5
    -5
      include/decaf.h
  3. +13
    -3
      include/decaf.hxx
  4. +5
    -7
      include/decaf_crypto.h
  5. +145
    -0
      test/bench_decaf.cxx
  6. +2
    -1
      test/test_decaf.cxx

+ 10
- 3
Makefile View File

@@ -66,7 +66,7 @@ CXXFLAGS = $(LANGXXFLAGS) $(WARNFLAGS) $(INCFLAGS) $(OFLAGS) $(ARCHFLAGS) $(GENF
LDFLAGS = $(ARCHFLAGS) $(XLDFLAGS) LDFLAGS = $(ARCHFLAGS) $(XLDFLAGS)
ASFLAGS = $(ARCHFLAGS) $(XASFLAGS) ASFLAGS = $(ARCHFLAGS) $(XASFLAGS)


.PHONY: clean all test bench todo doc lib bat
.PHONY: clean all test bench test_decaf bench_decaf todo doc lib bat
.PRECIOUS: build/%.s .PRECIOUS: build/%.s


HEADERS= Makefile $(shell find . -name "*.h") $(shell find . -name "*.hxx") build/timestamp HEADERS= Makefile $(shell find . -name "*.h") $(shell find . -name "*.hxx") build/timestamp
@@ -87,6 +87,7 @@ TESTCOMPONENTS=build/test.o build/test_scalarmul.o build/test_sha512.o \
build/shake.o build/shake.o


TESTDECAFCOMPONENTS=build/test_decaf.o TESTDECAFCOMPONENTS=build/test_decaf.o
BENCHDECAFCOMPONENTS=build/bench_decaf.o


BENCHCOMPONENTS = build/bench.o build/shake.o BENCHCOMPONENTS = build/bench.o build/shake.o


@@ -108,7 +109,10 @@ build/test: $(LIBCOMPONENTS) $(TESTCOMPONENTS) $(DECAFCOMPONENTS)
$(LD) $(LDFLAGS) -o $@ $^ -lgmp $(LD) $(LDFLAGS) -o $@ $^ -lgmp


build/test_decaf: $(TESTDECAFCOMPONENTS) decaf_lib build/test_decaf: $(TESTDECAFCOMPONENTS) decaf_lib
$(LDXX) $(LDFLAGS) -o $@ $< -lgmp -Lbuild -ldecaf
$(LDXX) $(LDFLAGS) -o $@ $< -Lbuild -Wl,-rpath=`pwd`/build -ldecaf

build/bench_decaf: $(BENCHDECAFCOMPONENTS) decaf_lib
$(LDXX) $(LDFLAGS) -o $@ $< -Lbuild -Wl,-rpath=`pwd`/build -ldecaf
build/shakesum: build/shakesum.o build/shake.o build/shakesum: build/shakesum.o build/shake.o
$(LD) $(LDFLAGS) -o $@ $^ $(LD) $(LDFLAGS) -o $@ $^
@@ -223,7 +227,10 @@ test: build/test test_decaf
build/test build/test
test_decaf: build/test_decaf test_decaf: build/test_decaf
LD_LIBRARY_PATH=`pwd`/build:$(LD_LIBRARY_PATH) build/test_decaf
build/test_decaf
bench_decaf: build/bench_decaf
build/bench_decaf


clean: clean:
rm -fr build doc $(BATNAME) rm -fr build doc $(BATNAME)

+ 5
- 5
include/decaf.h View File

@@ -240,10 +240,10 @@ static inline void NONNULL2 decaf_448_scalar_copy (
* @param [out] out Will become equal to a. * @param [out] out Will become equal to a.
* @todo Make inline? * @todo Make inline?
*/ */
void decaf_448_scalar_set API_VIS NONNULL1 (
void decaf_448_scalar_set(
decaf_448_scalar_t out, decaf_448_scalar_t out,
decaf_word_t a decaf_word_t a
);
) API_VIS NONNULL1;


/** /**
* @brief Encode a point as a sequence of bytes. * @brief Encode a point as a sequence of bytes.
@@ -317,7 +317,7 @@ void decaf_448_point_add (
decaf_448_point_t sum, decaf_448_point_t sum,
const decaf_448_point_t a, const decaf_448_point_t a,
const decaf_448_point_t b const decaf_448_point_t b
) API_VIS NONNULL3; // TODO: NOINLINE?
) API_VIS NONNULL3;


/** /**
* @brief Double a point. Equivalent to * @brief Double a point. Equivalent to
@@ -329,7 +329,7 @@ void decaf_448_point_add (
void decaf_448_point_double ( void decaf_448_point_double (
decaf_448_point_t two_a, decaf_448_point_t two_a,
const decaf_448_point_t a const decaf_448_point_t a
) API_VIS NONNULL2; // TODO: NOINLINE?
) API_VIS NONNULL2;


/** /**
* @brief Subtract two points to produce a third point. The * @brief Subtract two points to produce a third point. The
@@ -455,7 +455,7 @@ void decaf_448_point_double_scalarmul (
* scaled = scalar1*decaf_448_point_base + scalar2*base2. * scaled = scalar1*decaf_448_point_base + scalar2*base2.
* *
* Otherwise equivalent to decaf_448_point_double_scalarmul, but may be * Otherwise equivalent to decaf_448_point_double_scalarmul, but may be
* faster.
* faster at the expense of being variable time.
* *
* @param [out] combo The linear combination scalar1*base + scalar2*base2. * @param [out] combo The linear combination scalar1*base + scalar2*base2.
* @param [in] scalar1 A first scalar to multiply by. * @param [in] scalar1 A first scalar to multiply by.


+ 13
- 3
include/decaf.hxx View File

@@ -87,13 +87,13 @@ public:
decaf_448_scalar_t s; decaf_448_scalar_t s;
/** @brief Set to an unsigned word */ /** @brief Set to an unsigned word */
inline Scalar(const decaf_word_t w=0) NOEXCEPT { *this = w; }
inline Scalar(const decaf_word_t w) NOEXCEPT { *this = w; }


/** @brief Set to a signed word */ /** @brief Set to a signed word */
inline Scalar(const int w) NOEXCEPT { *this = w; } inline Scalar(const int w) NOEXCEPT { *this = w; }
/** @brief Construct from decaf_scalar_t object. */ /** @brief Construct from decaf_scalar_t object. */
inline Scalar(const decaf_448_scalar_t &t) NOEXCEPT { decaf_448_scalar_copy(s,t); }
inline Scalar(const decaf_448_scalar_t &t = decaf_448_scalar_zero) NOEXCEPT { decaf_448_scalar_copy(s,t); }
/** @brief Copy constructor. */ /** @brief Copy constructor. */
inline Scalar(const Scalar &x) NOEXCEPT { decaf_448_scalar_copy(s,x.s); } inline Scalar(const Scalar &x) NOEXCEPT { decaf_448_scalar_copy(s,x.s); }
@@ -385,6 +385,15 @@ public:
Point p; decaf_448_point_double_scalarmul(p.p,q.p,qs.s,r.p,rs.s); return p; Point p; decaf_448_point_double_scalarmul(p.p,q.p,qs.s,r.p,rs.s); return p;
} }
/**
* @brief Double-scalar multiply: this point by the first scalar and base by the second scalar.
* @warning This function takes variable time, and may leak the scalars (or points, but currently
* it doesn't).
*/
inline Point non_secret_combo_with_base(const Scalar &s, const Scalar &s_base) {
Point r; decaf_448_base_double_scalarmul_non_secret(r.p,s_base.s,p,s.s); return r;
}
/** @brief Return the base point */ /** @brief Return the base point */
static inline const Point base() NOEXCEPT { return Point(decaf_448_point_base); } static inline const Point base() NOEXCEPT { return Point(decaf_448_point_base); }
@@ -438,7 +447,8 @@ public:
* *
* By default, initializes to the table for the base point. * By default, initializes to the table for the base point.
* *
* @todo: FIXME Harmonize with Point(), which initializes to the identity.
* @warning The empty initializer makes this equal to base, unlike the empty
* initializer for points which makes this equal to the identity.
*/ */
inline Precomputed( inline Precomputed(
const decaf_448_precomputed_s &yours = *decaf_448_precomputed_base const decaf_448_precomputed_s &yours = *decaf_448_precomputed_base


+ 5
- 7
include/decaf_crypto.h View File

@@ -47,12 +47,10 @@ typedef struct {
/** x*Base */ /** x*Base */
decaf_448_public_key_t pub; decaf_448_public_key_t pub;
/** @endcond */ /** @endcond */
}
/** Private key structure for pointers. */
decaf_448_private_key_s,

/** A private key (gmp array[1] style). */
decaf_448_private_key_t[1];
} /** Private key structure for pointers. */
decaf_448_private_key_s,
/** A private key (gmp array[1] style). */
decaf_448_private_key_t[1];


#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -179,7 +177,7 @@ decaf_448_verify (
#undef NONNULL5 #undef NONNULL5


#ifdef __cplusplus #ifdef __cplusplus
}; /* extern "C" */
} /* extern "C" */
#endif #endif


#endif /* __DECAF_CRYPTO_H__ */ #endif /* __DECAF_CRYPTO_H__ */


+ 145
- 0
test/bench_decaf.cxx View File

@@ -0,0 +1,145 @@
/**
* @file test_decaf.cxx
* @author Mike Hamburg
*
* @copyright
* Copyright (c) 2015 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
*
* @brief C++ benchmarks, because that's easier.
*/

#include "decaf.hxx"
#include "shake.h"
#include "decaf_crypto.h"
#include <stdio.h>
#include <sys/time.h>
#include <assert.h>
#include <stdint.h>

typedef decaf::decaf<448>::Scalar Scalar;
typedef decaf::decaf<448>::Point Point;
typedef decaf::decaf<448>::Precomputed Precomputed;

static __inline__ void __attribute__((unused)) ignore_result ( int result ) { (void)result; }
static double now(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec/1000000.0;
}

// RDTSC from the chacha code
#ifndef __has_builtin
#define __has_builtin(X) 0
#endif
#if defined(__clang__) && __has_builtin(__builtin_readcyclecounter)
#define rdtsc __builtin_readcyclecounter
#else
static inline uint64_t rdtsc(void) {
u_int64_t out = 0;
# if (defined(__i386__) || defined(__x86_64__))
__asm__ __volatile__ ("rdtsc" : "=A"(out));
# endif
return out;
}
#endif

class Benchmark {
static const int NTESTS = 1000;
public:
int i, ntests;
double begin;
uint64_t tsc_begin;
Benchmark(const char *s, double factor = 1) {
printf("%s:", s);
if (strlen(s) < 25) printf("%*s",int(25-strlen(s)),"");
fflush(stdout);
i = 0;
ntests = NTESTS * factor;
begin = now();
tsc_begin = rdtsc();
}
~Benchmark() {
double tsc = (rdtsc() - tsc_begin) * 1.0 / ntests;
double t = (now() - begin)/ntests;
const char *small[] = {" ","m","µ","n","p"};
const char *big[] = {" ","k","M","G","T"};
unsigned di=0;
for (di=0; di<sizeof(small)/sizeof(*small)-1 && t && t < 1; di++) {
t *= 1000.0;
}
unsigned bi=0;
for (bi=0; bi<sizeof(big)/sizeof(*big)-1 && tsc && tsc >= 1000; bi++) {
tsc /= 1000.0;
}
printf("%7.2f %ss", t, small[di]);
if (tsc) printf(" %7.2f %scy", tsc, big[bi]);
printf("\n");
}
inline bool iter() { return i++ < ntests; }
};

int main(int argc, char **argv) {
bool micro = false;
if (argc >= 2 && !strcmp(argv[1], "--micro"))
micro = true;
decaf_448_public_key_t p1,p2;
decaf_448_private_key_t s1,s2;
decaf_448_symmetric_key_t r1,r2;
decaf_448_signature_t sig1;
unsigned char ss[32];
memset(r1,1,sizeof(r1));
memset(r2,2,sizeof(r2));
unsigned char umessage[] = {1,2,3,4,5};
size_t lmessage = sizeof(umessage);

if (micro) {
Precomputed pBase;
Point p,q;
Scalar s,t;
printf("Micro:\n");
for (Benchmark b("Scalar add", 1000); b.iter(); ) { s+t; }
for (Benchmark b("Scalar times", 100); b.iter(); ) { s*t; }
for (Benchmark b("Scalar inv", 10); b.iter(); ) { s.inverse(); }
for (Benchmark b("Point add", 100); b.iter(); ) { p + q; }
for (Benchmark b("Point double", 100); b.iter(); ) { p.double_in_place(); }
for (Benchmark b("Point scalarmul"); b.iter(); ) { p * s; }
for (Benchmark b("Point double scalarmul"); b.iter(); ) { Point::double_scalarmul(p,s,q,t); }
for (Benchmark b("Point precmp scalarmul"); b.iter(); ) { pBase * s; }
/* TODO: scalarmul for verif */
printf("\nMacro:\n");
}
for (Benchmark b("Keygen"); b.iter(); ) {
decaf_448_derive_private_key(s1,r1);
}
decaf_448_private_to_public(p1,s1);
decaf_448_derive_private_key(s2,r2);
decaf_448_private_to_public(p2,s2);
for (Benchmark b("Shared secret"); b.iter(); ) {
decaf_bool_t ret = decaf_448_shared_secret(ss,sizeof(ss),s1,p2);
ignore_result(ret);
assert(ret);
}
for (Benchmark b("Sign"); b.iter(); ) {
decaf_448_sign(sig1,s1,umessage,lmessage);
}
for (Benchmark b("Verify"); b.iter(); ) {
decaf_bool_t ret = decaf_448_verify(sig1,p1,umessage,lmessage);
umessage[0]++;
ignore_result(ret);
}
printf("\n");
return 0;
}

+ 2
- 1
test/test_decaf.cxx View File

@@ -157,7 +157,7 @@ static void test_ec() {
Test test("EC"); Test test("EC");


Point id;
Point id = Point::identity(), base = Point::base();
point_check(test,id,id,id,0,0,Point::from_hash(std::string("")),id,"fh0"); point_check(test,id,id,id,0,0,Point::from_hash(std::string("")),id,"fh0");
point_check(test,id,id,id,0,0,Point::from_hash(std::string("\x01")),id,"fh1"); point_check(test,id,id,id,0,0,Point::from_hash(std::string("\x01")),id,"fh1");
@@ -183,6 +183,7 @@ static void test_ec() {
point_check(test,p,q,r,x,0,x*(p+q),x*p+x*q,"distr mul"); point_check(test,p,q,r,x,0,x*(p+q),x*p+x*q,"distr mul");
point_check(test,p,q,r,x,y,(x*y)*p,x*(y*p),"assoc mul"); point_check(test,p,q,r,x,y,(x*y)*p,x*(y*p),"assoc mul");
point_check(test,p,q,r,x,y,x*p+y*q,Point::double_scalarmul(x,p,y,q),"ds mul"); point_check(test,p,q,r,x,y,x*p+y*q,Point::double_scalarmul(x,p,y,q),"ds mul");
point_check(test,base,q,r,x,y,x*base+y*q,q.non_secret_combo_with_base(y,x),"ds vt mul");
point_check(test,p,q,r,x,0,Precomputed(p)*x,p*x,"precomp mul"); point_check(test,p,q,r,x,0,Precomputed(p)*x,p*x,"precomp mul");
} }
} }


Loading…
Cancel
Save