Browse Source

change the misleading mul_by_cofactor functions to mul_by_ratio, and create ENCODE_RATIO and DECODE_ratio constants to represent this

master
Michael Hamburg 7 years ago
parent
commit
45eb0e14d3
18 changed files with 356 additions and 199 deletions
  1. +10
    -18
      src/GENERATED/c/curve25519/decaf.c
  2. +14
    -12
      src/GENERATED/c/curve25519/eddsa.c
  3. +10
    -18
      src/GENERATED/c/ed448goldilocks/decaf.c
  4. +14
    -12
      src/GENERATED/c/ed448goldilocks/eddsa.c
  5. +30
    -6
      src/GENERATED/include/decaf/ed255.h
  6. +30
    -6
      src/GENERATED/include/decaf/ed448.h
  7. +19
    -2
      src/GENERATED/include/decaf/point_255.h
  8. +35
    -24
      src/GENERATED/include/decaf/point_255.hxx
  9. +19
    -2
      src/GENERATED/include/decaf/point_448.h
  10. +35
    -24
      src/GENERATED/include/decaf/point_448.hxx
  11. +4
    -0
      src/generator/curve_data.py
  12. +10
    -18
      src/per_curve/decaf.tmpl.c
  13. +10
    -15
      src/per_curve/eddsa.tmpl.c
  14. +30
    -6
      src/per_curve/eddsa.tmpl.h
  15. +19
    -2
      src/per_curve/point.tmpl.h
  16. +35
    -24
      src/per_curve/point.tmpl.hxx
  17. +14
    -6
      test/ristretto.cxx
  18. +18
    -4
      test/test_decaf.cxx

+ 10
- 18
src/GENERATED/c/curve25519/decaf.c View File

@@ -1040,7 +1040,7 @@ decaf_error_t API_NS(direct_scalarmul) (
return succ;
}

void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
void API_NS(point_mul_by_ratio_and_encode_like_eddsa) (
uint8_t enc[DECAF_EDDSA_25519_PUBLIC_BYTES],
const point_t p
) {
@@ -1133,7 +1133,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
}


decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
decaf_error_t API_NS(point_decode_like_eddsa_and_mul_by_ratio) (
point_t p,
const uint8_t enc[DECAF_EDDSA_25519_PUBLIC_BYTES]
) {
@@ -1352,13 +1352,16 @@ void decaf_x25519_generate_key (
decaf_x25519_derive_public_key(out,scalar);
}

void API_NS(point_mul_by_cofactor_and_encode_like_x25519) (
void API_NS(point_mul_by_ratio_and_encode_like_x25519) (
uint8_t out[X_PUBLIC_BYTES],
const point_t p
) {
point_t q;
#if COFACTOR == 8
point_double_internal(q,p,1);
for (unsigned i=1; i<COFACTOR/4; i<<=1) point_double_internal(q,q,1);
#else
API_NS(point_copy)(q,p);
#endif
gf_invert(q->t,q->x,0); /* 1/x */
gf_mul(q->z,q->t,q->y); /* y/x */
gf_sqr(q->y,q->z); /* (y/x)^2 */
@@ -1384,24 +1387,13 @@ void decaf_x25519_derive_public_key (
scalar_t the_scalar;
API_NS(scalar_decode_long)(the_scalar,scalar2,sizeof(scalar2));
/* We're gonna isogenize by 2, so divide by 2.
*
* Why by 2, even though it's a 4-isogeny?
*
* The isogeny map looks like
* Montgomery <-2-> Jacobi <-2-> Edwards
*
* Since the Jacobi base point is the PREimage of the iso to
* the Montgomery curve, and we're going
* Jacobi -> Edwards -> Jacobi -> Montgomery,
* we pick up only a factor of 2 over Jacobi -> Montgomery.
*/
for (unsigned i=1; i<COFACTOR; i<<=1) {
/* Compensate for the encoding ratio */
for (unsigned i=1; i<DECAF_X25519_ENCODE_RATIO; i<<=1) {
API_NS(scalar_halve)(the_scalar,the_scalar);
}
point_t p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),the_scalar);
API_NS(point_mul_by_cofactor_and_encode_like_x25519)(out,p);
API_NS(point_mul_by_ratio_and_encode_like_x25519)(out,p);
API_NS(point_destroy)(p);
}



+ 14
- 12
src/GENERATED/c/curve25519/eddsa.c View File

@@ -31,6 +31,7 @@
#define NO_CONTEXT DECAF_EDDSA_25519_SUPPORTS_CONTEXTLESS_SIGS
#define EDDSA_USE_SIGMA_ISOGENY 1
#define COFACTOR 8
#define EDDSA_PREHASH_BYTES 64

#if NO_CONTEXT
const uint8_t NO_CONTEXT_POINTS_HERE = 0;
@@ -41,7 +42,7 @@ const uint8_t * const DECAF_ED25519_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
* Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d,
* its base point is twice ours.
*/
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY)
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) /* TODO: remove */

static void clamp (
uint8_t secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES]
@@ -128,14 +129,14 @@ void decaf_ed25519_derive_public_key (
* the decaf base point is on Etwist_d, and when converted it effectively
* picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1.
*/
for (unsigned int c = EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c=1; c<DECAF_255_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(secret_scalar,secret_scalar);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(pubkey, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(pubkey, p);
/* Cleanup */
API_NS(scalar_destroy)(secret_scalar);
@@ -191,13 +192,13 @@ void decaf_ed25519_sign (
/* Scalarmul to create the nonce-point */
API_NS(scalar_t) nonce_scalar_2;
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar);
for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c = 2; c < DECAF_255_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_destroy)(p);
API_NS(scalar_destroy)(nonce_scalar_2);
}
@@ -237,7 +238,7 @@ void decaf_ed25519_sign_prehash (
const uint8_t *context,
uint8_t context_len
) {
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
decaf_ed25519_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));
@@ -259,10 +260,10 @@ decaf_error_t decaf_ed25519_verify (
uint8_t context_len
) {
API_NS(point_t) pk_point, r_point;
decaf_error_t error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(pk_point,pubkey);
decaf_error_t error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(pk_point,pubkey);
if (DECAF_SUCCESS != error) { return error; }
error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(r_point,signature);
error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(r_point,signature);
if (DECAF_SUCCESS != error) { return error; }
API_NS(scalar_t) challenge_scalar;
@@ -287,9 +288,10 @@ decaf_error_t decaf_ed25519_verify (
&signature[DECAF_EDDSA_25519_PUBLIC_BYTES],
DECAF_EDDSA_25519_PRIVATE_BYTES
);
#if EDDSA_BASE_POINT_RATIO == 2
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
#endif
for (unsigned c=1; c<DECAF_255_EDDSA_DECODE_RATIO; c<<=1) {
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
}
/* pk_point = -c(x(P)) + (cx + k)G = kG */
@@ -312,7 +314,7 @@ decaf_error_t decaf_ed25519_verify_prehash (
) {
decaf_error_t ret;
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
decaf_ed25519_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));


+ 10
- 18
src/GENERATED/c/ed448goldilocks/decaf.c View File

@@ -1040,7 +1040,7 @@ decaf_error_t API_NS(direct_scalarmul) (
return succ;
}

void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
void API_NS(point_mul_by_ratio_and_encode_like_eddsa) (
uint8_t enc[DECAF_EDDSA_448_PUBLIC_BYTES],
const point_t p
) {
@@ -1133,7 +1133,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
}


decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
decaf_error_t API_NS(point_decode_like_eddsa_and_mul_by_ratio) (
point_t p,
const uint8_t enc[DECAF_EDDSA_448_PUBLIC_BYTES]
) {
@@ -1352,13 +1352,16 @@ void decaf_x448_generate_key (
decaf_x448_derive_public_key(out,scalar);
}

void API_NS(point_mul_by_cofactor_and_encode_like_x448) (
void API_NS(point_mul_by_ratio_and_encode_like_x448) (
uint8_t out[X_PUBLIC_BYTES],
const point_t p
) {
point_t q;
#if COFACTOR == 8
point_double_internal(q,p,1);
for (unsigned i=1; i<COFACTOR/4; i<<=1) point_double_internal(q,q,1);
#else
API_NS(point_copy)(q,p);
#endif
gf_invert(q->t,q->x,0); /* 1/x */
gf_mul(q->z,q->t,q->y); /* y/x */
gf_sqr(q->y,q->z); /* (y/x)^2 */
@@ -1384,24 +1387,13 @@ void decaf_x448_derive_public_key (
scalar_t the_scalar;
API_NS(scalar_decode_long)(the_scalar,scalar2,sizeof(scalar2));
/* We're gonna isogenize by 2, so divide by 2.
*
* Why by 2, even though it's a 4-isogeny?
*
* The isogeny map looks like
* Montgomery <-2-> Jacobi <-2-> Edwards
*
* Since the Jacobi base point is the PREimage of the iso to
* the Montgomery curve, and we're going
* Jacobi -> Edwards -> Jacobi -> Montgomery,
* we pick up only a factor of 2 over Jacobi -> Montgomery.
*/
for (unsigned i=1; i<COFACTOR; i<<=1) {
/* Compensate for the encoding ratio */
for (unsigned i=1; i<DECAF_X448_ENCODE_RATIO; i<<=1) {
API_NS(scalar_halve)(the_scalar,the_scalar);
}
point_t p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),the_scalar);
API_NS(point_mul_by_cofactor_and_encode_like_x448)(out,p);
API_NS(point_mul_by_ratio_and_encode_like_x448)(out,p);
API_NS(point_destroy)(p);
}



+ 14
- 12
src/GENERATED/c/ed448goldilocks/eddsa.c View File

@@ -31,6 +31,7 @@
#define NO_CONTEXT DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS
#define EDDSA_USE_SIGMA_ISOGENY 0
#define COFACTOR 4
#define EDDSA_PREHASH_BYTES 64

#if NO_CONTEXT
const uint8_t NO_CONTEXT_POINTS_HERE = 0;
@@ -41,7 +42,7 @@ const uint8_t * const DECAF_ED448_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
* Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d,
* its base point is twice ours.
*/
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY)
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) /* TODO: remove */

static void clamp (
uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES]
@@ -128,14 +129,14 @@ void decaf_ed448_derive_public_key (
* the decaf base point is on Etwist_d, and when converted it effectively
* picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1.
*/
for (unsigned int c = EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c=1; c<DECAF_448_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(secret_scalar,secret_scalar);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(pubkey, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(pubkey, p);
/* Cleanup */
API_NS(scalar_destroy)(secret_scalar);
@@ -191,13 +192,13 @@ void decaf_ed448_sign (
/* Scalarmul to create the nonce-point */
API_NS(scalar_t) nonce_scalar_2;
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar);
for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c = 2; c < DECAF_448_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_destroy)(p);
API_NS(scalar_destroy)(nonce_scalar_2);
}
@@ -237,7 +238,7 @@ void decaf_ed448_sign_prehash (
const uint8_t *context,
uint8_t context_len
) {
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
decaf_ed448_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));
@@ -259,10 +260,10 @@ decaf_error_t decaf_ed448_verify (
uint8_t context_len
) {
API_NS(point_t) pk_point, r_point;
decaf_error_t error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(pk_point,pubkey);
decaf_error_t error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(pk_point,pubkey);
if (DECAF_SUCCESS != error) { return error; }
error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(r_point,signature);
error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(r_point,signature);
if (DECAF_SUCCESS != error) { return error; }
API_NS(scalar_t) challenge_scalar;
@@ -287,9 +288,10 @@ decaf_error_t decaf_ed448_verify (
&signature[DECAF_EDDSA_448_PUBLIC_BYTES],
DECAF_EDDSA_448_PRIVATE_BYTES
);
#if EDDSA_BASE_POINT_RATIO == 2
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
#endif
for (unsigned c=1; c<DECAF_448_EDDSA_DECODE_RATIO; c<<=1) {
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
}
/* pk_point = -c(x(P)) + (cx + k)G = kG */
@@ -312,7 +314,7 @@ decaf_error_t decaf_ed448_verify_prehash (
) {
decaf_error_t ret;
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
decaf_ed448_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));


+ 30
- 6
src/GENERATED/include/decaf/ed255.h View File

@@ -42,6 +42,12 @@ extern const uint8_t * const DECAF_ED25519_NO_CONTEXT DECAF_API_VIS;
#define decaf_ed25519_prehash_update decaf_sha512_update
#define decaf_ed25519_prehash_destroy decaf_sha512_destroy

/** EdDSA encoding ratio. */
#define DECAF_255_EDDSA_ENCODE_RATIO 4

/** EdDSA decoding ratio. */
#define DECAF_255_EDDSA_DECODE_RATIO (8 / 4)

/**
* @brief EdDSA key generation. This function uses a different (non-Decaf)
* encoding.
@@ -169,25 +175,43 @@ decaf_error_t decaf_ed25519_verify_prehash (

/**
* @brief EdDSA point encoding. Used internally, exposed externally.
* Multiplies the point by the current cofactor first.
* Multiplies by DECAF_255_EDDSA_ENCODE_RATIO first.
*
* The multiplication is required because the EdDSA encoding represents
* the cofactor information, but the Decaf encoding ignores it (which
* is the whole point). So if you decode from EdDSA and re-encode to
* EdDSA, the cofactor info must get cleared, because the intermediate
* representation doesn't track it.
*
* The way libdecaf handles this is to multiply by
* DECAF_255_EDDSA_DECODE_RATIO when decoding, and by
* DECAF_255_EDDSA_ENCODE_RATIO when encoding. The product of these
* ratios is always exactly the cofactor 8, so the cofactor
* ends up cleared one way or another. But exactly how that shakes
* out depends on the base points specified in RFC 8032.
*
* The upshot is that if you pass the Decaf/Ristretto base point to
* this function, you will get DECAF_255_EDDSA_ENCODE_RATIO times the
* EdDSA base point.
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
void decaf_255_point_mul_by_cofactor_and_encode_like_eddsa (
void decaf_255_point_mul_by_ratio_and_encode_like_eddsa (
uint8_t enc[DECAF_EDDSA_25519_PUBLIC_BYTES],
const decaf_255_point_t p
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;

/**
* @brief EdDSA point decoding. Remember that while points on the
* EdDSA curves have cofactor information, Decaf ignores (quotients
* out) all cofactor information.
* @brief EdDSA point decoding. Multiplies by DECAF_255_EDDSA_DECODE_RATIO,
* and ignores cofactor information.
*
* See notes on decaf_255_point_mul_by_ratio_and_encode_like_eddsa
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
decaf_error_t decaf_255_point_decode_like_eddsa_and_ignore_cofactor (
decaf_error_t decaf_255_point_decode_like_eddsa_and_mul_by_ratio (
decaf_255_point_t p,
const uint8_t enc[DECAF_EDDSA_25519_PUBLIC_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;


+ 30
- 6
src/GENERATED/include/decaf/ed448.h View File

@@ -41,6 +41,12 @@ extern "C" {
#define decaf_ed448_prehash_update decaf_shake256_update
#define decaf_ed448_prehash_destroy decaf_shake256_destroy

/** EdDSA encoding ratio. */
#define DECAF_448_EDDSA_ENCODE_RATIO 4

/** EdDSA decoding ratio. */
#define DECAF_448_EDDSA_DECODE_RATIO (4 / 4)

/**
* @brief EdDSA key generation. This function uses a different (non-Decaf)
* encoding.
@@ -168,25 +174,43 @@ decaf_error_t decaf_ed448_verify_prehash (

/**
* @brief EdDSA point encoding. Used internally, exposed externally.
* Multiplies the point by the current cofactor first.
* Multiplies by DECAF_448_EDDSA_ENCODE_RATIO first.
*
* The multiplication is required because the EdDSA encoding represents
* the cofactor information, but the Decaf encoding ignores it (which
* is the whole point). So if you decode from EdDSA and re-encode to
* EdDSA, the cofactor info must get cleared, because the intermediate
* representation doesn't track it.
*
* The way libdecaf handles this is to multiply by
* DECAF_448_EDDSA_DECODE_RATIO when decoding, and by
* DECAF_448_EDDSA_ENCODE_RATIO when encoding. The product of these
* ratios is always exactly the cofactor 4, so the cofactor
* ends up cleared one way or another. But exactly how that shakes
* out depends on the base points specified in RFC 8032.
*
* The upshot is that if you pass the Decaf/Ristretto base point to
* this function, you will get DECAF_448_EDDSA_ENCODE_RATIO times the
* EdDSA base point.
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
void decaf_448_point_mul_by_cofactor_and_encode_like_eddsa (
void decaf_448_point_mul_by_ratio_and_encode_like_eddsa (
uint8_t enc[DECAF_EDDSA_448_PUBLIC_BYTES],
const decaf_448_point_t p
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;

/**
* @brief EdDSA point decoding. Remember that while points on the
* EdDSA curves have cofactor information, Decaf ignores (quotients
* out) all cofactor information.
* @brief EdDSA point decoding. Multiplies by DECAF_448_EDDSA_DECODE_RATIO,
* and ignores cofactor information.
*
* See notes on decaf_448_point_mul_by_ratio_and_encode_like_eddsa
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
decaf_error_t decaf_448_point_decode_like_eddsa_and_ignore_cofactor (
decaf_error_t decaf_448_point_decode_like_eddsa_and_mul_by_ratio (
decaf_448_point_t p,
const uint8_t enc[DECAF_EDDSA_448_PUBLIC_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;


+ 19
- 2
src/GENERATED/include/decaf/point_255.h View File

@@ -55,6 +55,9 @@ typedef struct gf_25519_s {
/** The cofactor the curve would have, if we hadn't removed it */
#define DECAF_255_REMOVED_COFACTOR 8

/** X25519 encoding ratio. */
#define DECAF_X25519_ENCODE_RATIO 4

/** Number of bytes in an x25519 public key */
#define DECAF_X25519_PUBLIC_BYTES 32

@@ -401,12 +404,26 @@ decaf_error_t decaf_x25519 (
) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE;

/**
* @brief Multiply a point by the cofactor, then encode it like RFC 7748
* @brief Multiply a point by DECAF_X25519_ENCODE_RATIO,
* then encode it like RFC 7748.
*
* This function is mainly used internally, but is exported in case
* it will be useful.
*
* The ratio is necessary because the internal representation doesn't
* track the cofactor information, so on output we must clear the cofactor.
* This would multiply by the cofactor, but in fact internally libdecaf's
* points are always even, so it multiplies by half the cofactor instead.
*
* As it happens, this aligns with the base point definitions; that is,
* if you pass the Decaf/Ristretto base point to this function, the result
* will be DECAF_X25519_ENCODE_RATIO times the X25519
* base point.
*
* @param [out] out The scaled and encoded point.
* @param [in] p The point to be scaled and encoded.
*/
void decaf_255_point_mul_by_cofactor_and_encode_like_x25519 (
void decaf_255_point_mul_by_ratio_and_encode_like_x25519 (
uint8_t out[DECAF_X25519_PUBLIC_BYTES],
const decaf_255_point_t p
) DECAF_API_VIS DECAF_NONNULL;


+ 35
- 24
src/GENERATED/include/decaf/point_255.hxx View File

@@ -64,9 +64,6 @@ static inline int bits() { return 255; }
/** The curve's cofactor (removed, but useful for testing) */
static const int REMOVED_COFACTOR = 8;

/** The curve's cofactor (removed, but useful for testing) */
static const int EDDSA_RATIO = 4;

/** Residue class of field modulus: p == this mod 2*(this-1) */
static const int FIELD_MODULUS_TYPE = 5;

@@ -263,6 +260,15 @@ public:

/** Bytes required for EdDSA encoding */
static const size_t LADDER_BYTES = DECAF_X25519_PUBLIC_BYTES;
/** Ratio due to EdDSA encoding */
static const int EDDSA_ENCODE_RATIO = DECAF_255_EDDSA_ENCODE_RATIO;
/** Ratio due to EdDSA decoding */
static const int EDDSA_DECODE_RATIO = DECAF_255_EDDSA_DECODE_RATIO;
/** Ratio due to ladder decoding */
static const int LADDER_ENCODE_RATIO = DECAF_X25519_ENCODE_RATIO;

/**
* Size of a stegged element.
@@ -348,44 +354,49 @@ public:
* @return DECAF_FAILURE the string was the wrong length, or wasn't the encoding of a point.
* Contents of the point are undefined.
*/
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_ignore_cofactor_noexcept (
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_mul_by_ratio_noexcept (
const FixedBlock<DECAF_EDDSA_25519_PUBLIC_BYTES> &buffer
) DECAF_NOEXCEPT {
return decaf_255_point_decode_like_eddsa_and_ignore_cofactor(p,buffer.data());
return decaf_255_point_decode_like_eddsa_and_mul_by_ratio(p,buffer.data());
}

inline void decode_like_eddsa_and_ignore_cofactor (
/**
* Decode from EDDSA, multiply by EDDSA_DECODE_RATIO, and ignore any
* remaining cofactor information.
* @throw CryptoException if the input point was invalid.
*/
inline void decode_like_eddsa_and_mul_by_ratio(
const FixedBlock<DECAF_EDDSA_25519_PUBLIC_BYTES> &buffer
) /*throw(CryptoException)*/ {
if (DECAF_SUCCESS != decode_like_eddsa_and_ignore_cofactor_noexcept(buffer)) throw(CryptoException());
if (DECAF_SUCCESS != decode_like_eddsa_and_mul_by_ratio_noexcept(buffer)) throw(CryptoException());
}

/** Multiply out cofactor and encode like EdDSA. */
inline SecureBuffer mul_by_cofactor_and_encode_like_eddsa() const {
/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline SecureBuffer mul_by_ratio_and_encode_like_eddsa() const {
SecureBuffer ret(DECAF_EDDSA_25519_PUBLIC_BYTES);
decaf_255_point_mul_by_cofactor_and_encode_like_eddsa(ret.data(),p);
decaf_255_point_mul_by_ratio_and_encode_like_eddsa(ret.data(),p);
return ret;
}

/** Multiply out cofactor and encode like X25519/X448. */
inline SecureBuffer mul_by_cofactor_and_encode_like_ladder() const {
SecureBuffer ret(LADDER_BYTES);
decaf_255_point_mul_by_cofactor_and_encode_like_x25519(ret.data(),p);
return ret;
}

/** Multiply out cofactor and encode like EdDSA. */
inline void mul_by_cofactor_and_encode_like_eddsa(
/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline void mul_by_ratio_and_encode_like_eddsa(
FixedBuffer<DECAF_EDDSA_25519_PUBLIC_BYTES> &out
) const {
decaf_255_point_mul_by_cofactor_and_encode_like_eddsa(out.data(),p);
decaf_255_point_mul_by_ratio_and_encode_like_eddsa(out.data(),p);
}

/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline SecureBuffer mul_by_ratio_and_encode_like_ladder() const {
SecureBuffer ret(LADDER_BYTES);
decaf_255_point_mul_by_ratio_and_encode_like_x25519(ret.data(),p);
return ret;
}

/** Multiply out cofactor and encode like X25519/X448. */
inline void mul_by_cofactor_and_encode_like_ladder(
/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline void mul_by_ratio_and_encode_like_ladder(
FixedBuffer<LADDER_BYTES> &out
) const {
decaf_255_point_mul_by_cofactor_and_encode_like_x25519(out.data(),p);
decaf_255_point_mul_by_ratio_and_encode_like_x25519(out.data(),p);
}

/**


+ 19
- 2
src/GENERATED/include/decaf/point_448.h View File

@@ -55,6 +55,9 @@ typedef struct gf_448_s {
/** The cofactor the curve would have, if we hadn't removed it */
#define DECAF_448_REMOVED_COFACTOR 4

/** X448 encoding ratio. */
#define DECAF_X448_ENCODE_RATIO 2

/** Number of bytes in an x448 public key */
#define DECAF_X448_PUBLIC_BYTES 56

@@ -401,12 +404,26 @@ decaf_error_t decaf_x448 (
) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE;

/**
* @brief Multiply a point by the cofactor, then encode it like RFC 7748
* @brief Multiply a point by DECAF_X448_ENCODE_RATIO,
* then encode it like RFC 7748.
*
* This function is mainly used internally, but is exported in case
* it will be useful.
*
* The ratio is necessary because the internal representation doesn't
* track the cofactor information, so on output we must clear the cofactor.
* This would multiply by the cofactor, but in fact internally libdecaf's
* points are always even, so it multiplies by half the cofactor instead.
*
* As it happens, this aligns with the base point definitions; that is,
* if you pass the Decaf/Ristretto base point to this function, the result
* will be DECAF_X448_ENCODE_RATIO times the X448
* base point.
*
* @param [out] out The scaled and encoded point.
* @param [in] p The point to be scaled and encoded.
*/
void decaf_448_point_mul_by_cofactor_and_encode_like_x448 (
void decaf_448_point_mul_by_ratio_and_encode_like_x448 (
uint8_t out[DECAF_X448_PUBLIC_BYTES],
const decaf_448_point_t p
) DECAF_API_VIS DECAF_NONNULL;


+ 35
- 24
src/GENERATED/include/decaf/point_448.hxx View File

@@ -64,9 +64,6 @@ static inline int bits() { return 448; }
/** The curve's cofactor (removed, but useful for testing) */
static const int REMOVED_COFACTOR = 4;

/** The curve's cofactor (removed, but useful for testing) */
static const int EDDSA_RATIO = 4;

/** Residue class of field modulus: p == this mod 2*(this-1) */
static const int FIELD_MODULUS_TYPE = 3;

@@ -263,6 +260,15 @@ public:

/** Bytes required for EdDSA encoding */
static const size_t LADDER_BYTES = DECAF_X448_PUBLIC_BYTES;
/** Ratio due to EdDSA encoding */
static const int EDDSA_ENCODE_RATIO = DECAF_448_EDDSA_ENCODE_RATIO;
/** Ratio due to EdDSA decoding */
static const int EDDSA_DECODE_RATIO = DECAF_448_EDDSA_DECODE_RATIO;
/** Ratio due to ladder decoding */
static const int LADDER_ENCODE_RATIO = DECAF_X448_ENCODE_RATIO;

/**
* Size of a stegged element.
@@ -348,44 +354,49 @@ public:
* @return DECAF_FAILURE the string was the wrong length, or wasn't the encoding of a point.
* Contents of the point are undefined.
*/
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_ignore_cofactor_noexcept (
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_mul_by_ratio_noexcept (
const FixedBlock<DECAF_EDDSA_448_PUBLIC_BYTES> &buffer
) DECAF_NOEXCEPT {
return decaf_448_point_decode_like_eddsa_and_ignore_cofactor(p,buffer.data());
return decaf_448_point_decode_like_eddsa_and_mul_by_ratio(p,buffer.data());
}

inline void decode_like_eddsa_and_ignore_cofactor (
/**
* Decode from EDDSA, multiply by EDDSA_DECODE_RATIO, and ignore any
* remaining cofactor information.
* @throw CryptoException if the input point was invalid.
*/
inline void decode_like_eddsa_and_mul_by_ratio(
const FixedBlock<DECAF_EDDSA_448_PUBLIC_BYTES> &buffer
) /*throw(CryptoException)*/ {
if (DECAF_SUCCESS != decode_like_eddsa_and_ignore_cofactor_noexcept(buffer)) throw(CryptoException());
if (DECAF_SUCCESS != decode_like_eddsa_and_mul_by_ratio_noexcept(buffer)) throw(CryptoException());
}

/** Multiply out cofactor and encode like EdDSA. */
inline SecureBuffer mul_by_cofactor_and_encode_like_eddsa() const {
/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline SecureBuffer mul_by_ratio_and_encode_like_eddsa() const {
SecureBuffer ret(DECAF_EDDSA_448_PUBLIC_BYTES);
decaf_448_point_mul_by_cofactor_and_encode_like_eddsa(ret.data(),p);
decaf_448_point_mul_by_ratio_and_encode_like_eddsa(ret.data(),p);
return ret;
}

/** Multiply out cofactor and encode like X25519/X448. */
inline SecureBuffer mul_by_cofactor_and_encode_like_ladder() const {
SecureBuffer ret(LADDER_BYTES);
decaf_448_point_mul_by_cofactor_and_encode_like_x448(ret.data(),p);
return ret;
}

/** Multiply out cofactor and encode like EdDSA. */
inline void mul_by_cofactor_and_encode_like_eddsa(
/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline void mul_by_ratio_and_encode_like_eddsa(
FixedBuffer<DECAF_EDDSA_448_PUBLIC_BYTES> &out
) const {
decaf_448_point_mul_by_cofactor_and_encode_like_eddsa(out.data(),p);
decaf_448_point_mul_by_ratio_and_encode_like_eddsa(out.data(),p);
}

/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline SecureBuffer mul_by_ratio_and_encode_like_ladder() const {
SecureBuffer ret(LADDER_BYTES);
decaf_448_point_mul_by_ratio_and_encode_like_x448(ret.data(),p);
return ret;
}

/** Multiply out cofactor and encode like X25519/X448. */
inline void mul_by_cofactor_and_encode_like_ladder(
/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline void mul_by_ratio_and_encode_like_ladder(
FixedBuffer<LADDER_BYTES> &out
) const {
decaf_448_point_mul_by_cofactor_and_encode_like_x448(out.data(),p);
decaf_448_point_mul_by_ratio_and_encode_like_x448(out.data(),p);
}

/**


+ 4
- 0
src/generator/curve_data.py View File

@@ -33,6 +33,8 @@ curve_data = {
"trace": -0xa6f7cef517bce6b2c09318d2e7ae9f7a,
"mont_base": 9,
"rist_base": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"eddsa_encode_ratio": 4,
"x_encode_ratio": 4,
"combs":comb_config(3,5,17),
"wnaf":wnaf_config(5,3),
@@ -44,6 +46,8 @@ curve_data = {
"eddsa_sigma_iso": 1
},
"ed448goldilocks" : {
"eddsa_encode_ratio": 4,
"x_encode_ratio": 2,
"altname": None,
"name" : "Ed448-Goldilocks",
"cofactor" : 4,


+ 10
- 18
src/per_curve/decaf.tmpl.c View File

@@ -1029,7 +1029,7 @@ decaf_error_t API_NS(direct_scalarmul) (
return succ;
}

void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
void API_NS(point_mul_by_ratio_and_encode_like_eddsa) (
uint8_t enc[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
const point_t p
) {
@@ -1122,7 +1122,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
}


decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
decaf_error_t API_NS(point_decode_like_eddsa_and_mul_by_ratio) (
point_t p,
const uint8_t enc[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES]
) {
@@ -1341,13 +1341,16 @@ void decaf_x$(gf_shortname)_generate_key (
decaf_x$(gf_shortname)_derive_public_key(out,scalar);
}

void API_NS(point_mul_by_cofactor_and_encode_like_x$(gf_shortname)) (
void API_NS(point_mul_by_ratio_and_encode_like_x$(gf_shortname)) (
uint8_t out[X_PUBLIC_BYTES],
const point_t p
) {
point_t q;
#if COFACTOR == 8
point_double_internal(q,p,1);
for (unsigned i=1; i<COFACTOR/4; i<<=1) point_double_internal(q,q,1);
#else
API_NS(point_copy)(q,p);
#endif
gf_invert(q->t,q->x,0); /* 1/x */
gf_mul(q->z,q->t,q->y); /* y/x */
gf_sqr(q->y,q->z); /* (y/x)^2 */
@@ -1373,24 +1376,13 @@ void decaf_x$(gf_shortname)_derive_public_key (
scalar_t the_scalar;
API_NS(scalar_decode_long)(the_scalar,scalar2,sizeof(scalar2));
/* We're gonna isogenize by 2, so divide by 2.
*
* Why by 2, even though it's a 4-isogeny?
*
* The isogeny map looks like
* Montgomery <-2-> Jacobi <-2-> Edwards
*
* Since the Jacobi base point is the PREimage of the iso to
* the Montgomery curve, and we're going
* Jacobi -> Edwards -> Jacobi -> Montgomery,
* we pick up only a factor of 2 over Jacobi -> Montgomery.
*/
for (unsigned i=1; i<COFACTOR; i<<=1) {
/* Compensate for the encoding ratio */
for (unsigned i=1; i<DECAF_X$(gf_shortname)_ENCODE_RATIO; i<<=1) {
API_NS(scalar_halve)(the_scalar,the_scalar);
}
point_t p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),the_scalar);
API_NS(point_mul_by_cofactor_and_encode_like_x$(gf_shortname))(out,p);
API_NS(point_mul_by_ratio_and_encode_like_x$(gf_shortname))(out,p);
API_NS(point_destroy)(p);
}



+ 10
- 15
src/per_curve/eddsa.tmpl.c View File

@@ -29,12 +29,6 @@ const uint8_t NO_CONTEXT_POINTS_HERE = 0;
const uint8_t * const DECAF_ED$(gf_shortname)_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
#endif

/* EDDSA_BASE_POINT_RATIO = 1 or 2
* Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d,
* its base point is twice ours.
*/
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY)

static void clamp (
uint8_t secret_scalar_ser[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES]
) {
@@ -120,14 +114,14 @@ void decaf_ed$(gf_shortname)_derive_public_key (
* the decaf base point is on Etwist_d, and when converted it effectively
* picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1.
*/
for (unsigned int c = EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c=1; c<$(C_NS)_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(secret_scalar,secret_scalar);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(pubkey, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(pubkey, p);
/* Cleanup */
API_NS(scalar_destroy)(secret_scalar);
@@ -183,13 +177,13 @@ void decaf_ed$(gf_shortname)_sign (
/* Scalarmul to create the nonce-point */
API_NS(scalar_t) nonce_scalar_2;
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar);
for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c = 2; c < $(C_NS)_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_destroy)(p);
API_NS(scalar_destroy)(nonce_scalar_2);
}
@@ -251,10 +245,10 @@ decaf_error_t decaf_ed$(gf_shortname)_verify (
uint8_t context_len
) {
API_NS(point_t) pk_point, r_point;
decaf_error_t error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(pk_point,pubkey);
decaf_error_t error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(pk_point,pubkey);
if (DECAF_SUCCESS != error) { return error; }
error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(r_point,signature);
error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(r_point,signature);
if (DECAF_SUCCESS != error) { return error; }
API_NS(scalar_t) challenge_scalar;
@@ -279,9 +273,10 @@ decaf_error_t decaf_ed$(gf_shortname)_verify (
&signature[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES
);
#if EDDSA_BASE_POINT_RATIO == 2
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
#endif
for (unsigned c=1; c<$(C_NS)_EDDSA_DECODE_RATIO; c<<=1) {
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
}
/* pk_point = -c(x(P)) + (cx + k)G = kG */


+ 30
- 6
src/per_curve/eddsa.tmpl.h View File

@@ -26,6 +26,12 @@ $("extern const uint8_t * const DECAF_ED" + gf_shortname + "_NO_CONTEXT DECAF_AP
#define decaf_ed$(gf_shortname)_prehash_update decaf_$(eddsa_hash)_update
#define decaf_ed$(gf_shortname)_prehash_destroy decaf_$(eddsa_hash)_destroy

/** EdDSA encoding ratio. */
#define $(C_NS)_EDDSA_ENCODE_RATIO $(eddsa_encode_ratio)

/** EdDSA decoding ratio. */
#define $(C_NS)_EDDSA_DECODE_RATIO ($(cofactor) / $(eddsa_encode_ratio))

/**
* @brief EdDSA key generation. This function uses a different (non-Decaf)
* encoding.
@@ -153,25 +159,43 @@ decaf_error_t decaf_ed$(gf_shortname)_verify_prehash (

/**
* @brief EdDSA point encoding. Used internally, exposed externally.
* Multiplies the point by the current cofactor first.
* Multiplies by $(C_NS)_EDDSA_ENCODE_RATIO first.
*
* The multiplication is required because the EdDSA encoding represents
* the cofactor information, but the Decaf encoding ignores it (which
* is the whole point). So if you decode from EdDSA and re-encode to
* EdDSA, the cofactor info must get cleared, because the intermediate
* representation doesn't track it.
*
* The way libdecaf handles this is to multiply by
* $(C_NS)_EDDSA_DECODE_RATIO when decoding, and by
* $(C_NS)_EDDSA_ENCODE_RATIO when encoding. The product of these
* ratios is always exactly the cofactor $(cofactor), so the cofactor
* ends up cleared one way or another. But exactly how that shakes
* out depends on the base points specified in RFC 8032.
*
* The upshot is that if you pass the Decaf/Ristretto base point to
* this function, you will get $(C_NS)_EDDSA_ENCODE_RATIO times the
* EdDSA base point.
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
void $(c_ns)_point_mul_by_cofactor_and_encode_like_eddsa (
void $(c_ns)_point_mul_by_ratio_and_encode_like_eddsa (
uint8_t enc[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
const $(c_ns)_point_t p
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;

/**
* @brief EdDSA point decoding. Remember that while points on the
* EdDSA curves have cofactor information, Decaf ignores (quotients
* out) all cofactor information.
* @brief EdDSA point decoding. Multiplies by $(C_NS)_EDDSA_DECODE_RATIO,
* and ignores cofactor information.
*
* See notes on $(c_ns)_point_mul_by_ratio_and_encode_like_eddsa
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
decaf_error_t $(c_ns)_point_decode_like_eddsa_and_ignore_cofactor (
decaf_error_t $(c_ns)_point_decode_like_eddsa_and_mul_by_ratio (
$(c_ns)_point_t p,
const uint8_t enc[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;


+ 19
- 2
src/per_curve/point.tmpl.h View File

@@ -40,6 +40,9 @@ typedef struct gf_$(gf_shortname)_s {
/** The cofactor the curve would have, if we hadn't removed it */
#define $(C_NS)_REMOVED_COFACTOR $(cofactor)

/** X$(gf_shortname) encoding ratio. */
#define DECAF_X$(gf_shortname)_ENCODE_RATIO $(x_encode_ratio)

/** Number of bytes in an x$(gf_shortname) public key */
#define DECAF_X$(gf_shortname)_PUBLIC_BYTES $((gf_bits-1)//8 + 1)

@@ -386,12 +389,26 @@ decaf_error_t decaf_x$(gf_shortname) (
) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE;

/**
* @brief Multiply a point by the cofactor, then encode it like RFC 7748
* @brief Multiply a point by DECAF_X$(gf_shortname)_ENCODE_RATIO,
* then encode it like RFC 7748.
*
* This function is mainly used internally, but is exported in case
* it will be useful.
*
* The ratio is necessary because the internal representation doesn't
* track the cofactor information, so on output we must clear the cofactor.
* This would multiply by the cofactor, but in fact internally libdecaf's
* points are always even, so it multiplies by half the cofactor instead.
*
* As it happens, this aligns with the base point definitions; that is,
* if you pass the Decaf/Ristretto base point to this function, the result
* will be DECAF_X$(gf_shortname)_ENCODE_RATIO times the X$(gf_shortname)
* base point.
*
* @param [out] out The scaled and encoded point.
* @param [in] p The point to be scaled and encoded.
*/
void $(c_ns)_point_mul_by_cofactor_and_encode_like_x$(gf_shortname) (
void $(c_ns)_point_mul_by_ratio_and_encode_like_x$(gf_shortname) (
uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES],
const $(c_ns)_point_t p
) DECAF_API_VIS DECAF_NONNULL;


+ 35
- 24
src/per_curve/point.tmpl.hxx View File

@@ -51,9 +51,6 @@ static inline int bits() { return $(gf_bits); }
/** The curve's cofactor (removed, but useful for testing) */
static const int REMOVED_COFACTOR = $(cofactor);

/** The curve's cofactor (removed, but useful for testing) */
static const int EDDSA_RATIO = $(cofactor/2 if eddsa_sigma_iso else cofactor);

/** Residue class of field modulus: p == this mod 2*(this-1) */
static const int FIELD_MODULUS_TYPE = $(modulus &~ (modulus-3));

@@ -250,6 +247,15 @@ public:

/** Bytes required for EdDSA encoding */
static const size_t LADDER_BYTES = DECAF_X$(gf_shortname)_PUBLIC_BYTES;
/** Ratio due to EdDSA encoding */
static const int EDDSA_ENCODE_RATIO = $(C_NS)_EDDSA_ENCODE_RATIO;
/** Ratio due to EdDSA decoding */
static const int EDDSA_DECODE_RATIO = $(C_NS)_EDDSA_DECODE_RATIO;
/** Ratio due to ladder decoding */
static const int LADDER_ENCODE_RATIO = DECAF_X$(gf_shortname)_ENCODE_RATIO;

/**
* Size of a stegged element.
@@ -335,44 +341,49 @@ public:
* @return DECAF_FAILURE the string was the wrong length, or wasn't the encoding of a point.
* Contents of the point are undefined.
*/
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_ignore_cofactor_noexcept (
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_mul_by_ratio_noexcept (
const FixedBlock<DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES> &buffer
) DECAF_NOEXCEPT {
return $(c_ns)_point_decode_like_eddsa_and_ignore_cofactor(p,buffer.data());
return $(c_ns)_point_decode_like_eddsa_and_mul_by_ratio(p,buffer.data());
}

inline void decode_like_eddsa_and_ignore_cofactor (
/**
* Decode from EDDSA, multiply by EDDSA_DECODE_RATIO, and ignore any
* remaining cofactor information.
* @throw CryptoException if the input point was invalid.
*/
inline void decode_like_eddsa_and_mul_by_ratio(
const FixedBlock<DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES> &buffer
) /*throw(CryptoException)*/ {
if (DECAF_SUCCESS != decode_like_eddsa_and_ignore_cofactor_noexcept(buffer)) throw(CryptoException());
if (DECAF_SUCCESS != decode_like_eddsa_and_mul_by_ratio_noexcept(buffer)) throw(CryptoException());
}

/** Multiply out cofactor and encode like EdDSA. */
inline SecureBuffer mul_by_cofactor_and_encode_like_eddsa() const {
/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline SecureBuffer mul_by_ratio_and_encode_like_eddsa() const {
SecureBuffer ret(DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES);
$(c_ns)_point_mul_by_cofactor_and_encode_like_eddsa(ret.data(),p);
$(c_ns)_point_mul_by_ratio_and_encode_like_eddsa(ret.data(),p);
return ret;
}

/** Multiply out cofactor and encode like X25519/X448. */
inline SecureBuffer mul_by_cofactor_and_encode_like_ladder() const {
SecureBuffer ret(LADDER_BYTES);
$(c_ns)_point_mul_by_cofactor_and_encode_like_x$(gf_shortname)(ret.data(),p);
return ret;
}

/** Multiply out cofactor and encode like EdDSA. */
inline void mul_by_cofactor_and_encode_like_eddsa(
/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline void mul_by_ratio_and_encode_like_eddsa(
FixedBuffer<DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES> &out
) const {
$(c_ns)_point_mul_by_cofactor_and_encode_like_eddsa(out.data(),p);
$(c_ns)_point_mul_by_ratio_and_encode_like_eddsa(out.data(),p);
}

/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline SecureBuffer mul_by_ratio_and_encode_like_ladder() const {
SecureBuffer ret(LADDER_BYTES);
$(c_ns)_point_mul_by_ratio_and_encode_like_x$(gf_shortname)(ret.data(),p);
return ret;
}

/** Multiply out cofactor and encode like X25519/X448. */
inline void mul_by_cofactor_and_encode_like_ladder(
/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline void mul_by_ratio_and_encode_like_ladder(
FixedBuffer<LADDER_BYTES> &out
) const {
$(c_ns)_point_mul_by_cofactor_and_encode_like_x$(gf_shortname)(out.data(),p);
$(c_ns)_point_mul_by_ratio_and_encode_like_x$(gf_shortname)(out.data(),p);
}

/**


+ 14
- 6
test/ristretto.cxx View File

@@ -70,7 +70,7 @@ void usage() {
fprintf(stderr," -D: Display output in EdDSA format (times clearing ratio)\n");
fprintf(stderr," -R: Display raw xyzt\n");
fprintf(stderr," -C: Display output in X[25519|448] format\n");
fprintf(stderr," -H: ... divide by clearing ratio first\n");
fprintf(stderr," -H: ... divide by encoding ratio first\n");
fprintf(stderr,"\n");
fprintf(stderr," Ways to create points:\n");
fprintf(stderr," [hex]: Point from point data as hex\n");
@@ -97,7 +97,7 @@ public:
uint8_t tmp[Group::Point::SER_BYTES];
typename Group::Point a,b;
typename Group::Scalar s;
bool plus=false, empty=true, elligator=false, mul=false, scalar=false,
bool plus=false, empty=true, elligator=false, mul=false, scalar=false, div=false, torque=false,
scalarempty=true, neg=false, einv=false, like_eddsa=false, like_x=false, decoeff=false, raw=false;
if (done || error) return;
for (int i=1; i<g_argc && !error; i++) {
@@ -121,9 +121,14 @@ public:
like_x = true;
} else if (!strcmp(g_argv[i],"-H")) {
decoeff = true;
} else if (!strcmp(g_argv[i],"-T")) {
torque = true;
} else if (!strcmp(g_argv[i],"*")) {
if (elligator || scalar || scalarempty) usage();
if (elligator || scalar || scalarempty || div) usage();
mul = true;
} else if (!strcmp(g_argv[i],"/")) {
if (elligator || scalar || scalarempty || mul) usage();
div = true;
} else if (!strcmp(g_argv[i],"-s")) {
if (elligator || scalar || !scalarempty) usage();
scalar = true;
@@ -156,6 +161,8 @@ public:

if (point) {
if (neg) { b = -b; neg = false; }
if (div) { b /= s; div=false; }
if (torque) { b = b.debugging_torque(); torque=false; }
if (mul) { b *= s; mul=false; }
if (empty) { a = b; empty=false; }
else if (plus) { a += b; plus=false; }
@@ -164,7 +171,6 @@ public:
}
if (!error && !empty) {
if (decoeff) a /= (Group::EDDSA_RATIO);
if (einv) {
uint8_t buffer[Group::Point::HASH_BYTES];
for (int h=0; h<1<<Group::Point::INVERT_ELLIGATOR_WHICH_BITS; h++) {
@@ -179,11 +185,13 @@ public:
printhex((const uint8_t *)&a, sizeof(a));
printf("\n");
} else if (like_eddsa) {
SecureBuffer b = a.mul_by_cofactor_and_encode_like_eddsa();
if (decoeff) a /= (Group::Point::EDDSA_ENCODE_RATIO);
SecureBuffer b = a.mul_by_ratio_and_encode_like_eddsa();
printhex(b.data(),b.size());
printf("\n");
} else if (like_x) {
SecureBuffer b = a.mul_by_cofactor_and_encode_like_ladder();
if (decoeff) a /= (Group::Point::LADDER_ENCODE_RATIO);
SecureBuffer b = a.mul_by_ratio_and_encode_like_ladder();
printhex(b.data(),b.size());
printf("\n");
} else {


+ 18
- 4
test/test_decaf.cxx View File

@@ -415,8 +415,8 @@ static void test_ec() {
q=p;
for (int j=1; j<Group::REMOVED_COFACTOR; j<<=1) q = q.times_two();
decaf_error_t error = r.decode_like_eddsa_and_ignore_cofactor_noexcept(
p.mul_by_cofactor_and_encode_like_eddsa()
decaf_error_t error = r.decode_like_eddsa_and_mul_by_ratio_noexcept(
p.mul_by_ratio_and_encode_like_eddsa()
);
if (error != DECAF_SUCCESS) {
test.fail();
@@ -552,7 +552,6 @@ static void test_eddsa() {
SpongeRng rng(Block("test_eddsa"),SpongeRng::DETERMINISTIC);
for (int i=0; i<NTESTS && test.passing_now; i++) {
typename EdDSA<Group>::PrivateKey priv(rng);
typename EdDSA<Group>::PublicKey pub(priv);
@@ -569,7 +568,22 @@ static void test_eddsa() {
} catch(CryptoException) {
test.fail();
printf(" Signature validation failed on sig %d\n", i);
}
}
/* Test encode_like and torque */
Point p(rng);
SecureBuffer p1 = p.mul_by_ratio_and_encode_like_eddsa();
SecureBuffer p2 = p.debugging_torque().mul_by_ratio_and_encode_like_eddsa();
if (!memeq(p1,p2)) {
test.fail();
printf(" Torque and encode like EdDSA failed\n");
}
SecureBuffer p3 = p.mul_by_ratio_and_encode_like_ladder();
SecureBuffer p4 = p.debugging_torque().mul_by_ratio_and_encode_like_ladder();
if (!memeq(p3,p4)) {
test.fail();
printf(" Torque and encode like ladder failed\n");
}
}
}



Loading…
Cancel
Save