Browse Source

Add "precomputed" API to decaf. It doesnt actually precompute in the mini decaf impl, but it passes tests.

master
Mike Hamburg 10 years ago
parent
commit
b274e35d9a
3 changed files with 82 additions and 10 deletions
  1. +44
    -5
      include/decaf.h
  2. +20
    -2
      src/decaf.c
  3. +18
    -3
      test/test_scalarmul.c

+ 44
- 5
include/decaf.h View File

@@ -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.


+ 20
- 2
src/decaf.c View File

@@ -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);
}

+ 18
- 3
test/test_scalarmul.c View File

@@ -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 */


Loading…
Cancel
Save