| @@ -29,6 +29,7 @@ | |||||
| #define NONNULL2 __attribute__((nonnull(1,2))) | #define NONNULL2 __attribute__((nonnull(1,2))) | ||||
| #define NONNULL3 __attribute__((nonnull(1,2,3))) | #define NONNULL3 __attribute__((nonnull(1,2,3))) | ||||
| /** Types of internal words. TODO: ARCH: make 32-bit clean */ | |||||
| typedef uint64_t decaf_word_t, decaf_bool_t; | typedef uint64_t decaf_word_t, decaf_bool_t; | ||||
| /* TODO: prefix all these operations and factor to support multiple curves. */ | /* TODO: prefix all these operations and factor to support multiple curves. */ | ||||
| @@ -49,21 +50,20 @@ typedef struct decaf_point_s { | |||||
| decaf_word_t x[DECAF_LIMBS],y[DECAF_LIMBS],z[DECAF_LIMBS],t[DECAF_LIMBS]; | decaf_word_t x[DECAF_LIMBS],y[DECAF_LIMBS],z[DECAF_LIMBS],t[DECAF_LIMBS]; | ||||
| } decaf_point_t[1]; | } decaf_point_t[1]; | ||||
| /** Scalar is stored packed, because we don't need the speed. */ | |||||
| typedef struct decaf_scalar_s { | typedef struct decaf_scalar_s { | ||||
| decaf_word_t limb[DECAF_SCALAR_LIMBS]; | decaf_word_t limb[DECAF_SCALAR_LIMBS]; | ||||
| } decaf_scalar_t[1]; | } decaf_scalar_t[1]; | ||||
| /** DECAF_TRUE = -1 so that DECAF_TRUE & x = x */ | |||||
| static const decaf_bool_t DECAF_TRUE = -(decaf_bool_t)1, DECAF_FALSE = 0; | static const decaf_bool_t DECAF_TRUE = -(decaf_bool_t)1, DECAF_FALSE = 0; | ||||
| /** NB Success is -1, failure is 0. TODO: see if people would rather the reverse. */ | /** NB Success is -1, failure is 0. TODO: see if people would rather the reverse. */ | ||||
| static const decaf_bool_t DECAF_SUCCESS = -(decaf_bool_t)1 /*DECAF_TRUE*/, | static const decaf_bool_t DECAF_SUCCESS = -(decaf_bool_t)1 /*DECAF_TRUE*/, | ||||
| DECAF_FAILURE = 0 /*DECAF_FALSE*/; | DECAF_FAILURE = 0 /*DECAF_FALSE*/; | ||||
| /** The identity point on the curve. */ | |||||
| const decaf_point_t decaf_identity API_VIS; | |||||
| /** The prime p, for debugging purposes. | /** The prime p, for debugging purposes. | ||||
| * FIXME: 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_scalar_t decaf_scalar_p API_VIS; | const decaf_scalar_t decaf_scalar_p API_VIS; | ||||
| @@ -73,17 +73,22 @@ const decaf_scalar_t decaf_scalar_one API_VIS; | |||||
| /** A scalar equal to 0. */ | /** A scalar equal to 0. */ | ||||
| const decaf_scalar_t decaf_scalar_zero API_VIS; | const decaf_scalar_t decaf_scalar_zero API_VIS; | ||||
| /** An arbitrarily chosen base point on the curve. TODO: define */ | |||||
| const decaf_point_t decaf_basepoint API_VIS; | |||||
| /** The identity point on the curve. */ | |||||
| const decaf_point_t decaf_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_point_t decaf_point_base API_VIS; | |||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| extern "C" { | extern "C" { | ||||
| #endif | #endif | ||||
| /* TODO: scalar invert? */ | |||||
| // TODO: ser, deser, inv?. | |||||
| // FIXME: scalar math is untested, and therefore probably wrong. | |||||
| /** | /** | ||||
| * @brief Read a scalar from wire format or from bytes. | * @brief Read a scalar from wire format or from bytes. | ||||
| * | * | ||||
| @@ -96,7 +101,7 @@ extern "C" { | |||||
| * @param [in] ser Serialized form of a scalar. | * @param [in] ser Serialized form of a scalar. | ||||
| * @param [out] out Deserialized form. | * @param [out] out Deserialized form. | ||||
| */ | */ | ||||
| decaf_bool_t decaf_decode_scalar( | |||||
| decaf_bool_t decaf_scalar_decode ( | |||||
| decaf_scalar_t s, | decaf_scalar_t s, | ||||
| const unsigned char ser[DECAF_SER_BYTES] | const unsigned char ser[DECAF_SER_BYTES] | ||||
| ) API_VIS NONNULL2; | ) API_VIS NONNULL2; | ||||
| @@ -107,7 +112,7 @@ decaf_bool_t decaf_decode_scalar( | |||||
| * @param [out] ser Serialized form of a scalar. | * @param [out] ser Serialized form of a scalar. | ||||
| * @param [in] s Deserialized scalar. | * @param [in] s Deserialized scalar. | ||||
| */ | */ | ||||
| void decaf_encode_scalar( | |||||
| void decaf_scalar_encode ( | |||||
| unsigned char ser[DECAF_SER_BYTES], | unsigned char ser[DECAF_SER_BYTES], | ||||
| const decaf_scalar_t s | const decaf_scalar_t s | ||||
| ) API_VIS NONNULL2; | ) API_VIS NONNULL2; | ||||
| @@ -118,7 +123,7 @@ void decaf_encode_scalar( | |||||
| * @param [in] b Another scalar. | * @param [in] b Another scalar. | ||||
| * @param [out] out a+b. | * @param [out] out a+b. | ||||
| */ | */ | ||||
| void decaf_add_scalars ( | |||||
| void decaf_scalar_add ( | |||||
| decaf_scalar_t out, | decaf_scalar_t out, | ||||
| const decaf_scalar_t a, | const decaf_scalar_t a, | ||||
| const decaf_scalar_t b | const decaf_scalar_t b | ||||
| @@ -131,7 +136,7 @@ void decaf_add_scalars ( | |||||
| * @retval DECAF_TRUE The scalars are equal. | * @retval DECAF_TRUE The scalars are equal. | ||||
| * @retval DECAF_FALSE The scalars are not equal. | * @retval DECAF_FALSE The scalars are not equal. | ||||
| */ | */ | ||||
| decaf_bool_t decaf_eq_scalars ( | |||||
| decaf_bool_t decaf_scalar_eq ( | |||||
| const decaf_scalar_t a, | const decaf_scalar_t a, | ||||
| const decaf_scalar_t b | const decaf_scalar_t b | ||||
| ) API_VIS WARN_UNUSED NONNULL2; | ) API_VIS WARN_UNUSED NONNULL2; | ||||
| @@ -142,7 +147,7 @@ decaf_bool_t decaf_eq_scalars ( | |||||
| * @param [in] b Another scalar. | * @param [in] b Another scalar. | ||||
| * @param [out] out a-b. | * @param [out] out a-b. | ||||
| */ | */ | ||||
| void decaf_sub_scalars ( | |||||
| void decaf_scalar_sub ( | |||||
| decaf_scalar_t out, | decaf_scalar_t out, | ||||
| const decaf_scalar_t a, | const decaf_scalar_t a, | ||||
| const decaf_scalar_t b | const decaf_scalar_t b | ||||
| @@ -154,7 +159,7 @@ void decaf_sub_scalars ( | |||||
| * @param [in] b Another scalar. | * @param [in] b Another scalar. | ||||
| * @param [out] out a*b. | * @param [out] out a*b. | ||||
| */ | */ | ||||
| void decaf_mul_scalars ( | |||||
| void decaf_scalar_mul ( | |||||
| decaf_scalar_t out, | decaf_scalar_t out, | ||||
| const decaf_scalar_t a, | const decaf_scalar_t a, | ||||
| const decaf_scalar_t b | const decaf_scalar_t b | ||||
| @@ -166,7 +171,7 @@ void decaf_mul_scalars ( | |||||
| * @param [out] ser The byte representation of the point. | * @param [out] ser The byte representation of the point. | ||||
| * @param [in] pt The point to encode. | * @param [in] pt The point to encode. | ||||
| */ | */ | ||||
| void decaf_encode ( | |||||
| void decaf_point_encode ( | |||||
| uint8_t ser[DECAF_SER_BYTES], | uint8_t ser[DECAF_SER_BYTES], | ||||
| const decaf_point_t pt | const decaf_point_t pt | ||||
| ) API_VIS NONNULL2; | ) API_VIS NONNULL2; | ||||
| @@ -184,7 +189,7 @@ void decaf_encode ( | |||||
| * @retval DECAF_FAILURE The decoding didn't succeed, because | * @retval DECAF_FAILURE The decoding didn't succeed, because | ||||
| * ser does not represent a point. | * ser does not represent a point. | ||||
| */ | */ | ||||
| decaf_bool_t decaf_decode ( | |||||
| decaf_bool_t decaf_point_decode ( | |||||
| decaf_point_t pt, | decaf_point_t pt, | ||||
| const uint8_t ser[DECAF_SER_BYTES], | const uint8_t ser[DECAF_SER_BYTES], | ||||
| decaf_bool_t allow_identity | decaf_bool_t allow_identity | ||||
| @@ -197,7 +202,7 @@ decaf_bool_t decaf_decode ( | |||||
| * @param [out] a A copy of the point. | * @param [out] a A copy of the point. | ||||
| * @param [in] b Any point. | * @param [in] b Any point. | ||||
| */ | */ | ||||
| void decaf_copy ( | |||||
| void decaf_point_copy ( | |||||
| decaf_point_t a, | decaf_point_t a, | ||||
| const decaf_point_t b | const decaf_point_t b | ||||
| ) API_VIS NONNULL2; | ) API_VIS NONNULL2; | ||||
| @@ -211,7 +216,7 @@ void decaf_copy ( | |||||
| * @retval DECAF_TRUE The points are equal. | * @retval DECAF_TRUE The points are equal. | ||||
| * @retval DECAF_FALSE The points are not equal. | * @retval DECAF_FALSE The points are not equal. | ||||
| */ | */ | ||||
| decaf_bool_t decaf_eq ( | |||||
| decaf_bool_t decaf_point_eq ( | |||||
| const decaf_point_t a, | const decaf_point_t a, | ||||
| const decaf_point_t b | const decaf_point_t b | ||||
| ) API_VIS WARN_UNUSED NONNULL2; | ) API_VIS WARN_UNUSED NONNULL2; | ||||
| @@ -225,7 +230,7 @@ decaf_bool_t decaf_eq ( | |||||
| * @param [in] a An addend. | * @param [in] a An addend. | ||||
| * @param [in] b An addend. | * @param [in] b An addend. | ||||
| */ | */ | ||||
| void decaf_add ( | |||||
| void decaf_point_add ( | |||||
| decaf_point_t sum, | decaf_point_t sum, | ||||
| const decaf_point_t a, | const decaf_point_t a, | ||||
| const decaf_point_t b | const decaf_point_t b | ||||
| @@ -240,7 +245,7 @@ void decaf_add ( | |||||
| * @param [in] a The minuend. | * @param [in] a The minuend. | ||||
| * @param [in] b The subtrahend. | * @param [in] b The subtrahend. | ||||
| */ | */ | ||||
| void decaf_sub ( | |||||
| void decaf_point_sub ( | |||||
| decaf_point_t diff, | decaf_point_t diff, | ||||
| const decaf_point_t a, | const decaf_point_t a, | ||||
| const decaf_point_t b | const decaf_point_t b | ||||
| @@ -252,13 +257,11 @@ void decaf_sub ( | |||||
| * @param [out] scaled The scaled point base*scalar | * @param [out] scaled The scaled point base*scalar | ||||
| * @param [in] base The point to be scaled. | * @param [in] base The point to be scaled. | ||||
| * @param [in] scalar The scalar to multilpy by. | * @param [in] scalar The scalar to multilpy by. | ||||
| * @param [in] scalar_words The number of words in the scalar [TODO] | |||||
| */ | */ | ||||
| void decaf_scalarmul ( | |||||
| void decaf_point_scalarmul ( | |||||
| decaf_point_t scaled, | decaf_point_t scaled, | ||||
| const decaf_point_t base, | const decaf_point_t base, | ||||
| const decaf_word_t *scalar, | |||||
| unsigned int scalar_words | |||||
| const decaf_scalar_t scalar | |||||
| ) API_VIS NONNULL3; | ) API_VIS NONNULL3; | ||||
| /** | /** | ||||
| @@ -268,7 +271,7 @@ void decaf_scalarmul ( | |||||
| * @retval DECAF_TRUE The point is valid. | * @retval DECAF_TRUE The point is valid. | ||||
| * @retval DECAF_FALSE The point is invalid. | * @retval DECAF_FALSE The point is invalid. | ||||
| */ | */ | ||||
| decaf_bool_t decaf_valid ( | |||||
| decaf_bool_t decaf_point_valid ( | |||||
| const decaf_point_t toTest | const decaf_point_t toTest | ||||
| ) API_VIS WARN_UNUSED NONNULL1; | ) API_VIS WARN_UNUSED NONNULL1; | ||||
| @@ -299,7 +302,7 @@ decaf_bool_t decaf_valid ( | |||||
| * @param [in] hashed_data Output of some hash function. | * @param [in] hashed_data Output of some hash function. | ||||
| * @param [out] pt The data hashed to the curve. | * @param [out] pt The data hashed to the curve. | ||||
| */ | */ | ||||
| void decaf_nonuniform_map_to_curve ( | |||||
| void decaf_point_from_hash_nonuniform ( | |||||
| decaf_point_t pt, | decaf_point_t pt, | ||||
| const unsigned char hashed_data[DECAF_SER_BYTES] | const unsigned char hashed_data[DECAF_SER_BYTES] | ||||
| ) API_VIS NONNULL2; | ) API_VIS NONNULL2; | ||||
| @@ -307,18 +310,21 @@ void decaf_nonuniform_map_to_curve ( | |||||
| /** | /** | ||||
| * @brief Indifferentiable hash function encoding to curve. | * @brief Indifferentiable hash function encoding to curve. | ||||
| * | * | ||||
| * Equivalent to calling decaf_nonuniform_map_to_curve twice and adding. | |||||
| * Equivalent to calling decaf_point_from_hash_nonuniform twice and adding. | |||||
| * | * | ||||
| * @param [in] hashed_data Output of some hash function. | * @param [in] hashed_data Output of some hash function. | ||||
| * @param [out] pt The data hashed to the curve. | * @param [out] pt The data hashed to the curve. | ||||
| */ | */ | ||||
| void decaf_uniform_map_to_curve ( | |||||
| void decaf_point_from_hash_uniform ( | |||||
| decaf_point_t pt, | decaf_point_t pt, | ||||
| const unsigned char hashed_data[2*DECAF_SER_BYTES] | const unsigned char hashed_data[2*DECAF_SER_BYTES] | ||||
| ) API_VIS NONNULL2; | ) API_VIS NONNULL2; | ||||
| /* TODO: functions to invert point_from_hash?? */ | |||||
| #undef API_VIS | #undef API_VIS | ||||
| #undef WARN_UNUSED | #undef WARN_UNUSED | ||||
| #undef NONNULL1 | |||||
| #undef NONNULL2 | #undef NONNULL2 | ||||
| #undef NONNULL3 | #undef NONNULL3 | ||||
| @@ -279,7 +279,7 @@ sv decaf_montmul ( | |||||
| decaf_subx(out, accum, p, p, hi_carry); | decaf_subx(out, accum, p, p, hi_carry); | ||||
| } | } | ||||
| void decaf_mul_scalars ( | |||||
| void decaf_scalar_mul ( | |||||
| decaf_scalar_t out, | decaf_scalar_t out, | ||||
| const decaf_scalar_t a, | const decaf_scalar_t a, | ||||
| const decaf_scalar_t b | const decaf_scalar_t b | ||||
| @@ -288,7 +288,7 @@ void decaf_mul_scalars ( | |||||
| decaf_montmul(out,out,decaf_scalar_r2,decaf_scalar_p,DECAF_MONTGOMERY_FACTOR); | decaf_montmul(out,out,decaf_scalar_r2,decaf_scalar_p,DECAF_MONTGOMERY_FACTOR); | ||||
| } | } | ||||
| void decaf_sub_scalars ( | |||||
| void decaf_scalar_sub ( | |||||
| decaf_scalar_t out, | decaf_scalar_t out, | ||||
| const decaf_scalar_t a, | const decaf_scalar_t a, | ||||
| const decaf_scalar_t b | const decaf_scalar_t b | ||||
| @@ -296,7 +296,7 @@ void decaf_sub_scalars ( | |||||
| decaf_subx(out, a->limb, b, decaf_scalar_p, 0); | decaf_subx(out, a->limb, b, decaf_scalar_p, 0); | ||||
| } | } | ||||
| void decaf_add_scalars ( | |||||
| void decaf_scalar_add ( | |||||
| decaf_scalar_t out, | decaf_scalar_t out, | ||||
| const decaf_scalar_t a, | const decaf_scalar_t a, | ||||
| const decaf_scalar_t b | const decaf_scalar_t b | ||||
| @@ -311,7 +311,7 @@ void decaf_add_scalars ( | |||||
| decaf_subx(out, out->limb, decaf_scalar_p, decaf_scalar_p, chain); | decaf_subx(out, out->limb, decaf_scalar_p, decaf_scalar_p, chain); | ||||
| } | } | ||||
| decaf_bool_t decaf_eq_scalars ( | |||||
| decaf_bool_t decaf_scalar_eq ( | |||||
| const decaf_scalar_t a, | const decaf_scalar_t a, | ||||
| const decaf_scalar_t b | const decaf_scalar_t b | ||||
| ) { | ) { | ||||
| @@ -326,9 +326,20 @@ decaf_bool_t decaf_eq_scalars ( | |||||
| /* *** API begins here *** */ | /* *** API begins here *** */ | ||||
| /** identity = (0,1) */ | /** identity = (0,1) */ | ||||
| const decaf_point_t decaf_identity = {{{0},{1},{1},{0}}}; | |||||
| void decaf_encode( unsigned char ser[DECAF_SER_BYTES], const decaf_point_t p ) { | |||||
| const decaf_point_t decaf_point_identity = {{{0},{1},{1},{0}}}; | |||||
| /** base = twist of Goldilocks base point (~,19). FIXME: ARCH */ | |||||
| const decaf_point_t decaf_point_base = {{ | |||||
| { 0xb39a2d57e08c7bull,0xb38639c75ff281ull,0x2ec981082b3288ull,0x99fe8607e5237cull, | |||||
| 0x0e33fbb1fadd1full,0xe714f67055eb4aull,0xc9ae06d64067ddull,0xf7be45054760faull }, | |||||
| { 0xbd8715f551617full,0x8c17fbeca8f5fcull,0xaae0eec209c06full,0xce41ad80cbe6b8ull, | |||||
| 0xdf360b5c828c00ull,0xaf25b6bbb40e3bull,0x8ed37f0ce4ed31ull,0x72a1c3214557b9ull }, | |||||
| { 1 }, | |||||
| { 0x97ca9c8ed8bde9ull,0xf0b780da83304cull,0x0d79c0a7729a69ull,0xc18d3f24aebc1cull, | |||||
| 0x1fbb5389b3fda5ull,0xbb24f674635948ull,0x723a55709a3983ull,0xe1c0107a823dd4ull } | |||||
| }}; | |||||
| void decaf_point_encode( unsigned char ser[DECAF_SER_BYTES], const decaf_point_t p ) { | |||||
| gf a, b, c, d; | gf a, b, c, d; | ||||
| gf_mlw ( a, p->y, 1-EDWARDS_D ); | gf_mlw ( a, p->y, 1-EDWARDS_D ); | ||||
| gf_mul ( c, a, p->t ); | gf_mul ( c, a, p->t ); | ||||
| @@ -380,7 +391,7 @@ static decaf_bool_t gf_deser(gf s, const unsigned char ser[DECAF_SER_BYTES]) { | |||||
| } | } | ||||
| /* Constant-time add or subtract */ | /* Constant-time add or subtract */ | ||||
| sv decaf_add_sub ( | |||||
| sv decaf_point_add_sub ( | |||||
| decaf_point_t p, | decaf_point_t p, | ||||
| const decaf_point_t q, | const decaf_point_t q, | ||||
| const decaf_point_t r, | const decaf_point_t r, | ||||
| @@ -410,7 +421,7 @@ sv decaf_add_sub ( | |||||
| gf_mul ( p->t, b, c ); | gf_mul ( p->t, b, c ); | ||||
| } | } | ||||
| decaf_bool_t decaf_decode ( | |||||
| decaf_bool_t decaf_point_decode ( | |||||
| decaf_point_t p, | decaf_point_t p, | ||||
| const unsigned char ser[DECAF_SER_BYTES], | const unsigned char ser[DECAF_SER_BYTES], | ||||
| decaf_bool_t allow_identity | decaf_bool_t allow_identity | ||||
| @@ -444,16 +455,16 @@ decaf_bool_t decaf_decode ( | |||||
| return succ; | return succ; | ||||
| } | } | ||||
| void decaf_sub(decaf_point_t a, const decaf_point_t b, const decaf_point_t c) { | |||||
| decaf_add_sub(a,b,c,-1); | |||||
| void decaf_point_sub(decaf_point_t a, const decaf_point_t b, const decaf_point_t c) { | |||||
| decaf_point_add_sub(a,b,c,-1); | |||||
| } | } | ||||
| void decaf_add(decaf_point_t a, const decaf_point_t b, const decaf_point_t c) { | |||||
| decaf_add_sub(a,b,c,0); | |||||
| void decaf_point_add(decaf_point_t a, const decaf_point_t b, const decaf_point_t c) { | |||||
| decaf_point_add_sub(a,b,c,0); | |||||
| } | } | ||||
| /* No dedicated point double (PERF) */ | /* No dedicated point double (PERF) */ | ||||
| #define decaf_dbl(a,b) decaf_add(a,b,b) | |||||
| #define decaf_dbl(a,b) decaf_point_add(a,b,b) | |||||
| void decaf_copy ( | void decaf_copy ( | ||||
| decaf_point_t a, | decaf_point_t a, | ||||
| @@ -465,7 +476,7 @@ void decaf_copy ( | |||||
| gf_cpy(a->t, b->t); | gf_cpy(a->t, b->t); | ||||
| } | } | ||||
| decaf_bool_t decaf_decode_scalar( | |||||
| decaf_bool_t decaf_scalar_decode( | |||||
| decaf_scalar_t s, | decaf_scalar_t s, | ||||
| const unsigned char ser[DECAF_SER_BYTES] | const unsigned char ser[DECAF_SER_BYTES] | ||||
| ) { | ) { | ||||
| @@ -483,12 +494,12 @@ decaf_bool_t decaf_decode_scalar( | |||||
| accum = (accum + s->limb[i] - decaf_scalar_p->limb[i]) >> WBITS; | accum = (accum + s->limb[i] - decaf_scalar_p->limb[i]) >> WBITS; | ||||
| } | } | ||||
| //decaf_mul_scalars(s,s,decaf_scalar_one); /* ham-handed reduce */ | |||||
| decaf_scalar_mul(s,s,decaf_scalar_one); /* ham-handed reduce */ | |||||
| return accum; | return accum; | ||||
| } | } | ||||
| void decaf_encode_scalar( | |||||
| void decaf_scalar_encode( | |||||
| unsigned char ser[DECAF_SER_BYTES], | unsigned char ser[DECAF_SER_BYTES], | ||||
| const decaf_scalar_t s | const decaf_scalar_t s | ||||
| ) { | ) { | ||||
| @@ -500,16 +511,11 @@ void decaf_encode_scalar( | |||||
| } | } | ||||
| } | } | ||||
| void decaf_scalarmul ( | |||||
| void decaf_point_scalarmul ( | |||||
| decaf_point_t a, | decaf_point_t a, | ||||
| const decaf_point_t b, | const decaf_point_t b, | ||||
| const decaf_word_t *scalar, | |||||
| unsigned int scalar_words | |||||
| const decaf_scalar_t scalar | |||||
| ) { | ) { | ||||
| if (scalar_words == 0) { | |||||
| decaf_copy(a,decaf_identity); | |||||
| return; | |||||
| } | |||||
| /* w=2 signed window uses about 1.5 adds per bit. | /* w=2 signed window uses about 1.5 adds per bit. | ||||
| * I figured a few extra lines was worth the 25% speedup. | * I figured a few extra lines was worth the 25% speedup. | ||||
| * NB: if adapting this function to scalarmul by a | * NB: if adapting this function to scalarmul by a | ||||
| @@ -518,22 +524,22 @@ void decaf_scalarmul ( | |||||
| decaf_point_t w,b3,tmp; | decaf_point_t w,b3,tmp; | ||||
| decaf_dbl(w,b); | decaf_dbl(w,b); | ||||
| /* b3 = b*3 */ | /* b3 = b*3 */ | ||||
| decaf_add(b3,w,b); | |||||
| decaf_point_add(b3,w,b); | |||||
| int i; | int i; | ||||
| for (i=scalar_words*WBITS-2; i>0; i-=2) { | |||||
| decaf_word_t bits = scalar[i/WBITS]>>(i%WBITS); | |||||
| for (i=DECAF_SCALAR_LIMBS*WBITS-2; i>0; i-=2) { | |||||
| decaf_word_t bits = scalar->limb[i/WBITS]>>(i%WBITS); | |||||
| decaf_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1); | decaf_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1); | ||||
| decaf_dbl(w,w); | decaf_dbl(w,w); | ||||
| decaf_add_sub(w,w,tmp,((bits>>1)&1)-1); | |||||
| decaf_point_add_sub(w,w,tmp,((bits>>1)&1)-1); | |||||
| decaf_dbl(w,w); | decaf_dbl(w,w); | ||||
| } | } | ||||
| decaf_add_sub(w,w,b,((scalar[0]>>1)&1)-1); | |||||
| decaf_point_add_sub(w,w,b,((scalar->limb[0]>>1)&1)-1); | |||||
| /* low bit is special because fo signed window */ | /* low bit is special because fo signed window */ | ||||
| decaf_cond_sel(tmp,b,decaf_identity,-(scalar[0]&1)); | |||||
| decaf_sub(a,w,tmp); | |||||
| decaf_cond_sel(tmp,b,decaf_point_identity,-(scalar->limb[0]&1)); | |||||
| decaf_point_sub(a,w,tmp); | |||||
| } | } | ||||
| decaf_bool_t decaf_eq ( const decaf_point_t p, const decaf_point_t q ) { | |||||
| decaf_bool_t decaf_point_eq ( const decaf_point_t p, const decaf_point_t q ) { | |||||
| /* equality mod 2-torsion compares x/y */ | /* equality mod 2-torsion compares x/y */ | ||||
| gf a, b; | gf a, b; | ||||
| gf_mul ( a, p->y, q->x ); | gf_mul ( a, p->y, q->x ); | ||||
| @@ -543,7 +549,7 @@ decaf_bool_t decaf_eq ( const decaf_point_t p, const decaf_point_t q ) { | |||||
| static const int QUADRATIC_NONRESIDUE = -1; | static const int QUADRATIC_NONRESIDUE = -1; | ||||
| void decaf_nonuniform_map_to_curve ( | |||||
| void decaf_point_from_hash_nonuniform ( | |||||
| decaf_point_t p, | decaf_point_t p, | ||||
| const unsigned char ser[DECAF_SER_BYTES] | const unsigned char ser[DECAF_SER_BYTES] | ||||
| ) { | ) { | ||||
| @@ -583,17 +589,17 @@ void decaf_nonuniform_map_to_curve ( | |||||
| gf_mul(p->t,b,e); | gf_mul(p->t,b,e); | ||||
| } | } | ||||
| void decaf_uniform_map_to_curve ( | |||||
| void decaf_point_from_hash_uniform ( | |||||
| decaf_point_t pt, | decaf_point_t pt, | ||||
| const unsigned char hashed_data[2*DECAF_SER_BYTES] | const unsigned char hashed_data[2*DECAF_SER_BYTES] | ||||
| ) { | ) { | ||||
| decaf_point_t pt2; | decaf_point_t pt2; | ||||
| decaf_nonuniform_map_to_curve(pt,hashed_data); | |||||
| decaf_nonuniform_map_to_curve(pt2,&hashed_data[DECAF_SER_BYTES]); | |||||
| decaf_add(pt,pt,pt2); | |||||
| decaf_point_from_hash_nonuniform(pt,hashed_data); | |||||
| decaf_point_from_hash_nonuniform(pt2,&hashed_data[DECAF_SER_BYTES]); | |||||
| decaf_point_add(pt,pt,pt2); | |||||
| } | } | ||||
| decaf_bool_t decaf_valid ( | |||||
| decaf_bool_t decaf_point_valid ( | |||||
| const decaf_point_t p | const decaf_point_t p | ||||
| ) { | ) { | ||||
| gf a,b,c; | gf a,b,c; | ||||
| @@ -271,7 +271,7 @@ int main(int argc, char **argv) { | |||||
| memset(bsc,0,sizeof(bsc)); | memset(bsc,0,sizeof(bsc)); | ||||
| when = now(); | when = now(); | ||||
| for (i=0; i<nbase*10; i++) { | for (i=0; i<nbase*10; i++) { | ||||
| decaf_mul_scalars(csc,asc,bsc); | |||||
| decaf_scalar_mul(csc,asc,bsc); | |||||
| } | } | ||||
| when = now() - when; | when = now() - when; | ||||
| printf("decaf mulsc: %5.1fns\n", when * 1e9 / i); | printf("decaf mulsc: %5.1fns\n", when * 1e9 / i); | ||||
| @@ -302,7 +302,7 @@ int main(int argc, char **argv) { | |||||
| memset(Dc,0,sizeof(Dc)); | memset(Dc,0,sizeof(Dc)); | ||||
| when = now(); | when = now(); | ||||
| for (i=0; i<nbase*100; i++) { | for (i=0; i<nbase*100; i++) { | ||||
| decaf_add(Da,Db,Dc); | |||||
| decaf_point_add(Da,Db,Dc); | |||||
| } | } | ||||
| when = now() - when; | when = now() - when; | ||||
| printf("dec + dec: %5.1fns\n", when * 1e9 / i); | printf("dec + dec: %5.1fns\n", when * 1e9 / i); | ||||
| @@ -368,7 +368,7 @@ int main(int argc, char **argv) { | |||||
| when = now(); | when = now(); | ||||
| for (i=0; i<nbase/10; i++) { | for (i=0; i<nbase/10; i++) { | ||||
| decaf_scalarmul(Da,Db,sk,sizeof(sk)/sizeof(word_t)); | |||||
| decaf_point_scalarmul(Da,Db,asc); | |||||
| } | } | ||||
| when = now() - when; | when = now() - when; | ||||
| printf("decaf slow: %5.1fµs\n", when * 1e6 / i); | printf("decaf slow: %5.1fµs\n", when * 1e6 / i); | ||||
| @@ -44,7 +44,7 @@ static mask_t mpz_to_scalar ( | |||||
| mpz_init(modded); | mpz_init(modded); | ||||
| mpz_mod(modded, in, mp_scalar_field); | mpz_mod(modded, in, mp_scalar_field); | ||||
| mpz_export(ser, NULL, -1, 1, -1, 0, modded); | mpz_export(ser, NULL, -1, 1, -1, 0, modded); | ||||
| mask_t succ = decaf_decode_scalar(out, ser); | |||||
| mask_t succ = decaf_scalar_decode(out, ser); | |||||
| return succ; | return succ; | ||||
| } | } | ||||
| @@ -62,7 +62,7 @@ static mask_t scalar_assert_eq_gmp( | |||||
| memset(yser,0,sizeof(yser)); | memset(yser,0,sizeof(yser)); | ||||
| decaf_encode_scalar(xser, x); | |||||
| decaf_scalar_encode(xser, x); | |||||
| mpz_init(modded); | mpz_init(modded); | ||||
| mpz_mod(modded, y, mp_scalar_field); | mpz_mod(modded, y, mp_scalar_field); | ||||
| @@ -224,15 +224,15 @@ static mask_t test_scalar ( | |||||
| succ &= mpz_to_scalar(yy,y); | succ &= mpz_to_scalar(yy,y); | ||||
| mpz_init(t); | mpz_init(t); | ||||
| decaf_add_scalars(tt,xx,yy); | |||||
| decaf_scalar_add(tt,xx,yy); | |||||
| mpz_add(t,x,y); | mpz_add(t,x,y); | ||||
| succ &= scalar_assert_eq_gmp("scalar add",xx,yy,tt,x,y,t); | succ &= scalar_assert_eq_gmp("scalar add",xx,yy,tt,x,y,t); | ||||
| decaf_sub_scalars(tt,xx,yy); | |||||
| decaf_scalar_sub(tt,xx,yy); | |||||
| mpz_sub(t,x,y); | mpz_sub(t,x,y); | ||||
| succ &= scalar_assert_eq_gmp("scalar sub",xx,yy,tt,x,y,t); | succ &= scalar_assert_eq_gmp("scalar sub",xx,yy,tt,x,y,t); | ||||
| decaf_mul_scalars(tt,xx,yy); | |||||
| decaf_scalar_mul(tt,xx,yy); | |||||
| mpz_mul(t,x,y); | mpz_mul(t,x,y); | ||||
| succ &= scalar_assert_eq_gmp("scalar mul",xx,yy,tt,x,y,t); | succ &= scalar_assert_eq_gmp("scalar mul",xx,yy,tt,x,y,t); | ||||
| @@ -160,11 +160,11 @@ add_double_test ( | |||||
| decaf_point_t ted3; | decaf_point_t ted3; | ||||
| convert_tw_extensible_to_tw_extended(&ted1, &text1); | convert_tw_extensible_to_tw_extended(&ted1, &text1); | ||||
| convert_tw_extensible_to_tw_extended(&ted2, &text2); | convert_tw_extensible_to_tw_extended(&ted2, &text2); | ||||
| decaf_add(ted3, (struct decaf_point_s*)&ted1, (struct decaf_point_s*)&ted2); | |||||
| decaf_point_add(ted3, (struct decaf_point_s*)&ted1, (struct decaf_point_s*)&ted2); | |||||
| add_tw_extended(&ted1, &ted2); | add_tw_extended(&ted1, &ted2); | ||||
| convert_tw_extensible_to_tw_extended(&ted2, &textb); | convert_tw_extensible_to_tw_extended(&ted2, &textb); | ||||
| if (~decaf_eq_tw_extended(&ted1, &ted2) | ~decaf_eq((struct decaf_point_s*)&ted1, ted3)) { | |||||
| if (~decaf_eq_tw_extended(&ted1, &ted2) | ~decaf_point_eq((struct decaf_point_s*)&ted1, ted3)) { | |||||
| youfail(); | youfail(); | ||||
| succ = 0; | succ = 0; | ||||
| printf(" Tw extended simple compat:\n"); | printf(" Tw extended simple compat:\n"); | ||||
| @@ -359,8 +359,8 @@ int test_decaf_evil (void) { | |||||
| uint8_t ser_de[56], ser_ed[56]; | uint8_t ser_de[56], ser_ed[56]; | ||||
| decaf_point_t pt_dec, pt_dec2; | decaf_point_t pt_dec, pt_dec2; | ||||
| memcpy(pt_dec, pt_ed, sizeof(pt_dec)); | memcpy(pt_dec, pt_ed, sizeof(pt_dec)); | ||||
| decaf_encode(ser_de, pt_dec); | |||||
| mask_t succ_dec = decaf_decode(pt_dec2, ser_de, -1); | |||||
| decaf_point_encode(ser_de, pt_dec); | |||||
| mask_t succ_dec = decaf_point_decode(pt_dec2, ser_de, -1); | |||||
| field_serialize(ser_ed, out_ed); | field_serialize(ser_ed, out_ed); | ||||
| decaf_point_t p,q,m; | decaf_point_t p,q,m; | ||||
| @@ -373,17 +373,17 @@ int test_decaf_evil (void) { | |||||
| field_serialize(oo_base_ser,oo_base); | field_serialize(oo_base_ser,oo_base); | ||||
| field_neg(tmp,base); | field_neg(tmp,base); | ||||
| field_serialize(n_base_ser,tmp); // = -base | field_serialize(n_base_ser,tmp); // = -base | ||||
| decaf_nonuniform_map_to_curve (p,random_input); | |||||
| decaf_nonuniform_map_to_curve (q,oo_base_ser); | |||||
| decaf_nonuniform_map_to_curve (m,n_base_ser); | |||||
| mask_t succ_nur = decaf_valid(p); | |||||
| succ_nur &= decaf_valid(q); | |||||
| succ_nur &= decaf_valid(m); | |||||
| decaf_point_from_hash_nonuniform (p,random_input); | |||||
| decaf_point_from_hash_nonuniform (q,oo_base_ser); | |||||
| decaf_point_from_hash_nonuniform (m,n_base_ser); | |||||
| mask_t succ_nur = decaf_point_valid(p); | |||||
| succ_nur &= decaf_point_valid(q); | |||||
| succ_nur &= decaf_point_valid(m); | |||||
| mask_t eq_neg, eq_pos; | mask_t eq_neg, eq_pos; | ||||
| eq_neg = decaf_eq(m,p); | |||||
| decaf_add(m,p,q); | |||||
| eq_pos = decaf_eq(m,decaf_identity); | |||||
| eq_neg = decaf_point_eq(m,p); | |||||
| decaf_point_add(m,p,q); | |||||
| eq_pos = decaf_point_eq(m,decaf_point_identity); | |||||
| if ((care_should && should != s_m) | if ((care_should && should != s_m) | ||||
| || ~s_base || s_e != s_te || s_m != s_te || s_ed != s_te | || ~s_base || s_e != s_te || s_m != s_te || s_ed != s_te | ||||
| @@ -391,8 +391,8 @@ int test_decaf_evil (void) { | |||||
| || (s_ed && ~field_eq(out_e,out_ed)) | || (s_ed && ~field_eq(out_e,out_ed)) | ||||
| || memcmp(ser_de, ser_ed, 56) | || memcmp(ser_de, ser_ed, 56) | ||||
| || (s_e & ~succ_dec) | || (s_e & ~succ_dec) | ||||
| || (s_e & ~decaf_eq(pt_dec, pt_dec2) | |||||
| || (s_e & ~decaf_valid(pt_dec)) | |||||
| || (s_e & ~decaf_point_eq(pt_dec, pt_dec2) | |||||
| || (s_e & ~decaf_point_valid(pt_dec)) | |||||
| || ~succ_nur | || ~succ_nur | ||||
| || ~eq_neg | || ~eq_neg | ||||
| || ~eq_pos) | || ~eq_pos) | ||||
| @@ -429,6 +429,20 @@ int test_decaf (void) { | |||||
| crandom_init_from_buffer(&crand, "my test_decaf random initializer"); | crandom_init_from_buffer(&crand, "my test_decaf random initializer"); | ||||
| int i, hits = 0, fails = 0; | int i, hits = 0, fails = 0; | ||||
| if (~decaf_point_valid(decaf_point_base)) { | |||||
| youfail(); | |||||
| printf(" Decaf base point invalid\n"); | |||||
| fails++; | |||||
| } | |||||
| if (~decaf_point_valid(decaf_point_identity)) { | |||||
| youfail(); | |||||
| printf(" Decaf identity point invalid\n"); | |||||
| fails++; | |||||
| } | |||||
| for (i=0; i<1000; i++) { | for (i=0; i<1000; i++) { | ||||
| uint8_t ser[FIELD_BYTES]; | uint8_t ser[FIELD_BYTES]; | ||||
| @@ -114,7 +114,7 @@ single_scalarmul_compatibility_test ( | |||||
| decaf_point_t ed2; | decaf_point_t ed2; | ||||
| 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_scalarmul(ed2, (struct decaf_point_s *)ed, scalar, 7); | |||||
| decaf_point_scalarmul(ed2, (struct decaf_point_s *)ed, (struct decaf_scalar_s *)scalar); | |||||
| scalarmul_ed(ed, scalar); | scalarmul_ed(ed, scalar); | ||||
| field_copy(work.x, ed->x); | field_copy(work.x, ed->x); | ||||
| @@ -125,8 +125,8 @@ single_scalarmul_compatibility_test ( | |||||
| 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[(FIELD_BITS+6)/8], ser2[(FIELD_BITS+6)/8]; | ||||
| decaf_encode(ser1, (struct decaf_point_s *)ed); | |||||
| decaf_encode(ser2, ed2); | |||||
| decaf_point_encode(ser1, (struct decaf_point_s *)ed); | |||||
| decaf_point_encode(ser2, ed2); | |||||
| /* check consistency mont vs window */ | /* check consistency mont vs window */ | ||||
| consistent &= field_eq(mont, ct); | consistent &= field_eq(mont, ct); | ||||