Browse Source

Working on demagication, so as to support other curves for the CFRG benchmarks in a month or so.

Create new src/arithmetic.c for field-independent arithmetic (eg batch invert, is_square).

Replace p448_ with field_ where possible.

Create constant EDWARDS_D = -39081.

Create inline function field_mulw_scc for multiplying by compile-time signed curve constants.
master
Mike Hamburg 10 years ago
parent
commit
165510d57c
26 changed files with 1094 additions and 1255 deletions
  1. +1
    -1
      Makefile
  2. +0
    -35
      src/arch_32/p448.c
  3. +0
    -7
      src/arch_32/p448.h
  4. +0
    -36
      src/arch_arm_32/p448.c
  5. +1
    -8
      src/arch_arm_32/p448.h
  6. +0
    -36
      src/arch_neon/p448.c
  7. +0
    -7
      src/arch_neon/p448.h
  8. +0
    -35
      src/arch_neon_experimental/p448.c
  9. +0
    -7
      src/arch_neon_experimental/p448.h
  10. +0
    -36
      src/arch_ref64/p448.c
  11. +0
    -7
      src/arch_ref64/p448.h
  12. +0
    -35
      src/arch_x86_64/p448.c
  13. +0
    -7
      src/arch_x86_64/p448.h
  14. +76
    -0
      src/arithmetic.c
  15. +663
    -681
      src/ec_point.c
  16. +60
    -48
      src/include/ec_point.h
  17. +17
    -2
      src/include/field.h
  18. +11
    -7
      src/include/magic.h
  19. +8
    -1
      src/magic.c
  20. +2
    -2
      src/scalarmul.c
  21. +93
    -93
      test/bench.c
  22. +6
    -6
      test/test.c
  23. +3
    -3
      test/test.h
  24. +60
    -65
      test/test_arithmetic.c
  25. +26
    -26
      test/test_pointops.c
  26. +67
    -64
      test/test_scalarmul.c

+ 1
- 1
Makefile View File

@@ -63,7 +63,7 @@ ASFLAGS = $(ARCHFLAGS)
HEADERS= Makefile $(shell find . -name "*.h") build/timestamp

LIBCOMPONENTS= build/goldilocks.o build/barrett_field.o build/crandom.o \
build/p448.o build/ec_point.o build/scalarmul.o build/sha512.o build/magic.o
build/p448.o build/ec_point.o build/scalarmul.o build/sha512.o build/magic.o build/arithmetic.o

TESTCOMPONENTS=build/test.o build/test_scalarmul.o build/test_sha512.o \
build/test_pointops.o build/test_arithmetic.o build/test_goldilocks.o build/magic.o


+ 0
- 35
src/arch_32/p448.c View File

@@ -250,38 +250,3 @@ p448_deserialize (
return ~is_zero(ge ^ mask);
}

void
simultaneous_invert_p448(
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
) {
if (n==0) {
return;
} else if (n==1) {
p448_inverse(out,in);
return;
}
p448_copy(&out[1], &in[0]);
int i;
for (i=1; i<(int) (n-1); i++) {
p448_mul(&out[i+1], &out[i], &in[i]);
}
p448_mul(&out[0], &out[n-1], &in[n-1]);
struct p448_t tmp;
p448_inverse(&tmp, &out[0]);
p448_copy(&out[0], &tmp);
/* at this point, out[0] = product(in[i]) ^ -1
* out[i] = product(in[0]..in[i-1]) if i != 0
*/
for (i=n-1; i>0; i--) {
p448_mul(&tmp, &out[i], &out[0]);
p448_copy(&out[i], &tmp);
p448_mul(&tmp, &out[0], &in[i]);
p448_copy(&out[0], &tmp);
}
}

+ 0
- 7
src/arch_32/p448.h View File

@@ -151,13 +151,6 @@ p448_inverse (
struct p448_t* a,
const struct p448_t* x
);
void
simultaneous_invert_p448 (
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
);

static inline mask_t
p448_eq (


+ 0
- 36
src/arch_arm_32/p448.c View File

@@ -976,39 +976,3 @@ p448_deserialize (
return ~is_zero(ge ^ mask);
}

void
simultaneous_invert_p448(
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
) {
if (n==0) {
return;
} else if (n==1) {
p448_inverse(out,in);
return;
}
p448_copy(&out[1], &in[0]);
int i;
for (i=1; i<(int) (n-1); i++) {
p448_mul(&out[i+1], &out[i], &in[i]);
}
p448_mul(&out[0], &out[n-1], &in[n-1]);
struct p448_t tmp;
p448_inverse(&tmp, &out[0]);
p448_copy(&out[0], &tmp);
/* at this point, out[0] = product(in[i]) ^ -1
* out[i] = product(in[0]..in[i-1]) if i != 0
*/
for (i=n-1; i>0; i--) {
p448_mul(&tmp, &out[i], &out[0]);
p448_copy(&out[i], &tmp);
p448_mul(&tmp, &out[0], &in[i]);
p448_copy(&out[0], &tmp);
}
}

+ 1
- 8
src/arch_arm_32/p448.h View File

@@ -151,14 +151,7 @@ p448_inverse (
struct p448_t* a,
const struct p448_t* x
);
void
simultaneous_invert_p448 (
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
);

static inline mask_t
p448_eq (
const struct p448_t *a,


+ 0
- 36
src/arch_neon/p448.c View File

@@ -721,39 +721,3 @@ p448_deserialize (
return ~is_zero(ge ^ mask);
}

void
simultaneous_invert_p448(
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
) {
if (n==0) {
return;
} else if (n==1) {
p448_inverse(out,in);
return;
}
p448_copy(&out[1], &in[0]);
int i;
for (i=1; i<(int) (n-1); i++) {
p448_mul(&out[i+1], &out[i], &in[i]);
}
p448_mul(&out[0], &out[n-1], &in[n-1]);
struct p448_t tmp;
p448_inverse(&tmp, &out[0]);
p448_copy(&out[0], &tmp);
/* at this point, out[0] = product(in[i]) ^ -1
* out[i] = product(in[0]..in[i-1]) if i != 0
*/
for (i=n-1; i>0; i--) {
p448_mul(&tmp, &out[i], &out[0]);
p448_copy(&out[i], &tmp);
p448_mul(&tmp, &out[0], &in[i]);
p448_copy(&out[0], &tmp);
}
}

+ 0
- 7
src/arch_neon/p448.h View File

@@ -151,13 +151,6 @@ p448_inverse (
struct p448_t* a,
const struct p448_t* x
);
void
simultaneous_invert_p448 (
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
);

static inline mask_t
p448_eq (


+ 0
- 35
src/arch_neon_experimental/p448.c View File

@@ -736,38 +736,3 @@ p448_deserialize (
return ~is_zero(ge ^ mask);
}

void
simultaneous_invert_p448(
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
) {
if (n==0) {
return;
} else if (n==1) {
p448_inverse(out,in);
return;
}
p448_copy(&out[1], &in[0]);
int i;
for (i=1; i<(int) (n-1); i++) {
p448_mul(&out[i+1], &out[i], &in[i]);
}
p448_mul(&out[0], &out[n-1], &in[n-1]);
struct p448_t tmp;
p448_inverse(&tmp, &out[0]);
p448_copy(&out[0], &tmp);
/* at this point, out[0] = product(in[i]) ^ -1
* out[i] = product(in[0]..in[i-1]) if i != 0
*/
for (i=n-1; i>0; i--) {
p448_mul(&tmp, &out[i], &out[0]);
p448_copy(&out[i], &tmp);
p448_mul(&tmp, &out[0], &in[i]);
p448_copy(&out[0], &tmp);
}
}

+ 0
- 7
src/arch_neon_experimental/p448.h View File

@@ -154,13 +154,6 @@ p448_inverse (
struct p448_t* a,
const struct p448_t* x
);
void
simultaneous_invert_p448 (
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
);

static inline mask_t
p448_eq (


+ 0
- 36
src/arch_ref64/p448.c View File

@@ -439,39 +439,3 @@ p448_deserialize (
return ~is_zero(ge ^ mask);
}

void
simultaneous_invert_p448(
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
) {
if (n==0) {
return;
} else if (n==1) {
p448_inverse(out,in);
return;
}
p448_copy(&out[1], &in[0]);
int i;
for (i=1; i<(int) (n-1); i++) {
p448_mul(&out[i+1], &out[i], &in[i]);
}
p448_mul(&out[0], &out[n-1], &in[n-1]);
struct p448_t tmp;
p448_inverse(&tmp, &out[0]);
p448_copy(&out[0], &tmp);
/* at this point, out[0] = product(in[i]) ^ -1
* out[i] = product(in[0]..in[i-1]) if i != 0
*/
for (i=n-1; i>0; i--) {
p448_mul(&tmp, &out[i], &out[0]);
p448_copy(&out[i], &tmp);
p448_mul(&tmp, &out[0], &in[i]);
p448_copy(&out[0], &tmp);
}
}

+ 0
- 7
src/arch_ref64/p448.h View File

@@ -158,13 +158,6 @@ p448_inverse (
struct p448_t* a,
const struct p448_t* x
);
void
simultaneous_invert_p448 (
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
);

static inline mask_t
p448_eq (


+ 0
- 35
src/arch_x86_64/p448.c View File

@@ -419,38 +419,3 @@ p448_deserialize (
return ~is_zero(ge ^ mask);
}

void
simultaneous_invert_p448(
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
) {
if (n==0) {
return;
} else if (n==1) {
p448_inverse(out,in);
return;
}
p448_copy(&out[1], &in[0]);
int i;
for (i=1; i<(int) (n-1); i++) {
p448_mul(&out[i+1], &out[i], &in[i]);
}
p448_mul(&out[0], &out[n-1], &in[n-1]);
struct p448_t tmp;
p448_inverse(&tmp, &out[0]);
p448_copy(&out[0], &tmp);
/* at this point, out[0] = product(in[i]) ^ -1
* out[i] = product(in[0]..in[i-1]) if i != 0
*/
for (i=n-1; i>0; i--) {
p448_mul(&tmp, &out[i], &out[0]);
p448_copy(&out[i], &tmp);
p448_mul(&tmp, &out[0], &in[i]);
p448_copy(&out[0], &tmp);
}
}

+ 0
- 7
src/arch_x86_64/p448.h View File

@@ -151,13 +151,6 @@ p448_inverse (
struct p448_t* a,
const struct p448_t* x
);
void
simultaneous_invert_p448 (
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
);

static inline mask_t
p448_eq (


+ 76
- 0
src/arithmetic.c View File

@@ -0,0 +1,76 @@
/**
* @cond internal
* @file field.c
* @copyright
* Copyright (c) 2014 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
* @author Mike Hamburg
* @brief High-level arithmetic routines, independent of field (except 3 mod 4).
*/

#include "field.h"
#include "ec_point.h" // TODO

void
field_inverse (
struct field_t* a,
const struct field_t* x
) {
struct field_t L0, L1;
field_isr ( &L0, x );
field_sqr ( &L1, &L0 );
field_sqr ( &L0, &L1 );
field_mul ( a, x, &L0 );
}

mask_t
field_is_square (
const struct field_t* x
) {
mask_t L2, L3;
struct field_t L0, L1;
field_isr ( &L0, x );
field_sqr ( &L1, &L0 );
field_mul ( &L0, x, &L1 );
field_subw ( &L0, 1 );
field_bias ( &L0, 1 );
L3 = field_is_zero( &L0 );
L2 = field_is_zero( x );
return L3 | L2;
}

void
field_simultaneous_invert (
struct field_t *__restrict__ out,
const struct field_t *in,
unsigned int n
) {
if (n==0) {
return;
} else if (n==1) {
field_inverse(out,in);
return;
}
field_copy(&out[1], &in[0]);
int i;
for (i=1; i<(int) (n-1); i++) {
field_mul(&out[i+1], &out[i], &in[i]);
}
field_mul(&out[0], &out[n-1], &in[n-1]);
struct field_t tmp;
field_inverse(&tmp, &out[0]);
field_copy(&out[0], &tmp);
/* at this point, out[0] = product(in[i]) ^ -1
* out[i] = product(in[0]..in[i-1]) if i != 0
*/
for (i=n-1; i>0; i--) {
field_mul(&tmp, &out[i], &out[0]);
field_copy(&out[i], &tmp);
field_mul(&tmp, &out[0], &in[i]);
field_copy(&out[0], &tmp);
}
}

+ 663
- 681
src/ec_point.c
File diff suppressed because it is too large
View File


+ 60
- 48
src/include/ec_point.h View File

@@ -10,7 +10,7 @@
#ifndef __CC_INCLUDED_EC_POINT_H__
#define __CC_INCLUDED_EC_POINT_H__

#include "p448.h"
#include "field.h"

#ifdef __cplusplus
extern "C" {
@@ -20,21 +20,21 @@ extern "C" {
* Affine point on an Edwards curve.
*/
struct affine_t {
struct p448_t x, y;
struct field_t x, y;
};

/**
* Affine point on a twisted Edwards curve.
*/
struct tw_affine_t {
struct p448_t x, y;
struct field_t x, y;
};

/**
* Montgomery buffer.
*/
struct montgomery_t {
struct p448_t z0, xd, zd, xa, za;
struct field_t z0, xd, zd, xa, za;
};

/**
@@ -56,7 +56,7 @@ struct montgomery_t {
* instead.
*/
struct extensible_t {
struct p448_t x, y, z, t, u;
struct field_t x, y, z, t, u;
};

/**
@@ -64,7 +64,7 @@ struct extensible_t {
* suitable for accumulators.
*/
struct tw_extensible_t {
struct p448_t x, y, z, t, u;
struct field_t x, y, z, t, u;
};

/**
@@ -73,7 +73,7 @@ struct tw_extensible_t {
* Good for mixed readdition; suitable for fixed tables.
*/
struct tw_niels_t {
struct p448_t a, b, c;
struct field_t a, b, c;
};

/**
@@ -83,7 +83,7 @@ struct tw_niels_t {
*/
struct tw_pniels_t {
struct tw_niels_t n;
struct p448_t z;
struct field_t z;
};


@@ -159,9 +159,21 @@ copy_tw_pniels (
* If x=0, returns 0.
*/
void
p448_isr (
struct p448_t* a,
const struct p448_t* x
field_isr (
struct field_t* a,
const struct field_t* x
);
/**
* Batch inverts out[i] = 1/in[i]
*
* If any input is zero, all the outputs will be zero.
*/
void
field_simultaneous_invert (
struct p448_t *__restrict__ out,
const struct p448_t *in,
unsigned int n
);

/**
@@ -170,9 +182,9 @@ p448_isr (
* If x=0, returns 0.
*/
void
p448_inverse (
struct p448_t* a,
const struct p448_t* x
field_inverse (
struct field_t* a,
const struct field_t* x
);

/**
@@ -297,14 +309,14 @@ montgomery_step (
void
deserialize_montgomery (
struct montgomery_t* a,
const struct p448_t* sbz
const struct field_t* sbz
);

mask_t
serialize_montgomery (
struct p448_t* b,
struct field_t* b,
const struct montgomery_t* a,
const struct p448_t* sbz
const struct field_t* sbz
);

/**
@@ -320,7 +332,7 @@ serialize_montgomery (
*/
void
serialize_extensible (
struct p448_t* b,
struct field_t* b,
const struct extensible_t* a
);

@@ -329,7 +341,7 @@ serialize_extensible (
*/
void
untwist_and_double_and_serialize (
struct p448_t* b,
struct field_t* b,
const struct tw_extensible_t* a
);

@@ -368,8 +380,8 @@ test_only_twist (
);

mask_t
is_square (
const struct p448_t* x
field_is_square (
const struct field_t* x
);

mask_t
@@ -388,7 +400,7 @@ is_even_tw (
mask_t
deserialize_affine (
struct affine_t* a,
const struct p448_t* sz
const struct field_t* sz
);

/**
@@ -401,8 +413,8 @@ deserialize_affine (
mask_t
deserialize_and_twist_approx (
struct tw_extensible_t* a,
const struct p448_t* sdm1,
const struct p448_t* sz
const struct field_t* sdm1,
const struct field_t* sz
);

void
@@ -441,7 +453,7 @@ eq_tw_extensible (
void
elligator_2s_inject (
struct affine_t* a,
const struct p448_t* r
const struct field_t* r
);

mask_t
@@ -475,8 +487,8 @@ copy_affine (
struct affine_t* a,
const struct affine_t* ds
) {
p448_copy ( &a->x, &ds->x );
p448_copy ( &a->y, &ds->y );
field_copy ( &a->x, &ds->x );
field_copy ( &a->y, &ds->y );
}

void
@@ -484,8 +496,8 @@ copy_tw_affine (
struct tw_affine_t* a,
const struct tw_affine_t* ds
) {
p448_copy ( &a->x, &ds->x );
p448_copy ( &a->y, &ds->y );
field_copy ( &a->x, &ds->x );
field_copy ( &a->y, &ds->y );
}

void
@@ -493,11 +505,11 @@ copy_montgomery (
struct montgomery_t* a,
const struct montgomery_t* ds
) {
p448_copy ( &a->z0, &ds->z0 );
p448_copy ( &a->xd, &ds->xd );
p448_copy ( &a->zd, &ds->zd );
p448_copy ( &a->xa, &ds->xa );
p448_copy ( &a->za, &ds->za );
field_copy ( &a->z0, &ds->z0 );
field_copy ( &a->xd, &ds->xd );
field_copy ( &a->zd, &ds->zd );
field_copy ( &a->xa, &ds->xa );
field_copy ( &a->za, &ds->za );
}

void
@@ -505,11 +517,11 @@ copy_extensible (
struct extensible_t* a,
const struct extensible_t* ds
) {
p448_copy ( &a->x, &ds->x );
p448_copy ( &a->y, &ds->y );
p448_copy ( &a->z, &ds->z );
p448_copy ( &a->t, &ds->t );
p448_copy ( &a->u, &ds->u );
field_copy ( &a->x, &ds->x );
field_copy ( &a->y, &ds->y );
field_copy ( &a->z, &ds->z );
field_copy ( &a->t, &ds->t );
field_copy ( &a->u, &ds->u );
}

void
@@ -517,11 +529,11 @@ copy_tw_extensible (
struct tw_extensible_t* a,
const struct tw_extensible_t* ds
) {
p448_copy ( &a->x, &ds->x );
p448_copy ( &a->y, &ds->y );
p448_copy ( &a->z, &ds->z );
p448_copy ( &a->t, &ds->t );
p448_copy ( &a->u, &ds->u );
field_copy ( &a->x, &ds->x );
field_copy ( &a->y, &ds->y );
field_copy ( &a->z, &ds->z );
field_copy ( &a->t, &ds->t );
field_copy ( &a->u, &ds->u );
}

void
@@ -529,9 +541,9 @@ copy_tw_niels (
struct tw_niels_t* a,
const struct tw_niels_t* ds
) {
p448_copy ( &a->a, &ds->a );
p448_copy ( &a->b, &ds->b );
p448_copy ( &a->c, &ds->c );
field_copy ( &a->a, &ds->a );
field_copy ( &a->b, &ds->b );
field_copy ( &a->c, &ds->c );
}

void
@@ -540,7 +552,7 @@ copy_tw_pniels (
const struct tw_pniels_t* ds
) {
copy_tw_niels( &a->n, &ds->n );
p448_copy ( &a->z, &ds->z );
field_copy ( &a->z, &ds->z );
}




+ 17
- 2
src/include/field.h View File

@@ -8,16 +8,32 @@
*/
#ifndef __FIELD_H__
#define __FIELD_H__
#include "magic.h"

#include "p448.h"

#define FIELD_BITS 448
#define FIELD_BYTES (1+(FIELD_BITS-1)/8)
#define FIELD_WORDS (1+(FIELD_BITS-1)/sizeof(word_t))

/**
* @brief For GMP tests: little-endian representation of the field modulus.
*/
extern const uint8_t FIELD_MODULUS[FIELD_BYTES];

#define field_t p448_t
#define field_mul p448_mul
#define field_sqr p448_sqr
#define field_sqrn p448_sqrn
#define field_add p448_add
#define field_sub p448_sub
#define field_mulw p448_mulw
#define field_addw p448_addw
#define field_subw p448_subw
#define field_neg p448_neg
#define field_set_ui p448_set_ui
#define field_bias p448_bias
#define field_copy p448_copy
#define field_mask p448_mask
#define field_weak_reduce p448_weak_reduce
#define field_strong_reduce p448_strong_reduce
#define field_cond_swap p448_cond_swap
@@ -26,6 +42,5 @@
#define field_deserialize p448_deserialize
#define field_eq p448_eq
#define field_is_zero p448_is_zero
#define simultaneous_invert simultaneous_invert_p448 /* FUTURE: consistency */

#endif /* __FIELD_H__ */

+ 11
- 7
src/include/magic.h View File

@@ -17,18 +17,17 @@

/* TODO: standardize notation */


/** @brief The number of bits in the Goldilocks field. */
#define GOLDI_FIELD_BITS 448

/** @brief The number of words in the Goldilocks field. */
#define GOLDI_FIELD_WORDS DIV_CEIL(GOLDI_FIELD_BITS,WORD_BITS)
#define GOLDI_FIELD_WORDS DIV_CEIL(FIELD_BITS,WORD_BITS)

/** @brief The number of bits in the Goldilocks curve's cofactor (cofactor=4). */
#define COFACTOR_BITS 2

/** @brief The number of bits in a Goldilocks scalar. */
#define SCALAR_BITS (GOLDI_FIELD_BITS - COFACTOR_BITS)
#define SCALAR_BITS (FIELD_BITS - COFACTOR_BITS)

/** @brief The number of bytes in a Goldilocks scalar. */
#define SCALAR_BYTES (1+(SCALAR_BITS)/8)

/** @brief The number of words in the Goldilocks field. */
#define SCALAR_WORDS WORDS_FOR_BITS(SCALAR_BITS)
@@ -36,7 +35,12 @@
/**
* @brief sqrt(d-1), used for point formats and twisting.
*/
extern const struct p448_t sqrt_d_minus_1;
extern const struct field_t sqrt_d_minus_1;

/**
* @brief The Edwards "d" term for this curve.
*/
static const int64_t EDWARDS_D = -39081;

/**
* @brief The base point for Goldilocks.


+ 8
- 1
src/magic.c View File

@@ -6,7 +6,14 @@
#include "magic.h"
#include "barrett_field.h"

/* FUTURE: automatically generate this file. */
/* FUTURE: automatically generate this file? */

const uint8_t FIELD_MODULUS[FIELD_BYTES] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*!*/ 0xfe, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

const word_t SCALARMUL_FIXED_WINDOW_ADJUSTMENT[2*SCALAR_WORDS] = {
U64LE(0xebec9967f5d3f5c2),


+ 2
- 2
src/scalarmul.c View File

@@ -570,7 +570,7 @@ precompute_fixed_base (
}
}
simultaneous_invert(zis, zs, n<<(t-1));
field_simultaneous_invert(zis, zs, n<<(t-1));

field_t product;
for (i=0; i<n<<(t-1); i++) {
@@ -658,7 +658,7 @@ precompute_fixed_base_wnaf (
}
}
simultaneous_invert(zis, zs, 1<<tbits);
field_simultaneous_invert(zis, zs, 1<<tbits);

field_t product;
for (i=0; i<1<<tbits; i++) {


+ 93
- 93
test/bench.c View File

@@ -9,7 +9,7 @@
#include <stdio.h>
#include <memory.h>

#include "p448.h"
#include "field.h"
#include "ec_point.h"
#include "scalarmul.h"
#include "barrett_field.h"
@@ -29,19 +29,19 @@ static double now(void) {
return tv.tv_sec + tv.tv_usec/1000000.0;
}

static void p448_randomize( struct crandom_state_t *crand, struct p448_t *a ) {
static void field_randomize( struct crandom_state_t *crand, struct field_t *a ) {
crandom_generate(crand, (unsigned char *)a, sizeof(*a));
p448_strong_reduce(a);
field_strong_reduce(a);
}

static void q448_randomize( struct crandom_state_t *crand, word_t sk[448/WORD_BITS] ) {
crandom_generate(crand, (unsigned char *)sk, 448/8);
static void q448_randomize( struct crandom_state_t *crand, word_t sk[SCALAR_WORDS] ) {
crandom_generate(crand, (unsigned char *)sk, SCALAR_BYTES);
}

static void p448_print( const char *descr, const struct p448_t *a ) {
p448_t b;
p448_copy(&b, a);
p448_strong_reduce(&b);
static void field_print( const char *descr, const struct field_t *a ) {
field_t b;
field_copy(&b, a);
field_strong_reduce(&b);
int j;
printf("%s = 0x", descr);
for (j=sizeof(*a)/sizeof(a->limb[0])-1; j>=0; j--) {
@@ -51,9 +51,9 @@ static void p448_print( const char *descr, const struct p448_t *a ) {
}

static void __attribute__((unused))
p448_print_full (
field_print_full (
const char *descr,
const struct p448_t *a
const struct field_t *a
) {
int j;
printf("%s = 0x", descr);
@@ -64,10 +64,10 @@ p448_print_full (
printf("\n");
}

static void q448_print( const char *descr, const word_t secret[448/WORD_BITS] ) {
static void q448_print( const char *descr, const word_t secret[SCALAR_WORDS] ) {
int j;
printf("%s = 0x", descr);
for (j=448/WORD_BITS-1; j>=0; j--) {
for (j=SCALAR_WORDS-1; j>=0; j--) {
printf(PRIxWORDfull, secret[j]);
}
printf("\n");
@@ -87,7 +87,7 @@ int main(int argc, char **argv) {
struct tw_pniels_t pniels;
struct affine_t affine;
struct montgomery_t mb;
struct p448_t a,b,c,d;
struct field_t a,b,c,d;
double when;
@@ -104,41 +104,41 @@ int main(int argc, char **argv) {
ignore_result(crandom_init_from_file(&crand, "/dev/urandom", 10000, 1));
*/
word_t sk[448/WORD_BITS],tk[448/WORD_BITS];
word_t sk[SCALAR_WORDS],tk[SCALAR_WORDS];
q448_randomize(&crand, sk);
when = now();
for (i=0; i<nbase*5000; i++) {
p448_mul(&c, &b, &a);
field_mul(&c, &b, &a);
}
when = now() - when;
printf("mul: %5.1fns\n", when * 1e9 / i);
when = now();
for (i=0; i<nbase*5000; i++) {
p448_sqr(&c, &a);
field_sqr(&c, &a);
}
when = now() - when;
printf("sqr: %5.1fns\n", when * 1e9 / i);
when = now();
for (i=0; i<nbase*5000; i++) {
p448_mulw(&c, &b, 1234562);
field_mulw(&c, &b, 1234562);
}
when = now() - when;
printf("mulw: %5.1fns\n", when * 1e9 / i);
when = now();
for (i=0; i<nbase*500; i++) {
p448_mul(&c, &b, &a);
p448_mul(&a, &b, &c);
field_mul(&c, &b, &a);
field_mul(&a, &b, &c);
}
when = now() - when;
printf("mul dep: %5.1fns\n", when * 1e9 / i / 2);
when = now();
for (i=0; i<nbase*10; i++) {
p448_randomize(&crand, &a);
field_randomize(&crand, &a);
}
when = now() - when;
printf("rand448: %5.1fns\n", when * 1e9 / i);
@@ -162,23 +162,23 @@ int main(int argc, char **argv) {
when = now();
for (i=0; i<nbase; i++) {
p448_isr(&c, &a);
field_isr(&c, &a);
}
when = now() - when;
printf("isr auto: %5.1fµs\n", when * 1e6 / i);
for (i=0; i<100; i++) {
p448_randomize(&crand, &a);
p448_isr(&d,&a);
p448_sqr(&b,&d);
p448_mul(&c,&b,&a);
p448_sqr(&b,&c);
p448_subw(&b,1);
p448_bias(&b,1);
if (!p448_is_zero(&b)) {
field_randomize(&crand, &a);
field_isr(&d,&a);
field_sqr(&b,&d);
field_mul(&c,&b,&a);
field_sqr(&b,&c);
field_subw(&b,1);
field_bias(&b,1);
if (!field_is_zero(&b)) {
printf("ISR validation failure!\n");
p448_print("a", &a);
p448_print("s", &d);
field_print("a", &a);
field_print("s", &d);
}
}
@@ -190,13 +190,13 @@ int main(int argc, char **argv) {
printf("elligator: %5.1fµs\n", when * 1e6 / i);
for (i=0; i<100; i++) {
p448_randomize(&crand, &a);
field_randomize(&crand, &a);
elligator_2s_inject(&affine, &a);
if (!validate_affine(&affine)) {
printf("Elligator validation failure!\n");
p448_print("a", &a);
p448_print("x", &affine.x);
p448_print("y", &affine.y);
field_print("a", &a);
field_print("x", &affine.x);
field_print("y", &affine.y);
}
}
@@ -216,28 +216,28 @@ int main(int argc, char **argv) {
int goods = 0;
for (i=0; i<100; i++) {
p448_randomize(&crand, &a);
field_randomize(&crand, &a);
mask_t good = deserialize_affine(&affine, &a);
if (good & !validate_affine(&affine)) {
printf("Deserialize validation failure!\n");
p448_print("a", &a);
p448_print("x", &affine.x);
p448_print("y", &affine.y);
field_print("a", &a);
field_print("x", &affine.x);
field_print("y", &affine.y);
} else if (good) {
goods++;
convert_affine_to_extensible(&exta,&affine);
serialize_extensible(&b, &exta);
p448_sub(&c,&b,&a);
p448_bias(&c,2);
if (!p448_is_zero(&c)) {
field_sub(&c,&b,&a);
field_bias(&c,2);
if (!field_is_zero(&c)) {
printf("Reserialize validation failure!\n");
p448_print("a", &a);
p448_print("x", &affine.x);
p448_print("y", &affine.y);
field_print("a", &a);
field_print("x", &affine.x);
field_print("y", &affine.y);
deserialize_affine(&affine, &b);
p448_print("b", &b);
p448_print("x", &affine.x);
p448_print("y", &affine.y);
field_print("b", &b);
field_print("x", &affine.x);
field_print("y", &affine.y);
printf("\n");
}
}
@@ -258,7 +258,7 @@ int main(int argc, char **argv) {
when = now();
for (i=0; i<nbase*10; i++) {
barrett_mac(lsk,448/WORD_BITS,lsk,448/WORD_BITS,lsk,448/WORD_BITS,&curve_prime_order);
barrett_mac(lsk,SCALAR_WORDS,lsk,SCALAR_WORDS,lsk,SCALAR_WORDS,&curve_prime_order);
}
when = now() - when;
printf("barrett mac: %5.1fns\n", when * 1e9 / i);
@@ -307,7 +307,7 @@ int main(int argc, char **argv) {
when = now();
for (i=0; i<nbase/10; i++) {
ignore_result(montgomery_ladder(&a,&b,sk,448,0));
ignore_result(montgomery_ladder(&a,&b,sk,FIELD_BITS,0));
}
when = now() - when;
printf("full ladder: %5.1fµs\n", when * 1e6 / i);
@@ -337,7 +337,7 @@ int main(int argc, char **argv) {
when = now();
for (i=0; i<nbase/10; i++) {
q448_randomize(&crand, sk);
scalarmul_vt(&ext,sk,446);
scalarmul_vt(&ext,sk,SCALAR_BITS);
}
when = now() - when;
printf("edwards vtm: %5.1fµs\n", when * 1e6 / i);
@@ -353,7 +353,7 @@ int main(int argc, char **argv) {
when = now();
for (i=0; i<nbase/10; i++) {
q448_randomize(&crand, sk);
scalarmul_fixed_base_wnaf_vt(&ext,sk,446,wnaft,6);
scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,wnaft,6);
}
when = now() - when;
printf("edwards vt6: %5.1fµs\n", when * 1e6 / i);
@@ -368,7 +368,7 @@ int main(int argc, char **argv) {
when = now();
for (i=0; i<nbase/10; i++) {
q448_randomize(&crand, sk);
scalarmul_fixed_base_wnaf_vt(&ext,sk,446,wnaft,4);
scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,wnaft,4);
}
when = now() - when;
printf("edwards vt4: %5.1fµs\n", when * 1e6 / i);
@@ -383,7 +383,7 @@ int main(int argc, char **argv) {
when = now();
for (i=0; i<nbase/10; i++) {
q448_randomize(&crand, sk);
scalarmul_fixed_base_wnaf_vt(&ext,sk,446,wnaft,5);
scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,wnaft,5);
}
when = now() - when;
printf("edwards vt5: %5.1fµs\n", when * 1e6 / i);
@@ -392,7 +392,7 @@ int main(int argc, char **argv) {
for (i=0; i<nbase/10; i++) {
q448_randomize(&crand, sk);
q448_randomize(&crand, tk);
linear_combo_var_fixed_vt(&ext,sk,448,tk,448,wnaft,5);
linear_combo_var_fixed_vt(&ext,sk,FIELD_BITS,tk,FIELD_BITS,wnaft,5);
}
when = now() - when;
printf("vt vf combo: %5.1fµs\n", when * 1e6 / i);
@@ -412,7 +412,7 @@ int main(int argc, char **argv) {
struct fixed_base_table_t t_5_5_18, t_3_5_30, t_8_4_14, t_5_3_30, t_15_3_10;

while (1) {
p448_randomize(&crand, &a);
field_randomize(&crand, &a);
if (deserialize_affine(&affine, &a)) break;
}
convert_affine_to_extensible(&exta,&affine);
@@ -459,35 +459,35 @@ int main(int argc, char **argv) {
when = now();
for (i=0; i<nbase; i++) {
scalarmul_fixed_base(&ext, sk, 448, &t_5_5_18);
scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_5_5_18);
}
when = now() - when;
printf("com(5,5,18): %5.1fµs\n", when * 1e6 / i);
when = now();
for (i=0; i<nbase; i++) {
scalarmul_fixed_base(&ext, sk, 448, &t_3_5_30);
scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_3_5_30);
}
when = now() - when;
printf("com(3,5,30): %5.1fµs\n", when * 1e6 / i);

when = now();
for (i=0; i<nbase; i++) {
scalarmul_fixed_base(&ext, sk, 448, &t_8_4_14);
scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_8_4_14);
}
when = now() - when;
printf("com(8,4,14): %5.1fµs\n", when * 1e6 / i);

when = now();
for (i=0; i<nbase; i++) {
scalarmul_fixed_base(&ext, sk, 448, &t_5_3_30);
scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_5_3_30);
}
when = now() - when;
printf("com(5,3,30): %5.1fµs\n", when * 1e6 / i);

when = now();
for (i=0; i<nbase; i++) {
scalarmul_fixed_base(&ext, sk, 448, &t_15_3_10);
scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_15_3_10);
}
when = now() - when;
printf("com(15,3,10):%5.1fµs\n", when * 1e6 / i);
@@ -528,25 +528,25 @@ int main(int argc, char **argv) {
printf("[FAIL] %d %d\n",gres1,gres2);
printf("sk1 = ");
for (i=0; i<56; i++) {
for (i=0; i<SCALAR_BYTES; i++) {
printf("%02x", gsk.opaque[i]);
}
printf("\nsk2 = ");
for (i=0; i<56; i++) {
for (i=0; i<SCALAR_BYTES; i++) {
printf("%02x", hsk.opaque[i]);
}
printf("\nss1 = ");
for (i=0; i<56; i++) {
for (i=0; i<FIELD_BYTES; i++) {
printf("%02x", ss1[i]);
}
printf("\nss2 = ");
for (i=0; i<56; i++) {
for (i=0; i<FIELD_BYTES; i++) {
printf("%02x", ss2[i]);
}
printf("\n");
}
uint8_t sout[56*2];
uint8_t sout[FIELD_BYTES*2];
const char *message = "hello world";
size_t message_len = strlen(message);
when = now();
@@ -610,7 +610,7 @@ int main(int argc, char **argv) {
failures=0; successes = 0;
for (i=0; i<nbase/10; i++) {
p448_randomize(&crand, &a);
field_randomize(&crand, &a);
word_t two = 2;
mask_t good = montgomery_ladder(&b,&a,&two,2,0);
if (!good) continue;
@@ -626,14 +626,14 @@ int main(int argc, char **argv) {
ignore_result(montgomery_ladder(&c,&b,&y,WORD_BITS,0));
ignore_result(montgomery_ladder(&b,&a,&z,WORD_BITS,0));
p448_sub(&d,&b,&c);
p448_bias(&d,2);
if (!p448_is_zero(&d)) {
field_sub(&d,&b,&c);
field_bias(&d,2);
if (!field_is_zero(&d)) {
printf("Odd ladder validation failure %d!\n", ++failures);
p448_print("a", &a);
field_print("a", &a);
printf("x=%"PRIxWORD", y=%"PRIxWORD", z=%"PRIxWORD"\n", x,y,z);
p448_print("c", &c);
p448_print("b", &b);
field_print("c", &c);
field_print("b", &b);
printf("\n");
}
}
@@ -642,7 +642,7 @@ int main(int argc, char **argv) {
for (i=0; i<nbase/10; i++) {
mask_t good;
do {
p448_randomize(&crand, &a);
field_randomize(&crand, &a);
good = deserialize_affine(&affine, &a);
} while (!good);
@@ -652,14 +652,14 @@ int main(int argc, char **argv) {
serialize_extensible(&b, &exta);
untwist_and_double_and_serialize(&c, &ext);
p448_sub(&d,&b,&c);
p448_bias(&d,2);
field_sub(&d,&b,&c);
field_bias(&d,2);
if (good && !p448_is_zero(&d)){
if (good && !field_is_zero(&d)){
printf("Iso+serial validation failure %d!\n", ++failures);
p448_print("a", &a);
p448_print("b", &b);
p448_print("c", &c);
field_print("a", &a);
field_print("b", &b);
field_print("c", &c);
printf("\n");
} else if (good) {
successes ++;
@@ -671,23 +671,23 @@ int main(int argc, char **argv) {
successes = failures = 0;
for (i=0; i<nbase/10; i++) {
struct p448_t aa;
struct field_t aa;
struct tw_extensible_t exu,exv,exw;
mask_t good;
do {
p448_randomize(&crand, &a);
field_randomize(&crand, &a);
good = deserialize_affine(&affine, &a);
convert_affine_to_extensible(&exta,&affine);
twist_and_double(&ext,&exta);
} while (!good);
do {
p448_randomize(&crand, &aa);
field_randomize(&crand, &aa);
good = deserialize_affine(&affine, &aa);
convert_affine_to_extensible(&exta,&affine);
twist_and_double(&exu,&exta);
} while (!good);
p448_randomize(&crand, &aa);
field_randomize(&crand, &aa);
q448_randomize(&crand, sk);
if (i==0 || i==2) memset(&sk, 0, sizeof(sk));
@@ -704,21 +704,21 @@ int main(int argc, char **argv) {
serialize_extensible(&b, &exta);

ignore_result(precompute_fixed_base_wnaf(wnaft,&exu,5));
linear_combo_var_fixed_vt(&ext,sk,448,tk,448,wnaft,5);
linear_combo_var_fixed_vt(&ext,sk,FIELD_BITS,tk,FIELD_BITS,wnaft,5);
untwist_and_double(&exta,&exv);
serialize_extensible(&c, &exta);
p448_sub(&d,&b,&c);
p448_bias(&d,2);
field_sub(&d,&b,&c);
field_bias(&d,2);
if (!p448_is_zero(&d)){
if (!field_is_zero(&d)){
printf("PreWNAF combo validation failure %d!\n", ++failures);
p448_print("a", &a);
p448_print("A", &aa);
field_print("a", &a);
field_print("A", &aa);
q448_print("s", sk);
q448_print("t", tk);
p448_print("c", &c);
p448_print("b", &b);
field_print("c", &c);
field_print("b", &b);
printf("\n\n");
} else if (good) {
successes ++;


+ 6
- 6
test/test.c View File

@@ -80,16 +80,16 @@ hexprint (
printf("\n");
}

void p448_print (
void field_print (
const char *descr,
const struct p448_t *a
const struct field_t *a
) {
p448_t b;
p448_copy(&b, a);
p448_strong_reduce(&b);
field_t b;
field_copy(&b, a);
field_strong_reduce(&b);
int j;
printf("%s = 0x", descr);
for (j=sizeof(*a)/sizeof(word_t)-1; j>=0; j--) {
for (j=FIELD_WORDS - 1; j>=0; j--) {
printf(PRIxWORD58, b.limb[LIMBPERM(j)]);
}
printf("\n");


+ 3
- 3
test/test.h View File

@@ -2,7 +2,7 @@
#define __GOLDILOCKS_TEST_H__ 1

#include "word.h"
#include "p448.h"
#include "field.h"

int
hexdecode (
@@ -18,9 +18,9 @@ hexprint (
unsigned int nbytes
);
void p448_print (
void field_print (
const char *descr,
const struct p448_t *a
const struct field_t *a
);
void scalar_print (


+ 60
- 65
test/test_arithmetic.c View File

@@ -1,63 +1,63 @@
#include "p448.h"
#include "field.h"
#include "test.h"
#include <gmp.h>
#include <string.h>
#include <stdio.h>

mpz_t mp_p448;
mpz_t mp_field;

static mask_t mpz_to_p448 (
struct p448_t *out,
static mask_t mpz_to_field (
struct field_t *out,
const mpz_t in
) {
uint8_t ser[56];
uint8_t ser[FIELD_BYTES];
mpz_t modded;
memset(ser,0,sizeof(ser));
mpz_init(modded);
mpz_mod(modded, in, mp_p448);
mpz_mod(modded, in, mp_field);
mpz_export(ser, NULL, -1, 1, -1, 0, modded);
mask_t succ = p448_deserialize(out, ser);
mask_t succ = field_deserialize(out, ser);
return succ;
}

static mask_t p448_assert_eq_gmp(
static mask_t field_assert_eq_gmp(
const char *descr,
const struct p448_t *x,
const struct field_t *x,
const mpz_t y,
float lowBound,
float highBound
) {
uint8_t xser[56], yser[56];
uint8_t xser[FIELD_BYTES], yser[FIELD_BYTES];
mpz_t modded;
memset(yser,0,sizeof(yser));
p448_serialize(xser, x);
field_serialize(xser, x);
mpz_init(modded);
mpz_mod(modded, y, mp_p448);
mpz_mod(modded, y, mp_field);
mpz_export(yser, NULL, -1, 1, -1, 0, modded);
unsigned int i;
for (i=0; i<sizeof(*x)/sizeof(x->limb[0]); i++) {
int bits = sizeof(x->limb[0]) * 448 / sizeof(*x);
int radix_bits = sizeof(x->limb[0]) * 448 / sizeof(*x);
word_t yardstick = (i==sizeof(*x)/sizeof(x->limb[0])/2) ?
(1ull<<bits) - 2 : (1ull<<bits) - 1;
(1ull<<radix_bits) - 2 : (1ull<<radix_bits) - 1; // FIELD_MAGIC
if (x->limb[i] < yardstick * lowBound || x->limb[i] > yardstick * highBound) {
youfail();
printf(" P448 limb %d -> " PRIxWORDfull " is out of bounds (%0.2f, %0.2f) for test %s (yardstick = " PRIxWORDfull ")\n",
printf(" Limb %d -> " PRIxWORDfull " is out of bounds (%0.2f, %0.2f) for test %s (yardstick = " PRIxWORDfull ")\n",
i, x->limb[i], lowBound, highBound, descr, yardstick);
break;
}
}
if (memcmp(xser,yser,56)) {
if (memcmp(xser,yser,FIELD_BYTES)) {
youfail();
printf(" Failed arithmetic test %s\n", descr);
p448_print(" p448", x);
printf(" gmp = 0x");
field_print(" goldi", x);
printf(" gmp = 0x");
int j;
for (j=55; j>=0; j--) {
for (j=FIELD_BYTES-1; j>=0; j--) {
printf("%02x", yser[j]);
}
printf("\n");
@@ -73,36 +73,36 @@ static mask_t test_add_sub (
const mpz_t y,
word_t word
) {
struct p448_t xx,yy,tt;
struct field_t xx,yy,tt;
mpz_t t;
mask_t succ = MASK_SUCCESS;
succ = mpz_to_p448(&xx,x);
succ &= mpz_to_p448(&yy,y);
succ = mpz_to_field(&xx,x);
succ &= mpz_to_field(&yy,y);
mpz_init(t);
p448_add(&tt,&xx,&yy);
field_add(&tt,&xx,&yy);
mpz_add(t,x,y);
succ &= p448_assert_eq_gmp("add",&tt,t,0,2.1);
succ &= field_assert_eq_gmp("add",&tt,t,0,2.1);
p448_sub(&tt,&xx,&yy);
p448_bias(&tt,2);
field_sub(&tt,&xx,&yy);
field_bias(&tt,2);
mpz_sub(t,x,y);
succ &= p448_assert_eq_gmp("sub",&tt,t,0,3.1);
succ &= field_assert_eq_gmp("sub",&tt,t,0,3.1);
p448_copy(&tt,&xx);
p448_addw(&tt,word);
field_copy(&tt,&xx);
field_addw(&tt,word);
mpz_add_ui(t,x,word);
succ &= p448_assert_eq_gmp("addw",&tt,t,0,2.1);
succ &= field_assert_eq_gmp("addw",&tt,t,0,2.1);
p448_copy(&tt,&xx);
p448_subw(&tt,word);
p448_bias(&tt,1);
field_copy(&tt,&xx);
field_subw(&tt,word);
field_bias(&tt,1);
mpz_sub_ui(t,x,word);
succ &= p448_assert_eq_gmp("subw",&tt,t,0,2.1);
succ &= field_assert_eq_gmp("subw",&tt,t,0,2.1);
if (!succ) {
p448_print(" x", &xx);
p448_print(" y", &yy);
field_print(" x", &xx);
field_print(" y", &yy);
}
mpz_clear(t);
@@ -115,32 +115,32 @@ static mask_t test_mul_sqr (
const mpz_t y,
word_t word
) {
struct p448_t xx,yy,tt;
struct field_t xx,yy,tt;
mpz_t t;
mask_t succ = MASK_SUCCESS;
succ = mpz_to_p448(&xx,x);
succ &= mpz_to_p448(&yy,y);
succ = mpz_to_field(&xx,x);
succ &= mpz_to_field(&yy,y);
mpz_init(t);
p448_mul(&tt,&xx,&yy);
field_mul(&tt,&xx,&yy);
mpz_mul(t,x,y);
succ &= p448_assert_eq_gmp("mul",&tt,t,0,1.1);
succ &= field_assert_eq_gmp("mul",&tt,t,0,1.1);
p448_mulw(&tt,&xx,word);
field_mulw(&tt,&xx,word);
mpz_mul_ui(t,x,word);
succ &= p448_assert_eq_gmp("mulw",&tt,t,0,1.1);
succ &= field_assert_eq_gmp("mulw",&tt,t,0,1.1);
p448_sqr(&tt,&xx);
field_sqr(&tt,&xx);
mpz_mul(t,x,x);
succ &= p448_assert_eq_gmp("sqrx",&tt,t,0,1.1);
succ &= field_assert_eq_gmp("sqrx",&tt,t,0,1.1);
p448_sqr(&tt,&yy);
field_sqr(&tt,&yy);
mpz_mul(t,y,y);
succ &= p448_assert_eq_gmp("sqy",&tt,t,0,1.1);
succ &= field_assert_eq_gmp("sqy",&tt,t,0,1.1);
if (!succ) {
p448_print(" x", &xx);
p448_print(" y", &yy);
field_print(" x", &xx);
field_print(" y", &yy);
}
mpz_clear(t);
@@ -153,13 +153,8 @@ int test_arithmetic (void) {
gmp_randstate_t state;
gmp_randinit_mt(state);
uint8_t pser[56];
for (j=0; j<56; j++) {
pser[j] = (j==28) ? 0xFE : 0xFF;
}
mpz_init(mp_p448);
mpz_import(mp_p448, 56, -1, 1, -1, 0, pser);
mpz_init(mp_field);
mpz_import(mp_field, FIELD_BYTES, -1, 1, -1, 0, FIELD_MODULUS);
mpz_t x,y;
mpz_init(x);
@@ -167,23 +162,23 @@ int test_arithmetic (void) {
mask_t succ = MASK_SUCCESS;
int bits = sizeof(word_t) * 448 / sizeof(p448_t);
int radix_bits = sizeof(word_t) * FIELD_BITS / sizeof(field_t);
for (j=0; j<ntests; j++) {
if (j<256) {
mpz_set_ui(x,0);
mpz_set_ui(y,0);
mpz_setbit(x,(j%16)*28);
mpz_setbit(y,(j/16)*28);
mpz_setbit(x,(j%16)*28); // FIELD_MAGIC
mpz_setbit(y,(j/16)*28); // FIELD_MAGIC
} else if (j&1) {
mpz_rrandomb(x, state, 448);
mpz_rrandomb(y, state, 448);
mpz_rrandomb(x, state, FIELD_BITS);
mpz_rrandomb(y, state, FIELD_BITS);
} else {
mpz_urandomb(x, state, 448);
mpz_urandomb(y, state, 448);
mpz_urandomb(x, state, FIELD_BITS);
mpz_urandomb(y, state, FIELD_BITS);
}
word_t word = gmp_urandomm_ui (state, 1ull<<bits);
word_t word = gmp_urandomm_ui (state, 1ull<<radix_bits);
succ &= test_add_sub(x,y,word);
succ &= test_mul_sqr(x,y,word);
@@ -193,7 +188,7 @@ int test_arithmetic (void) {
mpz_clear(x);
mpz_clear(y);
mpz_clear(mp_p448);
mpz_clear(mp_field);
gmp_randclear(state);
return succ ? 0 : 1;


+ 26
- 26
test/test_pointops.c View File

@@ -3,7 +3,7 @@
#include <stdio.h>

#include "ec_point.h"
#include "p448.h"
#include "field.h"
#include "crandom.h"


@@ -11,15 +11,15 @@ static void
failprint_ext (
const struct extensible_t *a
) {
struct p448_t zi, scaled;
p448_print(" x", &a->x);
p448_print(" y", &a->y);
p448_print(" z", &a->z);
p448_inverse(&zi, &a->z);
p448_mul(&scaled, &zi, &a->x);
p448_print(" X", &scaled);
p448_mul(&scaled, &zi, &a->y);
p448_print(" Y", &scaled);
struct field_t zi, scaled;
field_print(" x", &a->x);
field_print(" y", &a->y);
field_print(" z", &a->z);
field_inverse(&zi, &a->z);
field_mul(&scaled, &zi, &a->x);
field_print(" X", &scaled);
field_mul(&scaled, &zi, &a->y);
field_print(" Y", &scaled);
printf("\n");
}

@@ -164,10 +164,10 @@ add_double_test (
if (~succ) {
printf(" Bases were:\n");
p448_print(" x1", &base1->x);
p448_print(" y1", &base1->y);
p448_print(" x2", &base2->x);
p448_print(" y2", &base2->y);
field_print(" x1", &base1->x);
field_print(" y1", &base1->y);
field_print(" x2", &base2->x);
field_print(" y2", &base2->y);
}
return succ ? 0 : -1;
@@ -210,18 +210,18 @@ single_twisting_test (
succ = 0;
} /* FUTURE: quadness */
p448_t sera,serb;
field_t sera,serb;
untwist_and_double_and_serialize(&sera,&text);
copy_extensible(&tmpext,&exb);
double_extensible(&tmpext);
serialize_extensible(&serb,&tmpext);
/* check that their (doubled; FUTURE?) serializations are equal */
if (~p448_eq(&sera,&serb)) {
if (~field_eq(&sera,&serb)) {
youfail();
printf(" Different serialization from twist + double ()\n");
p448_print(" t", &sera);
p448_print(" b", &serb);
field_print(" t", &sera);
field_print(" b", &serb);
succ = 0;
}
@@ -241,8 +241,8 @@ single_twisting_test (
if (~succ) {
printf(" Base was:\n");
p448_print(" x", &base->x);
p448_print(" y", &base->y);
field_print(" x", &base->x);
field_print(" y", &base->y);
}
@@ -251,28 +251,28 @@ single_twisting_test (

int test_pointops (void) {
struct affine_t base, pbase;
struct p448_t ser448;
struct field_t serf;
struct crandom_state_t crand;
crandom_init_from_buffer(&crand, "test_pointops random initializer");
int i, ret;
for (i=0; i<1000; i++) {
uint8_t ser[56];
uint8_t ser[FIELD_BYTES];
crandom_generate(&crand, ser, sizeof(ser));
/* TODO: we need a p448 generate, which can return random or pathological. */
mask_t succ = p448_deserialize(&ser448, ser);
/* TODO: we need a field generate, which can return random or pathological. */
mask_t succ = field_deserialize(&serf, ser);
if (!succ) {
youfail();
printf(" Unlikely: fail at p448_deserialize\n");
printf(" Unlikely: fail at field_deserialize\n");
return -1;
}
if (i) {
copy_affine(&pbase, &base);
}
elligator_2s_inject(&base, &ser448);
elligator_2s_inject(&base, &serf);
if (i) {
ret = add_double_test(&base, &pbase);


+ 67
- 64
test/test_scalarmul.c View File

@@ -4,18 +4,20 @@

#include "scalarmul.h"
#include "ec_point.h"
#include "p448.h"
#include "field.h"
#include "crandom.h"

#define STRIDE 7

/* 0 = succeed, 1 = inval, -1 = fail */
static int
single_scalarmul_compatibility_test (
const struct p448_t *base,
const struct field_t *base,
const word_t *scalar,
int nbits
) {
struct tw_extensible_t text, work;
struct p448_t mont, ct, vl, vt;
struct field_t mont, ct, vl, vt;
int ret = 0, i;
mask_t succ, succm;
@@ -29,7 +31,7 @@ single_scalarmul_compatibility_test (
printf(" Deserialize_and_twist_approx succ=%d, montgomery_ladder succ=%d\n",
(int)-succ, (int)-succm);
printf(" nbits = %d\n", nbits);
p448_print(" base", base);
field_print(" base", base);
scalar_print(" scal", scalar, (nbits+WORD_BITS-1)/WORD_BITS);
return -1;
}
@@ -38,10 +40,11 @@ single_scalarmul_compatibility_test (
return 1;
}
struct { int n,t,s; } params[] = {{5,5,18},{3,5,30},{4,4,28},{1,2,224}};
struct { int n,t,s; } params[] = {{5,5,18},{3,5,30},{4,4,28},{1,2,224}}; // FIELD_MAGIC
const int nparams = sizeof(params)/sizeof(params[0]);
struct fixed_base_table_t fbt;
struct p448_t fbout[nparams], wout[6];
const int nsizes = 6;
struct field_t fbout[nparams], wout[nsizes];
memset(&fbt, 0, sizeof(fbt));
memset(&fbout, 0, sizeof(fbout));
memset(&wout, 0, sizeof(wout));
@@ -68,7 +71,7 @@ single_scalarmul_compatibility_test (
}
/* compute using precomp wNAF */
for (i=0; i<=5; i++) {
for (i=0; i<nsizes; i++) {
struct tw_niels_t pre[1<<i];
succ = precompute_fixed_base_wnaf(pre, &text, i);
@@ -85,8 +88,8 @@ single_scalarmul_compatibility_test (
mask_t consistent = MASK_SUCCESS;
if (nbits == 448) {
/* window methods currently only work on 448 bits. */
if (nbits == FIELD_BITS) {
/* window methods currently only work on FIELD_BITS bits. */
copy_tw_extensible(&work, &text);
scalarmul(&work, scalar);
untwist_and_double_and_serialize(&ct, &work);
@@ -101,44 +104,44 @@ single_scalarmul_compatibility_test (
/* check consistency mont vs window */
consistent &= p448_eq(&mont, &ct);
consistent &= p448_eq(&mont, &vl);
consistent &= p448_eq(&mont, &vt);
consistent &= field_eq(&mont, &ct);
consistent &= field_eq(&mont, &vl);
consistent &= field_eq(&mont, &vt);
}
/* check consistency mont vs combs */
for (i=0; i<nparams; i++) {
consistent &= p448_eq(&mont,&fbout[i]);
consistent &= field_eq(&mont,&fbout[i]);
}
/* check consistency mont vs wNAF */
for (i=0; i<6; i++) {
consistent &= p448_eq(&mont,&wout[i]);
for (i=0; i<nsizes; i++) {
consistent &= field_eq(&mont,&wout[i]);
}
/* If inconsistent, complain. */
if (!consistent) {
youfail();
printf(" Failed scalarmul consistency test with nbits=%d.\n",nbits);
p448_print(" base", base);
field_print(" base", base);
scalar_print(" scal", scalar, (nbits+WORD_BITS-1)/WORD_BITS);
p448_print(" mont", &mont);
field_print(" mont", &mont);
for (i=0; i<nparams; i++) {
printf(" With n=%d, t=%d, s=%d:\n", params[i].n, params[i].t, params[i].s);
p448_print(" out ", &fbout[i]);
field_print(" out ", &fbout[i]);
}
for (i=0; i<6; i++) {
for (i=0; i<nsizes; i++) {
printf(" With w=%d:\n",i);
p448_print(" wNAF", &wout[i]);
field_print(" wNAF", &wout[i]);
}
if (nbits == 448) {
p448_print(" ct ", &ct);
p448_print(" vl ", &vl);
p448_print(" vt ", &vt);
if (nbits == FIELD_BITS) {
field_print(" ct ", &ct);
field_print(" vl ", &vl);
field_print(" vt ", &vt);
}
ret = -1;
@@ -149,16 +152,16 @@ single_scalarmul_compatibility_test (

static int
single_linear_combo_test (
const struct p448_t *base1,
const struct field_t *base1,
const word_t *scalar1,
int nbits1,
const struct p448_t *base2,
const struct field_t *base2,
const word_t *scalar2,
int nbits2
) {
struct tw_extensible_t text1, text2, working;
struct tw_pniels_t pn;
struct p448_t result_comb, result_combo, result_wnaf;
struct field_t result_comb, result_combo, result_wnaf;
mask_t succ =
deserialize_and_twist_approx(&text1, &sqrt_d_minus_1, base1)
@@ -170,8 +173,8 @@ single_linear_combo_test (
memset(&t1,0,sizeof(t1));
memset(&t2,0,sizeof(t2));
succ = precompute_fixed_base(&t1, &text1, 5, 5, 18, NULL);
succ &= precompute_fixed_base(&t2, &text2, 6, 3, 25, NULL);
succ = precompute_fixed_base(&t1, &text1, 5, 5, 18, NULL); // FIELD_MAGIC
succ &= precompute_fixed_base(&t2, &text2, 6, 3, 25, NULL); // FIELD_MAGIC
succ &= precompute_fixed_base_wnaf(wnaf, &text2, 5);
if (!succ) {
@@ -197,20 +200,20 @@ single_linear_combo_test (
untwist_and_double_and_serialize(&result_comb, &working);
mask_t consistent = MASK_SUCCESS;
consistent &= p448_eq(&result_combo, &result_wnaf);
consistent &= p448_eq(&result_comb, &result_wnaf);
consistent &= field_eq(&result_combo, &result_wnaf);
consistent &= field_eq(&result_comb, &result_wnaf);
if (!succ || !consistent) {
youfail();
printf(" Failed linear combo consistency test with nbits=%d,%d.\n",nbits1,nbits2);

p448_print(" base1", base1);
field_print(" base1", base1);
scalar_print(" scal1", scalar1, (nbits1+WORD_BITS-1)/WORD_BITS);
p448_print(" base2", base2);
field_print(" base2", base2);
scalar_print(" scal2", scalar2, (nbits1+WORD_BITS-1)/WORD_BITS);
p448_print(" combs", &result_comb);
p448_print(" combo", &result_combo);
p448_print(" wNAFs", &result_wnaf);
field_print(" combs", &result_comb);
field_print(" combo", &result_combo);
field_print(" wNAFs", &result_wnaf);
return -1;
}
@@ -223,7 +226,7 @@ single_linear_combo_test (
/* 0 = succeed, 1 = inval, -1 = fail */
static int
single_scalarmul_commutativity_test (
const struct p448_t *base,
const struct field_t *base,
const word_t *scalar1,
int nbits1,
int ned1,
@@ -231,7 +234,7 @@ single_scalarmul_commutativity_test (
int nbits2,
int ned2
) {
struct p448_t m12, m21, tmp1, tmp2;
struct field_t m12, m21, tmp1, tmp2;
mask_t succ12a = montgomery_ladder(&tmp1,base,scalar1,nbits1,ned1);
mask_t succ12b = montgomery_ladder(&m12,&tmp1,scalar2,nbits2,ned2);
@@ -244,9 +247,9 @@ single_scalarmul_commutativity_test (
youfail();
printf(" Failed scalarmul commutativity test with (nbits,ned) = (%d,%d), (%d,%d).\n",
nbits1,ned1,nbits2,ned2);
p448_print(" base", base);
p448_print(" tmp1", &tmp1);
p448_print(" tmp2", &tmp2);
field_print(" base", base);
field_print(" tmp1", &tmp1);
field_print(" tmp2", &tmp2);
scalar_print(" sca1", scalar1, (nbits1+WORD_BITS-1)/WORD_BITS);
scalar_print(" sca2", scalar2, (nbits1+WORD_BITS-1)/WORD_BITS);
printf(" good = ((%d,%d),(%d,%d))\n", (int)-succ12a,
@@ -258,18 +261,18 @@ single_scalarmul_commutativity_test (
return 1;
}
mask_t consistent = p448_eq(&m12,&m21);
mask_t consistent = field_eq(&m12,&m21);
if (consistent) {
return 0;
} else {
youfail();
printf(" Failed scalarmul commutativity test with (nbits,ned) = (%d,%d), (%d,%d).\n",
nbits1,ned1,nbits2,ned2);
p448_print(" base", base);
field_print(" base", base);
scalar_print(" sca1", scalar1, (nbits1+WORD_BITS-1)/WORD_BITS);
scalar_print(" sca2", scalar2, (nbits1+WORD_BITS-1)/WORD_BITS);
p448_print(" m12 ", &m12);
p448_print(" m21 ", &m21);
field_print(" m12 ", &m12);
field_print(" m21 ", &m21);
return -1;
}
}
@@ -280,19 +283,19 @@ int test_scalarmul_commutativity (void) {
struct crandom_state_t crand;
crandom_init_from_buffer(&crand, "scalarmul_commutativity_test RNG");
for (i=0; i<=448; i+=7) {
for (j=0; j<=448; j+=7) {
for (i=0; i<=FIELD_BITS; i+=STRIDE) {
for (j=0; j<=FIELD_BITS; j+=STRIDE) {
got = 0;
for (k=0; k<128 && !got; k++) {
uint8_t ser[56];
word_t scalar1[7], scalar2[7];
uint8_t ser[FIELD_BYTES];
word_t scalar1[SCALAR_WORDS], scalar2[SCALAR_WORDS];
crandom_generate(&crand, ser, sizeof(ser));
crandom_generate(&crand, (uint8_t *)scalar1, sizeof(scalar1));
crandom_generate(&crand, (uint8_t *)scalar2, sizeof(scalar2));
p448_t base;
mask_t succ = p448_deserialize(&base, ser);
field_t base;
mask_t succ = field_deserialize(&base, ser);
if (!succ) continue;
int ret = single_scalarmul_commutativity_test (&base, scalar1, i, i%3, scalar2, j, j%3);
@@ -318,24 +321,24 @@ int test_linear_combo (void) {
struct crandom_state_t crand;
crandom_init_from_buffer(&crand, "scalarmul_linear_combos_test RNG");
for (i=0; i<=448; i+=7) {
for (j=0; j<=448; j+=7) {
for (i=0; i<=FIELD_BITS; i+=STRIDE) {
for (j=0; j<=FIELD_BITS; j+=STRIDE) {
got = 0;
for (k=0; k<128 && !got; k++) {
uint8_t ser[56];
word_t scalar1[7], scalar2[7];
uint8_t ser[FIELD_BYTES];
word_t scalar1[SCALAR_WORDS], scalar2[SCALAR_WORDS];
crandom_generate(&crand, (uint8_t *)scalar1, sizeof(scalar1));
crandom_generate(&crand, (uint8_t *)scalar2, sizeof(scalar2));
p448_t base1;
field_t base1;
crandom_generate(&crand, ser, sizeof(ser));
mask_t succ = p448_deserialize(&base1, ser);
mask_t succ = field_deserialize(&base1, ser);
if (!succ) continue;
p448_t base2;
field_t base2;
crandom_generate(&crand, ser, sizeof(ser));
succ = p448_deserialize(&base2, ser);
succ = field_deserialize(&base2, ser);
if (!succ) continue;
int ret = single_linear_combo_test (&base1, scalar1, i, &base2, scalar2, j);
@@ -361,18 +364,18 @@ int test_scalarmul_compatibility (void) {
struct crandom_state_t crand;
crandom_init_from_buffer(&crand, "scalarmul_compatibility_test RNG");
for (i=0; i<=448; i+=7) {
for (i=0; i<=FIELD_BITS; i+=STRIDE) {
for (j=0; j<=20; j++) {
got = 0;
for (k=0; k<128 && !got; k++) {
uint8_t ser[56];
word_t scalar[7];
uint8_t ser[FIELD_BYTES];
word_t scalar[SCALAR_WORDS];
crandom_generate(&crand, ser, sizeof(ser));
crandom_generate(&crand, (uint8_t *)scalar, sizeof(scalar));
p448_t base;
mask_t succ = p448_deserialize(&base, ser);
field_t base;
mask_t succ = field_deserialize(&base, ser);
if (!succ) continue;
int ret = single_scalarmul_compatibility_test (&base, scalar, i);


Loading…
Cancel
Save