| @@ -324,6 +324,31 @@ void decaf_448_point_scalarmul ( | |||||
| const decaf_448_scalar_t scalar | const decaf_448_scalar_t scalar | ||||
| ) API_VIS NONNULL3; | ) 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. | * @brief Precompute a table for fast scalar multiplication. | ||||
| * Some implementations do not include precomputed points; for | * 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] scalar1 A first scalar to multiply by. | ||||
| * @param [in] base2 A second point to be scaled. | * @param [in] base2 A second point to be scaled. | ||||
| * @param [in] scalar2 A second scalar to multiply by. | * @param [in] scalar2 A second scalar to multiply by. | ||||
| * | |||||
| * @TODO: test | * @TODO: test | ||||
| * @TODO: define vartime/precomp version of this for performance?? | |||||
| */ | */ | ||||
| void decaf_448_point_double_scalarmul ( | void decaf_448_point_double_scalarmul ( | ||||
| decaf_448_point_t combo, | decaf_448_point_t combo, | ||||
| @@ -778,6 +778,24 @@ void decaf_448_precompute ( | |||||
| decaf_448_point_copy(a->p[0],b); | 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 ( | void decaf_448_precomputed_scalarmul ( | ||||
| decaf_448_point_t a, | decaf_448_point_t a, | ||||
| const decaf_448_precomputed_s *b, | const decaf_448_precomputed_s *b, | ||||
| @@ -809,3 +809,22 @@ void decaf_448_precomputed_scalarmul ( | |||||
| ) { | ) { | ||||
| decaf_448_point_scalarmul(a,b->p[0],scalar); | 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; | |||||
| } | |||||
| @@ -116,6 +116,8 @@ single_scalarmul_compatibility_test ( | |||||
| posix_memalign((void**)&dpre, alignof_decaf_448_precomputed_s, sizeof_decaf_448_precomputed_s); | posix_memalign((void**)&dpre, alignof_decaf_448_precomputed_s, sizeof_decaf_448_precomputed_s); | ||||
| 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); | ||||
| uint8_t ser4[DECAF_448_SER_BYTES]; | |||||
| decaf_448_point_encode(ser4, (struct decaf_448_point_s *)ed); | |||||
| decaf_448_point_scalarmul( | decaf_448_point_scalarmul( | ||||
| ed2, | ed2, | ||||
| (struct decaf_448_point_s *)ed, | (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(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); | 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 */ | /* check consistency mont vs window */ | ||||
| consistent &= field_eq(mont, ct); | consistent &= field_eq(mont, ct); | ||||
| @@ -150,6 +153,7 @@ single_scalarmul_compatibility_test ( | |||||
| 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; | consistent &= memcmp(ser1,ser3,sizeof(ser1)) ? 0 : -1; | ||||
| consistent &= memcmp(ser1,ser4,sizeof(ser1)) ? 0 : -1; | |||||
| } | } | ||||
| /* check consistency mont vs combs */ | /* check consistency mont vs combs */ | ||||