From 1a38c25d9d3e8c22f2fc24322dca53e39d0f0c03 Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Fri, 6 Oct 2017 11:27:28 -0700 Subject: [PATCH] CFRG crypto back to working, just need to do elligator inversion for identity on x25519 --- src/GENERATED/c/curve25519/decaf.c | 51 ++++++++++++------------- src/GENERATED/c/ed448goldilocks/decaf.c | 51 ++++++++++++------------- src/GENERATED/include/decaf/point_255.h | 14 +++++++ src/GENERATED/include/decaf/point_448.h | 14 +++++++ src/per_curve/decaf.tmpl.c | 51 ++++++++++++------------- src/per_curve/point.tmpl.h | 14 +++++++ test/test_decaf.cxx | 17 +++++---- 7 files changed, 124 insertions(+), 88 deletions(-) diff --git a/src/GENERATED/c/curve25519/decaf.c b/src/GENERATED/c/curve25519/decaf.c index 10b6e90..f323186 100644 --- a/src/GENERATED/c/curve25519/decaf.c +++ b/src/GENERATED/c/curve25519/decaf.c @@ -52,12 +52,6 @@ static const gf RISTRETTO_ISOMAGIC = {{{ 0x0fdaa805d40ea, 0x2eb482e57d339, 0x007610274bc58, 0x6510b613dc8ff, 0x786c8905cfaff }}}; -#if COFACTOR==8 || EDDSA_USE_SIGMA_ISOGENY - static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( - 0x6db8831bbddec, 0x38d7b56c9c165, 0x016b221394bdc, 0x7540f7816214a, 0x0a0d85b4032b1 - )}; -#endif - #if IMAGINE_TWIST #define TWISTED_D (-(EDWARDS_D)) #else @@ -1193,8 +1187,9 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) ( gf_sub ( p->t, a, c ); // y^2 - x^2 gf_sqr ( p->x, p->z ); gf_add ( p->z, p->x, p->x ); - gf_sub ( a, p->z, p->t ); // 2z^2 - y^2 + x^2 - gf_mul ( c, a, SQRT_ONE_MINUS_D ); + gf_sub ( c, p->z, p->t ); // 2z^2 - y^2 + x^2 + gf_div_qnr ( a, c ); + gf_mul ( c, a, RISTRETTO_ISOMAGIC ); gf_mul ( p->x, b, p->t); // (2xy)(y^2-x^2) gf_mul ( p->z, p->t, c ); // (y^2-x^2)sd(2z^2 - y^2 + x^2) gf_mul ( p->y, d, c ); // (y^2+x^2)sd(2z^2 - y^2 + x^2) @@ -1363,6 +1358,23 @@ void decaf_x25519_generate_key ( decaf_x25519_derive_public_key(out,scalar); } +void API_NS(point_mul_by_cofactor_and_encode_like_x25519) ( + uint8_t out[X_PUBLIC_BYTES], + const point_t p +) { + point_t q; + point_double_internal(q,p,1); + for (unsigned i=1; it,q->x,0); /* 1/x */ + gf_mul(q->z,q->t,q->y); /* y/x */ + gf_sqr(q->y,q->z); /* (y/x)^2 */ +#if IMAGINE_TWIST + gf_sub(q->y,ZERO,q->y); +#endif + gf_serialize(out,q->y,1); + API_NS(point_destroy(q)); +} + void decaf_x25519_derive_public_key ( uint8_t out[X_PUBLIC_BYTES], const uint8_t scalar[X_PRIVATE_BYTES] @@ -1390,27 +1402,12 @@ void decaf_x25519_derive_public_key ( * Jacobi -> Edwards -> Jacobi -> Montgomery, * we pick up only a factor of 2 over Jacobi -> Montgomery. */ - API_NS(scalar_halve)(the_scalar,the_scalar); + for (unsigned i=1; it,p->x,0); /* 1/x */ - gf_mul(p->z,p->t,p->y); /* y/x */ - gf_sqr(p->y,p->z); /* (y/x)^2 */ -#if IMAGINE_TWIST - gf_sub(p->y,ZERO,p->y); -#endif - gf_serialize(out,p->y,1); - - decaf_bzero(scalar2,sizeof(scalar2)); - API_NS(scalar_destroy)(the_scalar); + API_NS(point_mul_by_cofactor_and_encode_like_x25519)(out,p); API_NS(point_destroy)(p); } diff --git a/src/GENERATED/c/ed448goldilocks/decaf.c b/src/GENERATED/c/ed448goldilocks/decaf.c index b8daee2..6e14e5c 100644 --- a/src/GENERATED/c/ed448goldilocks/decaf.c +++ b/src/GENERATED/c/ed448goldilocks/decaf.c @@ -52,12 +52,6 @@ static const gf RISTRETTO_ISOMAGIC = {{{ 0x42ef0f45572736, 0x7bf6aa20ce5296, 0xf4fd6eded26033, 0x968c14ba839a66, 0xb8d54b64a2d780, 0x6aa0a1f1a7b8a5, 0x683bf68d722fa2, 0x22d962fbeb24f7 }}}; -#if COFACTOR==8 || EDDSA_USE_SIGMA_ISOGENY - static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( - /* NONE */ - )}; -#endif - #if IMAGINE_TWIST #define TWISTED_D (-(EDWARDS_D)) #else @@ -1193,8 +1187,9 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) ( gf_sub ( p->t, a, c ); // y^2 - x^2 gf_sqr ( p->x, p->z ); gf_add ( p->z, p->x, p->x ); - gf_sub ( a, p->z, p->t ); // 2z^2 - y^2 + x^2 - gf_mul ( c, a, SQRT_ONE_MINUS_D ); + gf_sub ( c, p->z, p->t ); // 2z^2 - y^2 + x^2 + gf_div_qnr ( a, c ); + gf_mul ( c, a, RISTRETTO_ISOMAGIC ); gf_mul ( p->x, b, p->t); // (2xy)(y^2-x^2) gf_mul ( p->z, p->t, c ); // (y^2-x^2)sd(2z^2 - y^2 + x^2) gf_mul ( p->y, d, c ); // (y^2+x^2)sd(2z^2 - y^2 + x^2) @@ -1363,6 +1358,23 @@ void decaf_x448_generate_key ( decaf_x448_derive_public_key(out,scalar); } +void API_NS(point_mul_by_cofactor_and_encode_like_x448) ( + uint8_t out[X_PUBLIC_BYTES], + const point_t p +) { + point_t q; + point_double_internal(q,p,1); + for (unsigned i=1; it,q->x,0); /* 1/x */ + gf_mul(q->z,q->t,q->y); /* y/x */ + gf_sqr(q->y,q->z); /* (y/x)^2 */ +#if IMAGINE_TWIST + gf_sub(q->y,ZERO,q->y); +#endif + gf_serialize(out,q->y,1); + API_NS(point_destroy(q)); +} + void decaf_x448_derive_public_key ( uint8_t out[X_PUBLIC_BYTES], const uint8_t scalar[X_PRIVATE_BYTES] @@ -1390,27 +1402,12 @@ void decaf_x448_derive_public_key ( * Jacobi -> Edwards -> Jacobi -> Montgomery, * we pick up only a factor of 2 over Jacobi -> Montgomery. */ - API_NS(scalar_halve)(the_scalar,the_scalar); + for (unsigned i=1; it,p->x,0); /* 1/x */ - gf_mul(p->z,p->t,p->y); /* y/x */ - gf_sqr(p->y,p->z); /* (y/x)^2 */ -#if IMAGINE_TWIST - gf_sub(p->y,ZERO,p->y); -#endif - gf_serialize(out,p->y,1); - - decaf_bzero(scalar2,sizeof(scalar2)); - API_NS(scalar_destroy)(the_scalar); + API_NS(point_mul_by_cofactor_and_encode_like_x448)(out,p); API_NS(point_destroy)(p); } diff --git a/src/GENERATED/include/decaf/point_255.h b/src/GENERATED/include/decaf/point_255.h index 7e1e2d6..79ba778 100644 --- a/src/GENERATED/include/decaf/point_255.h +++ b/src/GENERATED/include/decaf/point_255.h @@ -52,6 +52,9 @@ typedef struct gf_25519_s { /** Number of bits in the "which" field of an elligator inverse */ #define DECAF_255_INVERT_ELLIGATOR_WHICH_BITS 5 +/** The cofactor the curve would have, if we hadn't removed it */ +#define DECAF_255_REMOVED_COFACTOR 8 + /** Number of bytes in an x25519 public key */ #define DECAF_X25519_PUBLIC_BYTES 32 @@ -397,6 +400,17 @@ decaf_error_t decaf_x25519 ( const uint8_t scalar[DECAF_X25519_PRIVATE_BYTES] ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; +/** + * @brief Multiply a point by the cofactor, then encode it like RFC 7748 + * + * @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 ( + uint8_t out[DECAF_X25519_PUBLIC_BYTES], + const decaf_255_point_t p +); + /** The base point for X25519 Diffie-Hellman */ extern const uint8_t decaf_x25519_base_point[DECAF_X25519_PUBLIC_BYTES] DECAF_API_VIS; diff --git a/src/GENERATED/include/decaf/point_448.h b/src/GENERATED/include/decaf/point_448.h index a291e58..35c83dd 100644 --- a/src/GENERATED/include/decaf/point_448.h +++ b/src/GENERATED/include/decaf/point_448.h @@ -52,6 +52,9 @@ typedef struct gf_448_s { /** Number of bits in the "which" field of an elligator inverse */ #define DECAF_448_INVERT_ELLIGATOR_WHICH_BITS 3 +/** The cofactor the curve would have, if we hadn't removed it */ +#define DECAF_448_REMOVED_COFACTOR 4 + /** Number of bytes in an x448 public key */ #define DECAF_X448_PUBLIC_BYTES 56 @@ -397,6 +400,17 @@ decaf_error_t decaf_x448 ( const uint8_t scalar[DECAF_X448_PRIVATE_BYTES] ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; +/** + * @brief Multiply a point by the cofactor, then encode it like RFC 7748 + * + * @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 ( + uint8_t out[DECAF_X448_PUBLIC_BYTES], + const decaf_448_point_t p +); + /** The base point for X448 Diffie-Hellman */ extern const uint8_t decaf_x448_base_point[DECAF_X448_PUBLIC_BYTES] DECAF_API_VIS; diff --git a/src/per_curve/decaf.tmpl.c b/src/per_curve/decaf.tmpl.c index c786a2b..902c6b0 100644 --- a/src/per_curve/decaf.tmpl.c +++ b/src/per_curve/decaf.tmpl.c @@ -41,12 +41,6 @@ static const gf RISTRETTO_ISOMAGIC = {{{ $(ser(msqrt(d-1 if imagine_twist else -d,modulus,lo_bit_clear=True),gf_lit_limb_bits)) }}}; -#if COFACTOR==8 || EDDSA_USE_SIGMA_ISOGENY - static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( - $(ser(msqrt(1-d,modulus),gf_lit_limb_bits) if cofactor == 8 else "/* NONE */") - )}; -#endif - #if IMAGINE_TWIST #define TWISTED_D (-(EDWARDS_D)) #else @@ -1182,8 +1176,9 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) ( gf_sub ( p->t, a, c ); // y^2 - x^2 gf_sqr ( p->x, p->z ); gf_add ( p->z, p->x, p->x ); - gf_sub ( a, p->z, p->t ); // 2z^2 - y^2 + x^2 - gf_mul ( c, a, SQRT_ONE_MINUS_D ); + gf_sub ( c, p->z, p->t ); // 2z^2 - y^2 + x^2 + gf_div_qnr ( a, c ); + gf_mul ( c, a, RISTRETTO_ISOMAGIC ); gf_mul ( p->x, b, p->t); // (2xy)(y^2-x^2) gf_mul ( p->z, p->t, c ); // (y^2-x^2)sd(2z^2 - y^2 + x^2) gf_mul ( p->y, d, c ); // (y^2+x^2)sd(2z^2 - y^2 + x^2) @@ -1352,6 +1347,23 @@ 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)) ( + uint8_t out[X_PUBLIC_BYTES], + const point_t p +) { + point_t q; + point_double_internal(q,p,1); + for (unsigned i=1; it,q->x,0); /* 1/x */ + gf_mul(q->z,q->t,q->y); /* y/x */ + gf_sqr(q->y,q->z); /* (y/x)^2 */ +#if IMAGINE_TWIST + gf_sub(q->y,ZERO,q->y); +#endif + gf_serialize(out,q->y,1); + API_NS(point_destroy(q)); +} + void decaf_x$(gf_shortname)_derive_public_key ( uint8_t out[X_PUBLIC_BYTES], const uint8_t scalar[X_PRIVATE_BYTES] @@ -1379,27 +1391,12 @@ void decaf_x$(gf_shortname)_derive_public_key ( * Jacobi -> Edwards -> Jacobi -> Montgomery, * we pick up only a factor of 2 over Jacobi -> Montgomery. */ - API_NS(scalar_halve)(the_scalar,the_scalar); + for (unsigned i=1; it,p->x,0); /* 1/x */ - gf_mul(p->z,p->t,p->y); /* y/x */ - gf_sqr(p->y,p->z); /* (y/x)^2 */ -#if IMAGINE_TWIST - gf_sub(p->y,ZERO,p->y); -#endif - gf_serialize(out,p->y,1); - - decaf_bzero(scalar2,sizeof(scalar2)); - API_NS(scalar_destroy)(the_scalar); + API_NS(point_mul_by_cofactor_and_encode_like_x$(gf_shortname))(out,p); API_NS(point_destroy)(p); } diff --git a/src/per_curve/point.tmpl.h b/src/per_curve/point.tmpl.h index bf3762d..c0565f2 100644 --- a/src/per_curve/point.tmpl.h +++ b/src/per_curve/point.tmpl.h @@ -37,6 +37,9 @@ typedef struct gf_$(gf_shortname)_s { /** Number of bits in the "which" field of an elligator inverse */ #define $(C_NS)_INVERT_ELLIGATOR_WHICH_BITS $(ceil_log2(cofactor) + 7 + elligator_onto - ((gf_bits-2) % 8)) +/** The cofactor the curve would have, if we hadn't removed it */ +#define $(C_NS)_REMOVED_COFACTOR $(cofactor) + /** Number of bytes in an x$(gf_shortname) public key */ #define DECAF_X$(gf_shortname)_PUBLIC_BYTES $((gf_bits-1)//8 + 1) @@ -382,6 +385,17 @@ decaf_error_t decaf_x$(gf_shortname) ( const uint8_t scalar[DECAF_X$(gf_shortname)_PRIVATE_BYTES] ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; +/** + * @brief Multiply a point by the cofactor, then encode it like RFC 7748 + * + * @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) ( + uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES], + const $(c_ns)_point_t p +); + /** The base point for X$(gf_shortname) Diffie-Hellman */ extern const uint8_t decaf_x$(gf_shortname)_base_point[DECAF_X$(gf_shortname)_PUBLIC_BYTES] DECAF_API_VIS; diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index b72269b..c52747d 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -457,12 +457,15 @@ static void test_cfrg_crypto() { printf(" Shared secrets disagree on iteration %d.\n",i); } - if (!memeq( - DhLadder::shared_secret(DhLadder::base_point(),s1), - DhLadder::derive_public_key(s1) - )) { + p1 = DhLadder::shared_secret(DhLadder::base_point(),s1); + p2 = DhLadder::derive_public_key(s1); + if (!memeq(p1,p2)) { test.fail(); - printf(" Public keys disagree on iteration %d.\n",i); + printf(" Public keys disagree on iteration %d.\n Ladder public key: ",i); + for (unsigned j=0; j