From e84fd3f1fddae0ba6ed4f9885ed9485b2f4f5c92 Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Tue, 3 Mar 2015 16:43:10 -0800 Subject: [PATCH] define experimental direct_scalarmul, which can be implemented as monty ladder (at least for comparison purposes at the beginning) --- include/decaf.h | 27 +++++++++++++++++++++++++++ src/decaf.c | 18 ++++++++++++++++++ src/decaf_fast.c | 19 +++++++++++++++++++ test/test_scalarmul.c | 4 ++++ 4 files changed, 68 insertions(+) diff --git a/include/decaf.h b/include/decaf.h index 93af71b..b3de3ed 100644 --- a/include/decaf.h +++ b/include/decaf.h @@ -324,6 +324,31 @@ void decaf_448_point_scalarmul ( const decaf_448_scalar_t scalar ) API_VIS NONNULL3; +/** + * @brief Multiply a base point by a scalar: scaled = scalar*base. + * This function operates directly on serialized forms. + * + * @warning This function is experimental. It may not be supported + * long-term. + * + * @param [out] scaled The scaled point base*scalar + * @param [in] base The point to be scaled. + * @param [in] scalar The scalar to multiply by. + * @param [in] allow_identity Allow the input to be the identity. + * @param [in] short_circuit Allow a fast return if the input is illegal. + * + * @retval DECAF_SUCCESS The scalarmul succeeded. + * @retval DECAF_FAILURE The scalarmul didn't succeed, because + * base does not represent a point. + */ +decaf_bool_t decaf_448_direct_scalarmul ( + uint8_t scaled[DECAF_448_SER_BYTES], + const uint8_t base[DECAF_448_SER_BYTES], + const decaf_448_scalar_t scalar, + decaf_bool_t allow_identity, + decaf_bool_t short_circuit +) API_VIS NONNULL3 WARN_UNUSED; + /** * @brief Precompute a table for fast scalar multiplication. * Some implementations do not include precomputed points; for @@ -367,7 +392,9 @@ void decaf_448_precomputed_scalarmul ( * @param [in] scalar1 A first scalar to multiply by. * @param [in] base2 A second point to be scaled. * @param [in] scalar2 A second scalar to multiply by. + * * @TODO: test + * @TODO: define vartime/precomp version of this for performance?? */ void decaf_448_point_double_scalarmul ( decaf_448_point_t combo, diff --git a/src/decaf.c b/src/decaf.c index 8a61d22..329ac91 100644 --- a/src/decaf.c +++ b/src/decaf.c @@ -778,6 +778,24 @@ void decaf_448_precompute ( decaf_448_point_copy(a->p[0],b); } +decaf_bool_t decaf_448_direct_scalarmul ( + uint8_t scaled[DECAF_448_SER_BYTES], + const uint8_t base[DECAF_448_SER_BYTES], + const decaf_448_scalar_t scalar, + decaf_bool_t allow_identity, + decaf_bool_t short_circuit +) { + decaf_448_point_t basep; + decaf_bool_t succ = decaf_448_point_decode(basep, base, allow_identity); + /* FIXME: compiler can probably reorder this to something non-consttime even if + * !short_circuit. + */ + if (short_circuit && ~succ) return succ; + decaf_448_point_scalarmul(basep, basep, scalar); + decaf_448_point_encode(scaled, basep); + return succ; +} + void decaf_448_precomputed_scalarmul ( decaf_448_point_t a, const decaf_448_precomputed_s *b, diff --git a/src/decaf_fast.c b/src/decaf_fast.c index a120d4f..f2e8ed4 100644 --- a/src/decaf_fast.c +++ b/src/decaf_fast.c @@ -809,3 +809,22 @@ void decaf_448_precomputed_scalarmul ( ) { decaf_448_point_scalarmul(a,b->p[0],scalar); } + +decaf_bool_t decaf_448_direct_scalarmul ( + uint8_t scaled[DECAF_448_SER_BYTES], + const uint8_t base[DECAF_448_SER_BYTES], + const decaf_448_scalar_t scalar, + decaf_bool_t allow_identity, + decaf_bool_t short_circuit +) { + decaf_448_point_t basep; + decaf_bool_t succ = decaf_448_point_decode(basep, base, allow_identity); + /* FIXME: compiler can probably reorder this to something non-consttime even if + * !short_circuit. + */ + if (short_circuit && ~succ) return succ; + decaf_448_point_scalarmul(basep, basep, scalar); + decaf_448_point_encode(scaled, basep); + return succ; +} + diff --git a/test/test_scalarmul.c b/test/test_scalarmul.c index cfe841c..f6dc199 100644 --- a/test/test_scalarmul.c +++ b/test/test_scalarmul.c @@ -116,6 +116,8 @@ single_scalarmul_compatibility_test ( posix_memalign((void**)&dpre, alignof_decaf_448_precomputed_s, sizeof_decaf_448_precomputed_s); tw_extended_a_t ed; convert_tw_extensible_to_tw_extended(ed, &text); + uint8_t ser4[DECAF_448_SER_BYTES]; + decaf_448_point_encode(ser4, (struct decaf_448_point_s *)ed); decaf_448_point_scalarmul( ed2, (struct decaf_448_point_s *)ed, @@ -142,6 +144,7 @@ single_scalarmul_compatibility_test ( decaf_448_point_encode(ser1, (struct decaf_448_point_s *)ed); decaf_448_point_encode(ser2, ed2); decaf_448_point_encode(ser3, ed3); + (void)decaf_448_direct_scalarmul(ser4, ser4, (struct decaf_448_scalar_s *)scalar, -1, -1); /* check consistency mont vs window */ consistent &= field_eq(mont, ct); @@ -150,6 +153,7 @@ single_scalarmul_compatibility_test ( consistent &= field_eq(mont, sced); consistent &= memcmp(ser1,ser2,sizeof(ser1)) ? 0 : -1; consistent &= memcmp(ser1,ser3,sizeof(ser1)) ? 0 : -1; + consistent &= memcmp(ser1,ser4,sizeof(ser1)) ? 0 : -1; } /* check consistency mont vs combs */