@@ -238,12 +238,12 @@ class SpongeRng; | |||||
* @brief Group with prime order. | * @brief Group with prime order. | ||||
* @todo Move declarations of functions up here? | * @todo Move declarations of functions up here? | ||||
*/ | */ | ||||
template<GroupId group = Ed448Goldilocks> struct decaf; | |||||
template<GroupId group = Ed448Goldilocks> struct EcGroup; | |||||
/** | /** | ||||
* @brief Ed448-Goldilocks/Decaf instantiation of group. | * @brief Ed448-Goldilocks/Decaf instantiation of group. | ||||
*/ | */ | ||||
template<> struct decaf<Ed448Goldilocks> { | |||||
template<> struct EcGroup<Ed448Goldilocks> { | |||||
/** @cond internal */ | /** @cond internal */ | ||||
class Point; | class Point; | ||||
@@ -193,11 +193,11 @@ private: | |||||
/**@cond internal*/ | /**@cond internal*/ | ||||
/* FIXME: multiple sizes */ | /* FIXME: multiple sizes */ | ||||
decaf<448>::Scalar::Scalar(SpongeRng &rng) { | |||||
EcGroup<448>::Scalar::Scalar(SpongeRng &rng) { | |||||
*this = rng.read(SER_BYTES); | *this = rng.read(SER_BYTES); | ||||
} | } | ||||
decaf<448>::Point::Point(SpongeRng &rng, bool uniform) { | |||||
EcGroup<448>::Point::Point(SpongeRng &rng, bool uniform) { | |||||
SecureBuffer buffer((uniform ? 2 : 1) * HASH_BYTES); | SecureBuffer buffer((uniform ? 2 : 1) * HASH_BYTES); | ||||
rng.read(buffer); | rng.read(buffer); | ||||
if (uniform) { | if (uniform) { | ||||
@@ -177,22 +177,6 @@ p448_strong_reduce ( | |||||
assert(is_zero(carry + scarry)); | assert(is_zero(carry + scarry)); | ||||
} | } | ||||
mask_t | |||||
p448_is_zero ( | |||||
const struct p448_t *a | |||||
) { | |||||
struct p448_t b; | |||||
p448_copy(&b,a); | |||||
p448_strong_reduce(&b); | |||||
uint32_t any = 0; | |||||
int i; | |||||
for (i=0; i<16; i++) { | |||||
any |= b.limb[i]; | |||||
} | |||||
return is_zero(any); | |||||
} | |||||
void | void | ||||
p448_serialize ( | p448_serialize ( | ||||
uint8_t *serial, | uint8_t *serial, | ||||
@@ -904,22 +904,6 @@ p448_strong_reduce ( | |||||
assert(is_zero(carry + scarry)); | assert(is_zero(carry + scarry)); | ||||
} | } | ||||
mask_t | |||||
p448_is_zero ( | |||||
const struct p448_t *a | |||||
) { | |||||
struct p448_t b; | |||||
p448_copy(&b,a); | |||||
p448_strong_reduce(&b); | |||||
uint32_t any = 0; | |||||
int i; | |||||
for (i=0; i<16; i++) { | |||||
any |= b.limb[i]; | |||||
} | |||||
return is_zero(any); | |||||
} | |||||
void | void | ||||
p448_serialize ( | p448_serialize ( | ||||
uint8_t *serial, | uint8_t *serial, | ||||
@@ -662,22 +662,6 @@ p448_strong_reduce ( | |||||
assert(is_zero(carry + scarry)); | assert(is_zero(carry + scarry)); | ||||
} | } | ||||
mask_t | |||||
p448_is_zero ( | |||||
const struct p448_t *a | |||||
) { | |||||
struct p448_t b; | |||||
p448_copy(&b,a); | |||||
p448_strong_reduce(&b); | |||||
uint32_t any = 0; | |||||
int i; | |||||
for (i=0; i<16; i++) { | |||||
any |= b.limb[i]; | |||||
} | |||||
return is_zero(any); | |||||
} | |||||
void | void | ||||
p448_serialize ( | p448_serialize ( | ||||
uint8_t *serial, | uint8_t *serial, | ||||
@@ -369,22 +369,6 @@ p448_strong_reduce ( | |||||
assert(is_zero(carry + scarry)); | assert(is_zero(carry + scarry)); | ||||
} | } | ||||
mask_t | |||||
p448_is_zero ( | |||||
const struct p448_t *a | |||||
) { | |||||
struct p448_t b; | |||||
p448_copy(&b,a); | |||||
p448_strong_reduce(&b); | |||||
uint64_t any = 0; | |||||
int i; | |||||
for (i=0; i<8; i++) { | |||||
any |= b.limb[i]; | |||||
} | |||||
return is_zero(any); | |||||
} | |||||
void | void | ||||
p448_serialize ( | p448_serialize ( | ||||
uint8_t *serial, | uint8_t *serial, | ||||
@@ -348,22 +348,6 @@ p448_strong_reduce ( | |||||
assert(is_zero(carry + scarry)); | assert(is_zero(carry + scarry)); | ||||
} | } | ||||
mask_t | |||||
p448_is_zero ( | |||||
const struct p448_t *a | |||||
) { | |||||
struct p448_t b; | |||||
p448_copy(&b,a); | |||||
p448_strong_reduce(&b); | |||||
uint64_t any = 0; | |||||
int i; | |||||
for (i=0; i<8; i++) { | |||||
any |= b.limb[i]; | |||||
} | |||||
return is_zero(any); | |||||
} | |||||
void | void | ||||
p448_serialize ( | p448_serialize ( | ||||
uint8_t *serial, | uint8_t *serial, | ||||
@@ -348,22 +348,6 @@ p480_strong_reduce ( | |||||
assert(is_zero(carry + scarry)); | assert(is_zero(carry + scarry)); | ||||
} | } | ||||
mask_t | |||||
p480_is_zero ( | |||||
const struct p480_t *a | |||||
) { | |||||
struct p480_t b; | |||||
p480_copy(&b,a); | |||||
p480_strong_reduce(&b); | |||||
uint64_t any = 0; | |||||
int i; | |||||
for (i=0; i<8; i++) { | |||||
any |= b.limb[i]; | |||||
} | |||||
return is_zero(any); | |||||
} | |||||
void | void | ||||
p480_serialize ( | p480_serialize ( | ||||
uint8_t *serial, | uint8_t *serial, | ||||
@@ -346,22 +346,6 @@ p521_strong_reduce ( | |||||
assert(is_zero(carry + scarry)); | assert(is_zero(carry + scarry)); | ||||
} | } | ||||
mask_t | |||||
p521_is_zero ( | |||||
const struct p521_t *a | |||||
) { | |||||
struct p521_t b; | |||||
p521_copy(&b,a); | |||||
p521_strong_reduce(&b); | |||||
uint64_t any = 0; | |||||
int i; | |||||
for (i=0; i<9; i++) { | |||||
any |= b.limb[i]; | |||||
} | |||||
return is_zero(any); | |||||
} | |||||
void | void | ||||
p521_serialize ( | p521_serialize ( | ||||
uint8_t *serial, | uint8_t *serial, | ||||
@@ -417,22 +417,6 @@ p521_strong_reduce ( | |||||
a->limb[3] = a->limb[7] = a->limb[11] = 0; | a->limb[3] = a->limb[7] = a->limb[11] = 0; | ||||
} | } | ||||
mask_t | |||||
p521_is_zero ( | |||||
const struct p521_t *a | |||||
) { | |||||
struct p521_t b; | |||||
p521_copy(&b,a); | |||||
p521_strong_reduce(&b); | |||||
uint64_t any = 0; | |||||
unsigned int i; | |||||
for (i=0; i<sizeof(b)/sizeof(b.limb[0]); i++) { | |||||
any |= b.limb[i]; | |||||
} | |||||
return is_zero(any); | |||||
} | |||||
void | void | ||||
p521_serialize ( | p521_serialize ( | ||||
uint8_t *serial, | uint8_t *serial, | ||||
@@ -17,11 +17,13 @@ | |||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <vector> | |||||
#include <algorithm> | |||||
using namespace decaf; | using namespace decaf; | ||||
typedef decaf<448>::Scalar Scalar; | |||||
typedef decaf<448>::Point Point; | |||||
typedef decaf<448>::Precomputed Precomputed; | |||||
typedef EcGroup<448>::Scalar Scalar; | |||||
typedef EcGroup<448>::Point Point; | |||||
typedef EcGroup<448>::Precomputed Precomputed; | |||||
static __inline__ void __attribute__((unused)) ignore_result ( int result ) { (void)result; } | static __inline__ void __attribute__((unused)) ignore_result ( int result ) { (void)result; } | ||||
@@ -66,31 +68,44 @@ static void printSI(double x, const char *unit, const char *spacer = " ") { | |||||
} | } | ||||
class Benchmark { | class Benchmark { | ||||
static const int NTESTS = 1000; | |||||
static const int NTESTS = 20, NSAMPLES=50, DISCARD=2; | |||||
static double totalCy, totalS; | static double totalCy, totalS; | ||||
/* FIXME Tcy if get descheduled */ | /* FIXME Tcy if get descheduled */ | ||||
public: | public: | ||||
int i, ntests; | |||||
int i, j, ntests, nsamples; | |||||
double begin; | double begin; | ||||
uint64_t tsc_begin; | uint64_t tsc_begin; | ||||
std::vector<double> times; | |||||
std::vector<uint64_t> cycles; | |||||
Benchmark(const char *s, double factor = 1) { | Benchmark(const char *s, double factor = 1) { | ||||
printf("%s:", s); | printf("%s:", s); | ||||
if (strlen(s) < 25) printf("%*s",int(25-strlen(s)),""); | if (strlen(s) < 25) printf("%*s",int(25-strlen(s)),""); | ||||
fflush(stdout); | fflush(stdout); | ||||
i = 0; | |||||
i = j = 0; | |||||
ntests = NTESTS * factor; | ntests = NTESTS * factor; | ||||
nsamples = NSAMPLES; | |||||
begin = now(); | begin = now(); | ||||
tsc_begin = rdtsc(); | tsc_begin = rdtsc(); | ||||
times = std::vector<double>(NSAMPLES); | |||||
cycles = std::vector<uint64_t>(NSAMPLES); | |||||
} | } | ||||
~Benchmark() { | ~Benchmark() { | ||||
double tsc = (rdtsc() - tsc_begin) * 1.0; | |||||
double t = (now() - begin); | |||||
double tsc = 0; | |||||
double t = 0; | |||||
std::sort(times.begin(), times.end()); | |||||
std::sort(cycles.begin(), cycles.end()); | |||||
for (int k=DISCARD; k<nsamples-DISCARD; k++) { | |||||
tsc += cycles[k]; | |||||
t += times[k]; | |||||
} | |||||
totalCy += tsc; | totalCy += tsc; | ||||
totalS += t; | totalS += t; | ||||
t /= ntests; | |||||
tsc /= ntests; | |||||
t /= ntests*(nsamples-2*DISCARD); | |||||
tsc /= ntests*(nsamples-2*DISCARD); | |||||
printSI(t,"s"); | printSI(t,"s"); | ||||
printf(" "); | printf(" "); | ||||
@@ -98,7 +113,22 @@ public: | |||||
if (tsc) { printf(" "); printSI(tsc, "cy"); } | if (tsc) { printf(" "); printSI(tsc, "cy"); } | ||||
printf("\n"); | printf("\n"); | ||||
} | } | ||||
inline bool iter() { return i++ < ntests; } | |||||
inline bool iter() { | |||||
i++; | |||||
if (i >= ntests) { | |||||
uint64_t tsc = rdtsc() - tsc_begin; | |||||
double t = now() - begin; | |||||
begin += t; | |||||
tsc_begin += tsc; | |||||
assert(j >= 0 && j < nsamples); | |||||
cycles[j] = tsc; | |||||
times[j] = t; | |||||
j++; | |||||
i = 0; | |||||
} | |||||
return j < nsamples; | |||||
} | |||||
static void calib() { | static void calib() { | ||||
if (totalS && totalCy) { | if (totalS && totalCy) { | ||||
const char *s = "Cycle calibration"; | const char *s = "Cycle calibration"; | ||||
@@ -42,9 +42,9 @@ public: | |||||
template<decaf::GroupId GROUP> struct Tests { | template<decaf::GroupId GROUP> struct Tests { | ||||
typedef typename decaf::decaf<GROUP>::Scalar Scalar; | |||||
typedef typename decaf::decaf<GROUP>::Point Point; | |||||
typedef typename decaf::decaf<GROUP>::Precomputed Precomputed; | |||||
typedef typename decaf::EcGroup<GROUP>::Scalar Scalar; | |||||
typedef typename decaf::EcGroup<GROUP>::Point Point; | |||||
typedef typename decaf::EcGroup<GROUP>::Precomputed Precomputed; | |||||
static void print(const char *name, const Scalar &x) { | static void print(const char *name, const Scalar &x) { | ||||
unsigned char buffer[DECAF_448_SCALAR_BYTES]; | unsigned char buffer[DECAF_448_SCALAR_BYTES]; | ||||