Commit b274e35d authored by Mike Hamburg's avatar Mike Hamburg

Add "precomputed" API to decaf. It doesnt actually precompute in the mini...

Add "precomputed" API to decaf.  It doesnt actually precompute in the mini decaf impl, but it passes tests.
parent d280028c
......@@ -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_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. */
typedef struct decaf_448_scalar_s {
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.
* 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. */
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. */
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. */
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.
* 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?
*/
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
extern "C" {
......@@ -300,6 +308,37 @@ void decaf_448_point_scalarmul (
const decaf_448_scalar_t scalar
) 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:
* 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);
/** 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(0x2ec981082b3288),LIMB(0x99fe8607e5237c),
LIMB(0x0e33fbb1fadd1f),LIMB(0xe714f67055eb4a),
......@@ -80,7 +81,9 @@ const decaf_448_point_t decaf_448_point_base = {{
LIMB(0x0d79c0a7729a69),LIMB(0xc18d3f24aebc1c),
LIMB(0x1fbb5389b3fda5),LIMB(0xbb24f674635948),
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 DECAF_448_LIMBS==8
......@@ -698,3 +701,18 @@ decaf_bool_t decaf_448_point_valid (
out &= ~gf_eq(p->z,ZERO);
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);
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;
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);
field_copy(work.x, ed->x);
......@@ -124,9 +136,11 @@ single_scalarmul_compatibility_test (
field_set_ui(work.u, 1);
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(ser2, ed2);
decaf_448_point_encode(ser3, ed3);
/* check consistency mont vs window */
consistent &= field_eq(mont, ct);
......@@ -134,6 +148,7 @@ single_scalarmul_compatibility_test (
consistent &= field_eq(mont, vt);
consistent &= field_eq(mont, sced);
consistent &= memcmp(ser1,ser2,sizeof(ser1)) ? 0 : -1;
consistent &= memcmp(ser1,ser3,sizeof(ser1)) ? 0 : -1;
}
/* check consistency mont vs combs */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment