| @@ -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]; | ||||