@@ -63,6 +63,11 @@ typedef struct decaf_448_point_s { | |||||
decaf_word_t x[DECAF_448_LIMBS],y[DECAF_448_LIMBS],z[DECAF_448_LIMBS],t[DECAF_448_LIMBS]; | decaf_word_t x[DECAF_448_LIMBS],y[DECAF_448_LIMBS],z[DECAF_448_LIMBS],t[DECAF_448_LIMBS]; | ||||
} decaf_448_point_t[1]; | } decaf_448_point_t[1]; | ||||
/** Precomputed table based on a point. Can be trivial implementation. */ | |||||
typedef struct decaf_448_precomputed_s { | |||||
decaf_448_point_t p[1]; | |||||
} decaf_448_precomputed_t[1]; | |||||
/** Scalar is stored packed, because we don't need the speed. */ | /** Scalar is stored packed, because we don't need the speed. */ | ||||
typedef struct decaf_448_scalar_s { | typedef struct decaf_448_scalar_s { | ||||
decaf_word_t limb[DECAF_448_SCALAR_LIMBS]; | decaf_word_t limb[DECAF_448_SCALAR_LIMBS]; | ||||
@@ -78,23 +83,26 @@ static const decaf_bool_t DECAF_SUCCESS = -(decaf_bool_t)1 /*DECAF_TRUE*/, | |||||
/** The prime p, for debugging purposes. | /** The prime p, for debugging purposes. | ||||
* TODO: prevent this scalar from actually being used for non-debugging purposes? | * TODO: prevent this scalar from actually being used for non-debugging purposes? | ||||
*/ | */ | ||||
const decaf_448_scalar_t decaf_448_scalar_p API_VIS; | |||||
extern const decaf_448_scalar_t decaf_448_scalar_p API_VIS; | |||||
/** A scalar equal to 1. */ | /** A scalar equal to 1. */ | ||||
const decaf_448_scalar_t decaf_448_scalar_one API_VIS; | |||||
extern const decaf_448_scalar_t decaf_448_scalar_one API_VIS; | |||||
/** A scalar equal to 0. */ | /** A scalar equal to 0. */ | ||||
const decaf_448_scalar_t decaf_448_scalar_zero API_VIS; | |||||
extern const decaf_448_scalar_t decaf_448_scalar_zero API_VIS; | |||||
/** The identity point on the curve. */ | /** The identity point on the curve. */ | ||||
const decaf_448_point_t decaf_448_point_identity API_VIS; | |||||
extern const decaf_448_point_t decaf_448_point_identity API_VIS; | |||||
/** | /** | ||||
* An arbitrarily chosen base point on the curve. | * An arbitrarily chosen base point on the curve. | ||||
* Equal to Ed448-Goldilocks base point defined by DJB, except of course that | * Equal to Ed448-Goldilocks base point defined by DJB, except of course that | ||||
* it's on the twist in this case. TODO: choose a base point with nice encoding? | * it's on the twist in this case. TODO: choose a base point with nice encoding? | ||||
*/ | */ | ||||
const decaf_448_point_t decaf_448_point_base API_VIS; | |||||
extern const struct decaf_448_point_s *decaf_448_point_base API_VIS; | |||||
/** Precomputed table for the base point on the curve. */ | |||||
extern const decaf_448_precomputed_t decaf_448_precomputed_base API_VIS; | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" { | extern "C" { | ||||
@@ -300,6 +308,37 @@ void decaf_448_point_scalarmul ( | |||||
const decaf_448_scalar_t scalar | const decaf_448_scalar_t scalar | ||||
) API_VIS NONNULL3; | ) API_VIS NONNULL3; | ||||
/** | |||||
* @brief Precompute a table for fast scalar multiplication. | |||||
* Some implementations do not include precomputed points; for | |||||
* those implementations, this implementation simply copies the | |||||
* point. | |||||
* | |||||
* @param [out] a A precomputed table of multiples of the point. | |||||
* @param [in] b Any point. | |||||
*/ | |||||
void decaf_448_precompute ( | |||||
decaf_448_precomputed_t a, | |||||
const decaf_448_point_t b | |||||
) API_VIS NONNULL2; | |||||
/** | |||||
* @brief Multiply a precomputed base point by a scalar: | |||||
* scaled = scalar*base. | |||||
* Some implementations do not include precomputed points; for | |||||
* those implementations, this function is the same as | |||||
* decaf_448_point_scalarmul | |||||
* | |||||
* @param [out] scaled The scaled point base*scalar | |||||
* @param [in] base The point to be scaled. | |||||
* @param [in] scalar The scalar to multiply by. | |||||
*/ | |||||
void decaf_448_precomputed_scalarmul ( | |||||
decaf_448_point_t scaled, | |||||
const decaf_448_precomputed_t base, | |||||
const decaf_448_scalar_t scalar | |||||
) API_VIS NONNULL3; | |||||
/** | /** | ||||
* @brief Multiply two base points by two scalars: | * @brief Multiply two base points by two scalars: | ||||
* scaled = scalar1*base1 + scalar2*base2. | * scaled = scalar1*base1 + scalar2*base2. | ||||
@@ -66,7 +66,8 @@ static const decaf_448_scalar_t decaf_448_scalar_r2 = {{{ | |||||
static const decaf_word_t DECAF_MONTGOMERY_FACTOR = (decaf_word_t)(0x3bd440fae918bc5ull); | static const decaf_word_t DECAF_MONTGOMERY_FACTOR = (decaf_word_t)(0x3bd440fae918bc5ull); | ||||
/** base = twist of Goldilocks base point (~,19). */ | /** base = twist of Goldilocks base point (~,19). */ | ||||
const decaf_448_point_t decaf_448_point_base = {{ | |||||
const decaf_448_precomputed_t decaf_448_precomputed_base = {{{{{ | |||||
{ LIMB(0xb39a2d57e08c7b),LIMB(0xb38639c75ff281), | { LIMB(0xb39a2d57e08c7b),LIMB(0xb38639c75ff281), | ||||
LIMB(0x2ec981082b3288),LIMB(0x99fe8607e5237c), | LIMB(0x2ec981082b3288),LIMB(0x99fe8607e5237c), | ||||
LIMB(0x0e33fbb1fadd1f),LIMB(0xe714f67055eb4a), | LIMB(0x0e33fbb1fadd1f),LIMB(0xe714f67055eb4a), | ||||
@@ -80,7 +81,9 @@ const decaf_448_point_t decaf_448_point_base = {{ | |||||
LIMB(0x0d79c0a7729a69),LIMB(0xc18d3f24aebc1c), | LIMB(0x0d79c0a7729a69),LIMB(0xc18d3f24aebc1c), | ||||
LIMB(0x1fbb5389b3fda5),LIMB(0xbb24f674635948), | LIMB(0x1fbb5389b3fda5),LIMB(0xbb24f674635948), | ||||
LIMB(0x723a55709a3983),LIMB(0xe1c0107a823dd4) } | LIMB(0x723a55709a3983),LIMB(0xe1c0107a823dd4) } | ||||
}}; | |||||
}}}}}; | |||||
const struct decaf_448_point_s *decaf_448_point_base = decaf_448_precomputed_base->p[0]; | |||||
#if (defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__)) || defined(DECAF_FORCE_UNROLL) | #if (defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__)) || defined(DECAF_FORCE_UNROLL) | ||||
#if DECAF_448_LIMBS==8 | #if DECAF_448_LIMBS==8 | ||||
@@ -698,3 +701,18 @@ decaf_bool_t decaf_448_point_valid ( | |||||
out &= ~gf_eq(p->z,ZERO); | out &= ~gf_eq(p->z,ZERO); | ||||
return out; | return out; | ||||
} | } | ||||
void decaf_448_precompute ( | |||||
decaf_448_precomputed_t a, | |||||
const decaf_448_point_t b | |||||
) { | |||||
decaf_448_point_copy(a->p[0],b); | |||||
} | |||||
void decaf_448_precomputed_scalarmul ( | |||||
decaf_448_point_t a, | |||||
const decaf_448_precomputed_t b, | |||||
const decaf_448_scalar_t scalar | |||||
) { | |||||
decaf_448_point_scalarmul(a,b->p[0],scalar); | |||||
} |
@@ -111,10 +111,22 @@ single_scalarmul_compatibility_test ( | |||||
scalarmul_vt(&work, scalar, nbits); | scalarmul_vt(&work, scalar, nbits); | ||||
untwist_and_double_and_serialize(vt, &work); | untwist_and_double_and_serialize(vt, &work); | ||||
decaf_448_point_t ed2; | |||||
decaf_448_point_t ed2, ed3; | |||||
decaf_448_precomputed_t dpre; | |||||
tw_extended_a_t ed; | tw_extended_a_t ed; | ||||
convert_tw_extensible_to_tw_extended(ed, &text); | convert_tw_extensible_to_tw_extended(ed, &text); | ||||
decaf_448_point_scalarmul(ed2, (struct decaf_448_point_s *)ed, (struct decaf_448_scalar_s *)scalar); | |||||
decaf_448_point_scalarmul( | |||||
ed2, | |||||
(struct decaf_448_point_s *)ed, | |||||
(struct decaf_448_scalar_s *)scalar | |||||
); | |||||
decaf_448_precompute(dpre, (struct decaf_448_point_s *)ed); | |||||
decaf_448_precomputed_scalarmul( | |||||
ed3, | |||||
dpre, | |||||
(struct decaf_448_scalar_s *)scalar | |||||
); | |||||
scalarmul_ed(ed, scalar); | scalarmul_ed(ed, scalar); | ||||
field_copy(work.x, ed->x); | field_copy(work.x, ed->x); | ||||
@@ -124,9 +136,11 @@ single_scalarmul_compatibility_test ( | |||||
field_set_ui(work.u, 1); | field_set_ui(work.u, 1); | ||||
untwist_and_double_and_serialize(sced, &work); | untwist_and_double_and_serialize(sced, &work); | ||||
uint8_t ser1[(FIELD_BITS+6)/8], ser2[(FIELD_BITS+6)/8]; | |||||
uint8_t ser1[DECAF_448_SER_BYTES], ser2[DECAF_448_SER_BYTES], | |||||
ser3[DECAF_448_SER_BYTES]; | |||||
decaf_448_point_encode(ser1, (struct decaf_448_point_s *)ed); | decaf_448_point_encode(ser1, (struct decaf_448_point_s *)ed); | ||||
decaf_448_point_encode(ser2, ed2); | decaf_448_point_encode(ser2, ed2); | ||||
decaf_448_point_encode(ser3, ed3); | |||||
/* check consistency mont vs window */ | /* check consistency mont vs window */ | ||||
consistent &= field_eq(mont, ct); | consistent &= field_eq(mont, ct); | ||||
@@ -134,6 +148,7 @@ single_scalarmul_compatibility_test ( | |||||
consistent &= field_eq(mont, vt); | consistent &= field_eq(mont, vt); | ||||
consistent &= field_eq(mont, sced); | consistent &= field_eq(mont, sced); | ||||
consistent &= memcmp(ser1,ser2,sizeof(ser1)) ? 0 : -1; | consistent &= memcmp(ser1,ser2,sizeof(ser1)) ? 0 : -1; | ||||
consistent &= memcmp(ser1,ser3,sizeof(ser1)) ? 0 : -1; | |||||
} | } | ||||
/* check consistency mont vs combs */ | /* check consistency mont vs combs */ | ||||