Browse Source

differentiate curve

master
Mike Hamburg 10 years ago
parent
commit
994812cf14
6 changed files with 295 additions and 293 deletions
  1. +93
    -91
      include/decaf.h
  2. +153
    -153
      src/decaf.c
  3. +6
    -6
      test/bench.c
  4. +18
    -18
      test/test_arithmetic.c
  5. +21
    -21
      test/test_pointops.c
  6. +4
    -4
      test/test_scalarmul.c

+ 93
- 91
include/decaf.h View File

@@ -12,13 +12,16 @@
* curve (isogenous to Ed448-Goldilocks) and wiping out the cofactor. * curve (isogenous to Ed448-Goldilocks) and wiping out the cofactor.
* *
* The formulas are all complete and have no special cases, except that * The formulas are all complete and have no special cases, except that
* decaf_decode can fail because not every sequence of bytes is a valid group
* decaf_448_decode can fail because not every sequence of bytes is a valid group
* element. * element.
* *
* The formulas contain no data-dependent branches, timing or memory accesses. * The formulas contain no data-dependent branches, timing or memory accesses.
*
* This library may support multiple curves eventually. The Ed448-Goldilocks
* specific identifiers are prefixed with DECAF_448 or decaf_448.
*/ */
#ifndef __DECAF_H__
#define __DECAF_H__ 1
#ifndef __DECAF_448_H__
#define __DECAF_448_H__ 1


#include <stdint.h> #include <stdint.h>


@@ -36,7 +39,7 @@


/* Internal word types */ /* Internal word types */
#if (defined(__ILP64__) || defined(__amd64__) || defined(__x86_64__) || (((__UINT_FAST32_MAX__)>>30)>>30)) \ #if (defined(__ILP64__) || defined(__amd64__) || defined(__x86_64__) || (((__UINT_FAST32_MAX__)>>30)>>30)) \
&& !defined(DECAF_FORCE_32_BIT)
&& !defined(DECAF_FORCE_32_BIT)
#define DECAF_WORD_BITS 64 #define DECAF_WORD_BITS 64
typedef uint64_t decaf_word_t, decaf_bool_t; typedef uint64_t decaf_word_t, decaf_bool_t;
#else #else
@@ -45,26 +48,25 @@ typedef uint32_t decaf_word_t, decaf_bool_t;
#endif #endif
/** @endcond */ /** @endcond */


/* TODO: prefix all these operations and factor to support multiple curves. */
#define DECAF_LIMBS (512/DECAF_WORD_BITS)
#define DECAF_SCALAR_BITS 446
#define DECAF_SCALAR_LIMBS (448/DECAF_WORD_BITS)
#define DECAF_448_LIMBS (512/DECAF_WORD_BITS)
#define DECAF_448_SCALAR_BITS 446
#define DECAF_448_SCALAR_LIMBS (448/DECAF_WORD_BITS)


/** Number of bytes in a serialized point. */ /** Number of bytes in a serialized point. */
#define DECAF_SER_BYTES 56
#define DECAF_448_SER_BYTES 56


/** Number of bytes in a serialized scalar. */ /** Number of bytes in a serialized scalar. */
#define DECAF_SCALAR_BYTES 56
#define DECAF_448_SCALAR_BYTES 56


/** Twisted Edwards (-1,d-1) extended homogeneous coordinates */ /** Twisted Edwards (-1,d-1) extended homogeneous coordinates */
typedef struct decaf_point_s {
decaf_word_t x[DECAF_LIMBS],y[DECAF_LIMBS],z[DECAF_LIMBS],t[DECAF_LIMBS];
} decaf_point_t[1];
typedef struct decaf_448_point_s {
decaf_word_t x[DECAF_448_LIMBS],y[DECAF_448_LIMBS],z[DECAF_448_LIMBS],t[DECAF_448_LIMBS];
} decaf_448_point_t[1];


/** Scalar is stored packed, because we don't need the speed. */ /** Scalar is stored packed, because we don't need the speed. */
typedef struct decaf_scalar_s {
decaf_word_t limb[DECAF_SCALAR_LIMBS];
} decaf_scalar_t[1];
typedef struct decaf_448_scalar_s {
decaf_word_t limb[DECAF_448_SCALAR_LIMBS];
} decaf_448_scalar_t[1];


/** DECAF_TRUE = -1 so that DECAF_TRUE & x = x */ /** 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;
@@ -76,23 +78,23 @@ static const decaf_bool_t DECAF_SUCCESS = -(decaf_bool_t)1 /*DECAF_TRUE*/,
/** The prime p, for debugging purposes. /** The prime p, for debugging purposes.
* TODO: 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_448_scalar_t decaf_448_scalar_p API_VIS;


/** A scalar equal to 1. */ /** A scalar equal to 1. */
const decaf_scalar_t decaf_scalar_one API_VIS;
const decaf_448_scalar_t decaf_448_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_448_scalar_t decaf_448_scalar_zero API_VIS;


/** The identity point on the curve. */ /** The identity point on the curve. */
const decaf_point_t decaf_point_identity API_VIS;
const decaf_448_point_t decaf_448_point_identity API_VIS;


/** /**
* An arbitrarily chosen base point on the curve. * An arbitrarily chosen base point on the curve.
* Equal to Ed448-Goldilocks base point defined by DJB, except of course that * 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? * 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;
const decaf_448_point_t decaf_448_point_base API_VIS;


#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -112,9 +114,9 @@ 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_scalar_decode (
decaf_scalar_t s,
const unsigned char ser[DECAF_SCALAR_BYTES]
decaf_bool_t decaf_448_scalar_decode (
decaf_448_scalar_t s,
const unsigned char ser[DECAF_448_SCALAR_BYTES]
) API_VIS NONNULL2; ) API_VIS NONNULL2;
/** /**
@@ -123,9 +125,9 @@ decaf_bool_t decaf_scalar_decode (
* @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_scalar_encode (
unsigned char ser[DECAF_SCALAR_BYTES],
const decaf_scalar_t s
void decaf_448_scalar_encode (
unsigned char ser[DECAF_448_SCALAR_BYTES],
const decaf_448_scalar_t s
) API_VIS NONNULL2; ) API_VIS NONNULL2;
/** /**
@@ -134,10 +136,10 @@ void decaf_scalar_encode (
* @param [in] b Another scalar. * @param [in] b Another scalar.
* @param [out] out a+b. * @param [out] out a+b.
*/ */
void decaf_scalar_add (
decaf_scalar_t out,
const decaf_scalar_t a,
const decaf_scalar_t b
void decaf_448_scalar_add (
decaf_448_scalar_t out,
const decaf_448_scalar_t a,
const decaf_448_scalar_t b
) API_VIS NONNULL3; ) API_VIS NONNULL3;


/** /**
@@ -147,9 +149,9 @@ void decaf_scalar_add (
* @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_scalar_eq (
const decaf_scalar_t a,
const decaf_scalar_t b
decaf_bool_t decaf_448_scalar_eq (
const decaf_448_scalar_t a,
const decaf_448_scalar_t b
) API_VIS WARN_UNUSED NONNULL2; ) API_VIS WARN_UNUSED NONNULL2;


/** /**
@@ -158,10 +160,10 @@ decaf_bool_t decaf_scalar_eq (
* @param [in] b Another scalar. * @param [in] b Another scalar.
* @param [out] out a-b. * @param [out] out a-b.
*/ */
void decaf_scalar_sub (
decaf_scalar_t out,
const decaf_scalar_t a,
const decaf_scalar_t b
void decaf_448_scalar_sub (
decaf_448_scalar_t out,
const decaf_448_scalar_t a,
const decaf_448_scalar_t b
) API_VIS NONNULL3; ) API_VIS NONNULL3;


/** /**
@@ -170,10 +172,10 @@ void decaf_scalar_sub (
* @param [in] b Another scalar. * @param [in] b Another scalar.
* @param [out] out a*b. * @param [out] out a*b.
*/ */
void decaf_scalar_mul (
decaf_scalar_t out,
const decaf_scalar_t a,
const decaf_scalar_t b
void decaf_448_scalar_mul (
decaf_448_scalar_t out,
const decaf_448_scalar_t a,
const decaf_448_scalar_t b
) API_VIS NONNULL3; ) API_VIS NONNULL3;


/** /**
@@ -182,9 +184,9 @@ void decaf_scalar_mul (
* @param [in] a A scalar. * @param [in] a A scalar.
* @param [out] out Will become a copy of a. * @param [out] out Will become a copy of a.
*/ */
void decaf_scalar_copy (
decaf_scalar_t out,
const decaf_scalar_t a
void decaf_448_scalar_copy (
decaf_448_scalar_t out,
const decaf_448_scalar_t a
) API_VIS NONNULL2; ) API_VIS NONNULL2;


/** /**
@@ -193,9 +195,9 @@ void decaf_scalar_copy (
* @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_point_encode (
uint8_t ser[DECAF_SER_BYTES],
const decaf_point_t pt
void decaf_448_point_encode (
uint8_t ser[DECAF_448_SER_BYTES],
const decaf_448_point_t pt
) API_VIS NONNULL2; ) API_VIS NONNULL2;


/** /**
@@ -211,9 +213,9 @@ void decaf_point_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_point_decode (
decaf_point_t pt,
const uint8_t ser[DECAF_SER_BYTES],
decaf_bool_t decaf_448_point_decode (
decaf_448_point_t pt,
const uint8_t ser[DECAF_448_SER_BYTES],
decaf_bool_t allow_identity decaf_bool_t allow_identity
) API_VIS WARN_UNUSED NONNULL2; ) API_VIS WARN_UNUSED NONNULL2;


@@ -224,9 +226,9 @@ decaf_bool_t decaf_point_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_point_copy (
decaf_point_t a,
const decaf_point_t b
void decaf_448_point_copy (
decaf_448_point_t a,
const decaf_448_point_t b
) API_VIS NONNULL2; ) API_VIS NONNULL2;


/** /**
@@ -238,9 +240,9 @@ void decaf_point_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_point_eq (
const decaf_point_t a,
const decaf_point_t b
decaf_bool_t decaf_448_point_eq (
const decaf_448_point_t a,
const decaf_448_point_t b
) API_VIS WARN_UNUSED NONNULL2; ) API_VIS WARN_UNUSED NONNULL2;


/** /**
@@ -252,22 +254,22 @@ decaf_bool_t decaf_point_eq (
* @param [in] a An addend. * @param [in] a An addend.
* @param [in] b An addend. * @param [in] b An addend.
*/ */
void decaf_point_add (
decaf_point_t sum,
const decaf_point_t a,
const decaf_point_t b
void decaf_448_point_add (
decaf_448_point_t sum,
const decaf_448_point_t a,
const decaf_448_point_t b
) API_VIS NONNULL3; ) API_VIS NONNULL3;


/** /**
* @brief Double a point. Equivalent to * @brief Double a point. Equivalent to
* decaf_point_add(two_a,a,a), but potentially faster.
* decaf_448_point_add(two_a,a,a), but potentially faster.
* *
* @param [out] sum The sum a+a. * @param [out] sum The sum a+a.
* @param [in] a A point. * @param [in] a A point.
*/ */
void decaf_point_double (
decaf_point_t two_a,
const decaf_point_t a
void decaf_448_point_double (
decaf_448_point_t two_a,
const decaf_448_point_t a
) API_VIS NONNULL2; ) API_VIS NONNULL2;


/** /**
@@ -279,10 +281,10 @@ void decaf_point_double (
* @param [in] a The minuend. * @param [in] a The minuend.
* @param [in] b The subtrahend. * @param [in] b The subtrahend.
*/ */
void decaf_point_sub (
decaf_point_t diff,
const decaf_point_t a,
const decaf_point_t b
void decaf_448_point_sub (
decaf_448_point_t diff,
const decaf_448_point_t a,
const decaf_448_point_t b
) API_VIS NONNULL3; ) API_VIS NONNULL3;


/** /**
@@ -292,17 +294,17 @@ void decaf_point_sub (
* @param [in] base The point to be scaled. * @param [in] base The point to be scaled.
* @param [in] scalar The scalar to multiply by. * @param [in] scalar The scalar to multiply by.
*/ */
void decaf_point_scalarmul (
decaf_point_t scaled,
const decaf_point_t base,
const decaf_scalar_t scalar
void decaf_448_point_scalarmul (
decaf_448_point_t scaled,
const decaf_448_point_t base,
const decaf_448_scalar_t scalar
) API_VIS NONNULL3; ) API_VIS NONNULL3;


/** /**
* @brief Multiply two base points by two scalars: * @brief Multiply two base points by two scalars:
* scaled = scalar1*base1 + scalar2*base2. * scaled = scalar1*base1 + scalar2*base2.
* *
* Equivalent to two calls to decaf_point_scalarmul, but may be
* Equivalent to two calls to decaf_448_point_scalarmul, but may be
* faster. * faster.
* *
* @param [out] scaled The scaled point base*scalar * @param [out] scaled The scaled point base*scalar
@@ -312,12 +314,12 @@ void decaf_point_scalarmul (
* @param [in] scalar2 A second scalar to multiply by. * @param [in] scalar2 A second scalar to multiply by.
* @TODO: test * @TODO: test
*/ */
void decaf_point_double_scalarmul (
decaf_point_t combo,
const decaf_point_t base1,
const decaf_scalar_t scalar1,
const decaf_point_t base2,
const decaf_scalar_t scalar2
void decaf_448_point_double_scalarmul (
decaf_448_point_t combo,
const decaf_448_point_t base1,
const decaf_448_scalar_t scalar1,
const decaf_448_point_t base2,
const decaf_448_scalar_t scalar2
) API_VIS NONNULL5; ) API_VIS NONNULL5;


/** /**
@@ -327,8 +329,8 @@ void decaf_point_double_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_point_valid (
const decaf_point_t toTest
decaf_bool_t decaf_448_point_valid (
const decaf_448_point_t toTest
) API_VIS WARN_UNUSED NONNULL1; ) API_VIS WARN_UNUSED NONNULL1;


/** /**
@@ -336,7 +338,7 @@ decaf_bool_t decaf_point_valid (
* *
* Call this function with the output of a hash to make a hash to the curve. * Call this function with the output of a hash to make a hash to the curve.
* *
* This function runs Elligator2 on the decaf Jacobi quartic model. It then
* This function runs Elligator2 on the decaf_448 Jacobi quartic model. It then
* uses the isogeny to put the result in twisted Edwards form. As a result, * uses the isogeny to put the result in twisted Edwards form. As a result,
* it is safe (cannot produce points of order 4), and would be compatible with * it is safe (cannot produce points of order 4), and would be compatible with
* hypothetical other implementations of Decaf using a Montgomery or untwisted * hypothetical other implementations of Decaf using a Montgomery or untwisted
@@ -358,22 +360,22 @@ decaf_bool_t decaf_point_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_point_from_hash_nonuniform (
decaf_point_t pt,
const unsigned char hashed_data[DECAF_SER_BYTES]
void decaf_448_point_from_hash_nonuniform (
decaf_448_point_t pt,
const unsigned char hashed_data[DECAF_448_SER_BYTES]
) API_VIS NONNULL2; ) API_VIS NONNULL2;


/** /**
* @brief Indifferentiable hash function encoding to curve. * @brief Indifferentiable hash function encoding to curve.
* *
* Equivalent to calling decaf_point_from_hash_nonuniform twice and adding.
* Equivalent to calling decaf_448_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_point_from_hash_uniform (
decaf_point_t pt,
const unsigned char hashed_data[2*DECAF_SER_BYTES]
void decaf_448_point_from_hash_uniform (
decaf_448_point_t pt,
const unsigned char hashed_data[2*DECAF_448_SER_BYTES]
) API_VIS NONNULL2; ) API_VIS NONNULL2;
/* TODO: functions to invert point_from_hash?? */ /* TODO: functions to invert point_from_hash?? */
@@ -389,4 +391,4 @@ void decaf_point_from_hash_uniform (
}; /* extern "C" */ }; /* extern "C" */
#endif #endif


#endif /* __DECAF_H__ */
#endif /* __DECAF_448_H__ */

+ 153
- 153
src/decaf.c View File

@@ -31,7 +31,7 @@ typedef int64_t decaf_sdword_t;
static const int QUADRATIC_NONRESIDUE = -1; static const int QUADRATIC_NONRESIDUE = -1;


#define sv static void #define sv static void
typedef decaf_word_t gf[DECAF_LIMBS];
typedef decaf_word_t gf[DECAF_448_LIMBS];
static const gf ZERO = {0}, ONE = {1}, TWO = {2}; static const gf ZERO = {0}, ONE = {1}, TWO = {2};


#define LMASK ((((decaf_word_t)1)<<LBITS)-1) #define LMASK ((((decaf_word_t)1)<<LBITS)-1)
@@ -43,7 +43,7 @@ static const gf P = { LMASK, LMASK, LMASK, LMASK, LMASK, LMASK, LMASK, LMASK,
#endif #endif
static const int EDWARDS_D = -39081; static const int EDWARDS_D = -39081;


const decaf_scalar_t decaf_scalar_p = {{{
const decaf_448_scalar_t decaf_448_scalar_p = {{{
SC_LIMB(0x2378c292ab5844f3), SC_LIMB(0x2378c292ab5844f3),
SC_LIMB(0x216cc2728dc58f55), SC_LIMB(0x216cc2728dc58f55),
SC_LIMB(0xc44edb49aed63690), SC_LIMB(0xc44edb49aed63690),
@@ -51,9 +51,9 @@ const decaf_scalar_t decaf_scalar_p = {{{
SC_LIMB(0xffffffffffffffff), SC_LIMB(0xffffffffffffffff),
SC_LIMB(0xffffffffffffffff), SC_LIMB(0xffffffffffffffff),
SC_LIMB(0x3fffffffffffffff) SC_LIMB(0x3fffffffffffffff)
}}}, decaf_scalar_one = {{{1}}}, decaf_scalar_zero = {{{0}}};
}}}, decaf_448_scalar_one = {{{1}}}, decaf_448_scalar_zero = {{{0}}};


static const decaf_scalar_t decaf_scalar_r2 = {{{
static const decaf_448_scalar_t decaf_448_scalar_r2 = {{{
SC_LIMB(0xe3539257049b9b60), SC_LIMB(0xe3539257049b9b60),
SC_LIMB(0x7af32c4bc1b195d9), SC_LIMB(0x7af32c4bc1b195d9),
SC_LIMB(0x0d66de2388ea1859), SC_LIMB(0x0d66de2388ea1859),
@@ -66,7 +66,7 @@ static const decaf_scalar_t decaf_scalar_r2 = {{{
static const decaf_word_t DECAF_MONTGOMERY_FACTOR = (decaf_word_t)(0x3bd440fae918bc5ull); static const decaf_word_t DECAF_MONTGOMERY_FACTOR = (decaf_word_t)(0x3bd440fae918bc5ull);


/** base = twist of Goldilocks base point (~,19). */ /** base = twist of Goldilocks base point (~,19). */
const decaf_point_t decaf_point_base = {{
const decaf_448_point_t decaf_448_point_base = {{
{ LIMB(0xb39a2d57e08c7b),LIMB(0xb38639c75ff281), { LIMB(0xb39a2d57e08c7b),LIMB(0xb38639c75ff281),
LIMB(0x2ec981082b3288),LIMB(0x99fe8607e5237c), LIMB(0x2ec981082b3288),LIMB(0x99fe8607e5237c),
LIMB(0x0e33fbb1fadd1f),LIMB(0xe714f67055eb4a), LIMB(0x0e33fbb1fadd1f),LIMB(0xe714f67055eb4a),
@@ -83,20 +83,20 @@ const decaf_point_t decaf_point_base = {{
}}; }};


#if (defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__)) || defined(DECAF_FORCE_UNROLL) #if (defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__)) || defined(DECAF_FORCE_UNROLL)
#if DECAF_LIMBS==8
#if DECAF_448_LIMBS==8
#define FOR_LIMB(i,op) { unsigned int i=0; \ #define FOR_LIMB(i,op) { unsigned int i=0; \
op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; \ op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; \
} }
#elif DECAF_LIMBS==16
#elif DECAF_448_LIMBS==16
#define FOR_LIMB(i,op) { unsigned int i=0; \ #define FOR_LIMB(i,op) { unsigned int i=0; \
op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; \ op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; \
op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; \ op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; \
} }
#else #else
#define FOR_LIMB(i,op) { unsigned int i=0; for (i=0; i<DECAF_LIMBS; i++) { op; }}
#define FOR_LIMB(i,op) { unsigned int i=0; for (i=0; i<DECAF_448_LIMBS; i++) { op; }}
#endif #endif
#else #else
#define FOR_LIMB(i,op) { unsigned int i=0; for (i=0; i<DECAF_LIMBS; i++) { op; }}
#define FOR_LIMB(i,op) { unsigned int i=0; for (i=0; i<DECAF_448_LIMBS; i++) { op; }}
#endif #endif


/** Copy x = y */ /** Copy x = y */
@@ -107,18 +107,18 @@ sv gf_mul (gf c, const gf a, const gf b) {
gf aa; gf aa;
gf_cpy(aa,a); gf_cpy(aa,a);
decaf_dword_t accum[DECAF_LIMBS] = {0};
decaf_dword_t accum[DECAF_448_LIMBS] = {0};
FOR_LIMB(i, { FOR_LIMB(i, {
FOR_LIMB(j,{ accum[(i+j)%DECAF_LIMBS] += (decaf_dword_t)b[i] * aa[j]; });
aa[(DECAF_LIMBS-1-i)^(DECAF_LIMBS/2)] += aa[DECAF_LIMBS-1-i];
FOR_LIMB(j,{ accum[(i+j)%DECAF_448_LIMBS] += (decaf_dword_t)b[i] * aa[j]; });
aa[(DECAF_448_LIMBS-1-i)^(DECAF_448_LIMBS/2)] += aa[DECAF_448_LIMBS-1-i];
}); });
accum[DECAF_LIMBS-1] += accum[DECAF_LIMBS-2] >> LBITS;
accum[DECAF_LIMBS-2] &= LMASK;
accum[DECAF_LIMBS/2] += accum[DECAF_LIMBS-1] >> LBITS;
accum[DECAF_448_LIMBS-1] += accum[DECAF_448_LIMBS-2] >> LBITS;
accum[DECAF_448_LIMBS-2] &= LMASK;
accum[DECAF_448_LIMBS/2] += accum[DECAF_448_LIMBS-1] >> LBITS;
FOR_LIMB(j,{ FOR_LIMB(j,{
accum[j] += accum[(j-1)%DECAF_LIMBS] >> LBITS;
accum[(j-1)%DECAF_LIMBS] &= LMASK;
accum[j] += accum[(j-1)%DECAF_448_LIMBS] >> LBITS;
accum[(j-1)%DECAF_448_LIMBS] &= LMASK;
}); });
FOR_LIMB(j, c[j] = accum[j] ); FOR_LIMB(j, c[j] = accum[j] );
} }
@@ -148,10 +148,10 @@ sv gf_isqrt(gf y, const gf x) {


/** Weak reduce mod p. */ /** Weak reduce mod p. */
sv gf_reduce(gf x) { sv gf_reduce(gf x) {
x[DECAF_LIMBS/2] += x[DECAF_LIMBS-1] >> LBITS;
x[DECAF_448_LIMBS/2] += x[DECAF_448_LIMBS-1] >> LBITS;
FOR_LIMB(j,{ FOR_LIMB(j,{
x[j] += x[(j-1)%DECAF_LIMBS] >> LBITS;
x[(j-1)%DECAF_LIMBS] &= LMASK;
x[j] += x[(j-1)%DECAF_448_LIMBS] >> LBITS;
x[(j-1)%DECAF_448_LIMBS] &= LMASK;
}); });
} }


@@ -246,10 +246,10 @@ static decaf_word_t hibit(const gf x) {
} }


/* a = use_c ? c : b */ /* a = use_c ? c : b */
sv decaf_cond_sel (
decaf_point_t a,
const decaf_point_t b,
const decaf_point_t c,
sv decaf_448_cond_sel (
decaf_448_point_t a,
const decaf_448_point_t b,
const decaf_448_point_t c,
decaf_bool_t use_c decaf_bool_t use_c
) { ) {
cond_sel(a->x, b->x, c->x, use_c); cond_sel(a->x, b->x, c->x, use_c);
@@ -261,16 +261,16 @@ sv decaf_cond_sel (
/** {extra,accum} - sub +? p /** {extra,accum} - sub +? p
* Must have extra <= 1 * Must have extra <= 1
*/ */
sv decaf_subx(
decaf_scalar_t out,
const decaf_word_t accum[DECAF_SCALAR_LIMBS],
const decaf_scalar_t sub,
const decaf_scalar_t p,
sv decaf_448_subx(
decaf_448_scalar_t out,
const decaf_word_t accum[DECAF_448_SCALAR_LIMBS],
const decaf_448_scalar_t sub,
const decaf_448_scalar_t p,
decaf_word_t extra decaf_word_t extra
) { ) {
decaf_sdword_t chain = 0; decaf_sdword_t chain = 0;
unsigned int i; unsigned int i;
for (i=0; i<DECAF_SCALAR_LIMBS; i++) {
for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
chain = (chain + accum[i]) - sub->limb[i]; chain = (chain + accum[i]) - sub->limb[i];
out->limb[i] = chain; out->limb[i] = chain;
chain >>= WBITS; chain >>= WBITS;
@@ -278,30 +278,30 @@ sv decaf_subx(
decaf_bool_t borrow = chain+extra; /* = 0 or -1 */ decaf_bool_t borrow = chain+extra; /* = 0 or -1 */
chain = 0; chain = 0;
for (i=0; i<DECAF_SCALAR_LIMBS; i++) {
for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
chain = (chain + out->limb[i]) + (p->limb[i] & borrow); chain = (chain + out->limb[i]) + (p->limb[i] & borrow);
out->limb[i] = chain; out->limb[i] = chain;
chain >>= WBITS; chain >>= WBITS;
} }
} }


sv decaf_montmul (
decaf_scalar_t out,
const decaf_scalar_t a,
const decaf_scalar_t b,
const decaf_scalar_t p,
sv decaf_448_montmul (
decaf_448_scalar_t out,
const decaf_448_scalar_t a,
const decaf_448_scalar_t b,
const decaf_448_scalar_t p,
decaf_word_t montgomery_factor decaf_word_t montgomery_factor
) { ) {
unsigned int i,j; unsigned int i,j;
decaf_word_t accum[DECAF_SCALAR_LIMBS+1] = {0};
decaf_word_t accum[DECAF_448_SCALAR_LIMBS+1] = {0};
decaf_word_t hi_carry = 0; decaf_word_t hi_carry = 0;
for (i=0; i<DECAF_SCALAR_LIMBS; i++) {
for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
decaf_word_t mand = a->limb[i]; decaf_word_t mand = a->limb[i];
const decaf_word_t *mier = b->limb; const decaf_word_t *mier = b->limb;
decaf_dword_t chain = 0; decaf_dword_t chain = 0;
for (j=0; j<DECAF_SCALAR_LIMBS; j++) {
for (j=0; j<DECAF_448_SCALAR_LIMBS; j++) {
chain += ((decaf_dword_t)mand)*mier[j] + accum[j]; chain += ((decaf_dword_t)mand)*mier[j] + accum[j];
accum[j] = chain; accum[j] = chain;
chain >>= WBITS; chain >>= WBITS;
@@ -311,7 +311,7 @@ sv decaf_montmul (
mand = accum[0] * montgomery_factor; mand = accum[0] * montgomery_factor;
chain = 0; chain = 0;
mier = p->limb; mier = p->limb;
for (j=0; j<DECAF_SCALAR_LIMBS; j++) {
for (j=0; j<DECAF_448_SCALAR_LIMBS; j++) {
chain += (decaf_dword_t)mand*mier[j] + accum[j]; chain += (decaf_dword_t)mand*mier[j] + accum[j];
if (j) accum[j-1] = chain; if (j) accum[j-1] = chain;
chain >>= WBITS; chain >>= WBITS;
@@ -322,58 +322,58 @@ sv decaf_montmul (
hi_carry = chain >> WBITS; hi_carry = chain >> WBITS;
} }
decaf_subx(out, accum, p, p, hi_carry);
decaf_448_subx(out, accum, p, p, hi_carry);
} }


void decaf_scalar_mul (
decaf_scalar_t out,
const decaf_scalar_t a,
const decaf_scalar_t b
void decaf_448_scalar_mul (
decaf_448_scalar_t out,
const decaf_448_scalar_t a,
const decaf_448_scalar_t b
) { ) {
decaf_montmul(out,a,b,decaf_scalar_p,DECAF_MONTGOMERY_FACTOR);
decaf_montmul(out,out,decaf_scalar_r2,decaf_scalar_p,DECAF_MONTGOMERY_FACTOR);
decaf_448_montmul(out,a,b,decaf_448_scalar_p,DECAF_MONTGOMERY_FACTOR);
decaf_448_montmul(out,out,decaf_448_scalar_r2,decaf_448_scalar_p,DECAF_MONTGOMERY_FACTOR);
} }


void decaf_scalar_sub (
decaf_scalar_t out,
const decaf_scalar_t a,
const decaf_scalar_t b
void decaf_448_scalar_sub (
decaf_448_scalar_t out,
const decaf_448_scalar_t a,
const decaf_448_scalar_t b
) { ) {
decaf_subx(out, a->limb, b, decaf_scalar_p, 0);
decaf_448_subx(out, a->limb, b, decaf_448_scalar_p, 0);
} }


void decaf_scalar_add (
decaf_scalar_t out,
const decaf_scalar_t a,
const decaf_scalar_t b
void decaf_448_scalar_add (
decaf_448_scalar_t out,
const decaf_448_scalar_t a,
const decaf_448_scalar_t b
) { ) {
decaf_dword_t chain = 0; decaf_dword_t chain = 0;
unsigned int i; unsigned int i;
for (i=0; i<DECAF_SCALAR_LIMBS; i++) {
for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
chain = (chain + a->limb[i]) + b->limb[i]; chain = (chain + a->limb[i]) + b->limb[i];
out->limb[i] = chain; out->limb[i] = chain;
chain >>= WBITS; chain >>= WBITS;
} }
decaf_subx(out, out->limb, decaf_scalar_p, decaf_scalar_p, chain);
decaf_448_subx(out, out->limb, decaf_448_scalar_p, decaf_448_scalar_p, chain);
} }


void decaf_scalar_copy (
decaf_scalar_t out,
const decaf_scalar_t a
void decaf_448_scalar_copy (
decaf_448_scalar_t out,
const decaf_448_scalar_t a
) { ) {
unsigned int i; unsigned int i;
for (i=0; i<DECAF_SCALAR_LIMBS; i++) {
for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
out->limb[i] = a->limb[i]; out->limb[i] = a->limb[i];
} }
} }


decaf_bool_t decaf_scalar_eq (
const decaf_scalar_t a,
const decaf_scalar_t b
decaf_bool_t decaf_448_scalar_eq (
const decaf_448_scalar_t a,
const decaf_448_scalar_t b
) { ) {
decaf_word_t diff = 0; decaf_word_t diff = 0;
unsigned int i; unsigned int i;
for (i=0; i<DECAF_SCALAR_LIMBS; i++) {
for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
diff |= a->limb[i] ^ b->limb[i]; diff |= a->limb[i] ^ b->limb[i];
} }
return (((decaf_dword_t)diff)-1)>>WBITS; return (((decaf_dword_t)diff)-1)>>WBITS;
@@ -382,9 +382,9 @@ decaf_bool_t decaf_scalar_eq (
/* *** API begins here *** */ /* *** API begins here *** */


/** identity = (0,1) */ /** identity = (0,1) */
const decaf_point_t decaf_point_identity = {{{0},{1},{1},{0}}};
const decaf_448_point_t decaf_448_point_identity = {{{0},{1},{1},{0}}};


void decaf_point_encode( unsigned char ser[DECAF_SER_BYTES], const decaf_point_t p ) {
void decaf_448_point_encode( unsigned char ser[DECAF_448_SER_BYTES], const decaf_448_point_t p ) {
/* Can shave off one mul here; not important but makes consistent with paper */ /* Can shave off one mul here; not important but makes consistent with paper */
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 );
@@ -409,9 +409,9 @@ void decaf_point_encode( unsigned char ser[DECAF_SER_BYTES], const decaf_point_t
gf_canon(a); gf_canon(a);
int i, k=0, bits=0; int i, k=0, bits=0;
decaf_dword_t buf=0; decaf_dword_t buf=0;
for (i=0; i<DECAF_LIMBS; i++) {
for (i=0; i<DECAF_448_LIMBS; i++) {
buf |= (decaf_dword_t)a[i]<<bits; buf |= (decaf_dword_t)a[i]<<bits;
for (bits += LBITS; (bits>=8 || i==DECAF_LIMBS-1) && k<DECAF_SER_BYTES; bits-=8, buf>>=8) {
for (bits += LBITS; (bits>=8 || i==DECAF_448_LIMBS-1) && k<DECAF_448_SER_BYTES; bits-=8, buf>>=8) {
ser[k++]=buf; ser[k++]=buf;
} }
} }
@@ -420,12 +420,12 @@ void decaf_point_encode( unsigned char ser[DECAF_SER_BYTES], const decaf_point_t
/** /**
* Deserialize a bool, return TRUE if < p. * Deserialize a bool, return TRUE if < p.
*/ */
static decaf_bool_t gf_deser(gf s, const unsigned char ser[DECAF_SER_BYTES]) {
static decaf_bool_t gf_deser(gf s, const unsigned char ser[DECAF_448_SER_BYTES]) {
unsigned int i, k=0, bits=0; unsigned int i, k=0, bits=0;
decaf_dword_t buf=0; decaf_dword_t buf=0;
for (i=0; i<DECAF_SER_BYTES; i++) {
for (i=0; i<DECAF_448_SER_BYTES; i++) {
buf |= (decaf_dword_t)ser[i]<<bits; buf |= (decaf_dword_t)ser[i]<<bits;
for (bits += 8; (bits>=LBITS || i==DECAF_SER_BYTES-1) && k<DECAF_LIMBS; bits-=LBITS, buf>>=LBITS) {
for (bits += 8; (bits>=LBITS || i==DECAF_448_SER_BYTES-1) && k<DECAF_448_LIMBS; bits-=LBITS, buf>>=LBITS) {
s[k++] = buf & LMASK; s[k++] = buf & LMASK;
} }
} }
@@ -436,10 +436,10 @@ 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_point_add_sub (
decaf_point_t p,
const decaf_point_t q,
const decaf_point_t r,
sv decaf_448_point_add_sub (
decaf_448_point_t p,
const decaf_448_point_t q,
const decaf_448_point_t r,
decaf_bool_t do_sub decaf_bool_t do_sub
) { ) {
/* Twisted Edward formulas, complete when 4-torsion isn't involved */ /* Twisted Edward formulas, complete when 4-torsion isn't involved */
@@ -466,9 +466,9 @@ sv decaf_point_add_sub (
gf_mul ( p->t, b, c ); gf_mul ( p->t, b, c );
} }
decaf_bool_t decaf_point_decode (
decaf_point_t p,
const unsigned char ser[DECAF_SER_BYTES],
decaf_bool_t decaf_448_point_decode (
decaf_448_point_t p,
const unsigned char ser[DECAF_448_SER_BYTES],
decaf_bool_t allow_identity decaf_bool_t allow_identity
) { ) {
gf s, a, b, c, d, e; gf s, a, b, c, d, e;
@@ -499,22 +499,22 @@ decaf_bool_t decaf_point_decode (
return succ; return succ;
} }


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_448_point_sub(decaf_448_point_t a, const decaf_448_point_t b, const decaf_448_point_t c) {
decaf_448_point_add_sub(a,b,c,-1);
} }
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);
void decaf_448_point_add(decaf_448_point_t a, const decaf_448_point_t b, const decaf_448_point_t c) {
decaf_448_point_add_sub(a,b,c,0);
} }


/* No dedicated point double yet (PERF) */ /* No dedicated point double yet (PERF) */
void decaf_point_double(decaf_point_t a, const decaf_point_t b) {
decaf_point_add(a,b,b);
void decaf_448_point_double(decaf_448_point_t a, const decaf_448_point_t b) {
decaf_448_point_add(a,b,b);
} }


void decaf_point_copy (
decaf_point_t a,
const decaf_point_t b
void decaf_448_point_copy (
decaf_448_point_t a,
const decaf_448_point_t b
) { ) {
gf_cpy(a->x, b->x); gf_cpy(a->x, b->x);
gf_cpy(a->y, b->y); gf_cpy(a->y, b->y);
@@ -522,12 +522,12 @@ void decaf_point_copy (
gf_cpy(a->t, b->t); gf_cpy(a->t, b->t);
} }


decaf_bool_t decaf_scalar_decode(
decaf_scalar_t s,
const unsigned char ser[DECAF_SER_BYTES]
decaf_bool_t decaf_448_scalar_decode(
decaf_448_scalar_t s,
const unsigned char ser[DECAF_448_SER_BYTES]
) { ) {
unsigned int i,j,k=0; unsigned int i,j,k=0;
for (i=0; i<DECAF_SCALAR_LIMBS; i++) {
for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
decaf_word_t out = 0; decaf_word_t out = 0;
for (j=0; j<sizeof(decaf_word_t); j++,k++) { for (j=0; j<sizeof(decaf_word_t); j++,k++) {
out |= ((decaf_word_t)ser[k])<<(8*j); out |= ((decaf_word_t)ser[k])<<(8*j);
@@ -536,93 +536,93 @@ decaf_bool_t decaf_scalar_decode(
} }
decaf_sdword_t accum = 0; decaf_sdword_t accum = 0;
for (i=0; i<DECAF_SCALAR_LIMBS; i++) {
accum = (accum + s->limb[i] - decaf_scalar_p->limb[i]) >> WBITS;
for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
accum = (accum + s->limb[i] - decaf_448_scalar_p->limb[i]) >> WBITS;
} }
decaf_scalar_mul(s,s,decaf_scalar_one); /* ham-handed reduce */
decaf_448_scalar_mul(s,s,decaf_448_scalar_one); /* ham-handed reduce */
return accum; return accum;
} }


void decaf_scalar_encode(
unsigned char ser[DECAF_SER_BYTES],
const decaf_scalar_t s
void decaf_448_scalar_encode(
unsigned char ser[DECAF_448_SER_BYTES],
const decaf_448_scalar_t s
) { ) {
unsigned int i,j,k=0; unsigned int i,j,k=0;
for (i=0; i<DECAF_SCALAR_LIMBS; i++) {
for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
for (j=0; j<sizeof(decaf_word_t); j++,k++) { for (j=0; j<sizeof(decaf_word_t); j++,k++) {
ser[k] = s->limb[i] >> (8*j); ser[k] = s->limb[i] >> (8*j);
} }
} }
} }


void decaf_point_scalarmul (
decaf_point_t a,
const decaf_point_t b,
const decaf_scalar_t scalar
void decaf_448_point_scalarmul (
decaf_448_point_t a,
const decaf_448_point_t b,
const decaf_448_scalar_t scalar
) { ) {
/* 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.
*/ */
decaf_point_t w,b3,tmp;
decaf_point_double(w,b);
decaf_448_point_t w,b3,tmp;
decaf_448_point_double(w,b);
/* b3 = b*3 */ /* b3 = b*3 */
decaf_point_add(b3,w,b);
decaf_448_point_add(b3,w,b);
int i; int i;
for (i=DECAF_SCALAR_BITS &~ 1; i>0; i-=2) {
for (i=DECAF_448_SCALAR_BITS &~ 1; i>0; i-=2) {
decaf_word_t bits = scalar->limb[i/WBITS]>>(i%WBITS); decaf_word_t bits = scalar->limb[i/WBITS]>>(i%WBITS);
decaf_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1);
decaf_point_double(w,w);
decaf_point_add_sub(w,w,tmp,((bits>>1)&1)-1);
decaf_point_double(w,w);
decaf_448_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1);
decaf_448_point_double(w,w);
decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1);
decaf_448_point_double(w,w);
} }
decaf_point_add_sub(w,w,b,((scalar->limb[0]>>1)&1)-1);
decaf_448_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_point_identity,-(scalar->limb[0]&1));
decaf_point_sub(a,w,tmp);
decaf_448_cond_sel(tmp,b,decaf_448_point_identity,-(scalar->limb[0]&1));
decaf_448_point_sub(a,w,tmp);
} }


void decaf_point_double_scalarmul (
decaf_point_t a,
const decaf_point_t b,
const decaf_scalar_t scalarb,
const decaf_point_t c,
const decaf_scalar_t scalarc
void decaf_448_point_double_scalarmul (
decaf_448_point_t a,
const decaf_448_point_t b,
const decaf_448_scalar_t scalarb,
const decaf_448_point_t c,
const decaf_448_scalar_t scalarc
) { ) {
/* 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
* possibly-odd number of unmasked bits, may need to mask. * possibly-odd number of unmasked bits, may need to mask.
*/ */
decaf_point_t w,b3,c3,tmp;
decaf_point_double(w,b);
decaf_point_double(tmp,c);
decaf_448_point_t w,b3,c3,tmp;
decaf_448_point_double(w,b);
decaf_448_point_double(tmp,c);
/* b3 = b*3 */ /* b3 = b*3 */
decaf_point_add(b3,w,b);
decaf_point_add(c3,tmp,c);
decaf_point_add(w,w,tmp);
decaf_448_point_add(b3,w,b);
decaf_448_point_add(c3,tmp,c);
decaf_448_point_add(w,w,tmp);
int i; int i;
for (i=DECAF_SCALAR_BITS &~ 1; i>0; i-=2) {
decaf_point_double(w,w);
for (i=DECAF_448_SCALAR_BITS &~ 1; i>0; i-=2) {
decaf_448_point_double(w,w);
decaf_word_t bits = scalarb->limb[i/WBITS]>>(i%WBITS); decaf_word_t bits = scalarb->limb[i/WBITS]>>(i%WBITS);
decaf_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1);
decaf_point_add_sub(w,w,tmp,((bits>>1)&1)-1);
decaf_448_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1);
decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1);
bits = scalarc->limb[i/WBITS]>>(i%WBITS); bits = scalarc->limb[i/WBITS]>>(i%WBITS);
decaf_cond_sel(tmp,c,c3,((bits^(bits>>1))&1)-1);
decaf_point_add_sub(w,w,tmp,((bits>>1)&1)-1);
decaf_point_double(w,w);
decaf_448_cond_sel(tmp,c,c3,((bits^(bits>>1))&1)-1);
decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1);
decaf_448_point_double(w,w);
} }
decaf_point_add_sub(w,w,b,((scalarb->limb[0]>>1)&1)-1);
decaf_point_add_sub(w,w,c,((scalarc->limb[0]>>1)&1)-1);
decaf_448_point_add_sub(w,w,b,((scalarb->limb[0]>>1)&1)-1);
decaf_448_point_add_sub(w,w,c,((scalarc->limb[0]>>1)&1)-1);
/* low bit is special because of signed window */ /* low bit is special because of signed window */
decaf_cond_sel(tmp,b,decaf_point_identity,-(scalarb->limb[0]&1));
decaf_point_sub(w,w,tmp);
decaf_cond_sel(tmp,c,decaf_point_identity,-(scalarc->limb[0]&1));
decaf_point_sub(a,w,tmp);
decaf_448_cond_sel(tmp,b,decaf_448_point_identity,-(scalarb->limb[0]&1));
decaf_448_point_sub(w,w,tmp);
decaf_448_cond_sel(tmp,c,decaf_448_point_identity,-(scalarc->limb[0]&1));
decaf_448_point_sub(a,w,tmp);
} }


decaf_bool_t decaf_point_eq ( const decaf_point_t p, const decaf_point_t q ) {
decaf_bool_t decaf_448_point_eq ( const decaf_448_point_t p, const decaf_448_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 );
@@ -630,9 +630,9 @@ decaf_bool_t decaf_point_eq ( const decaf_point_t p, const decaf_point_t q ) {
return gf_eq(a,b); return gf_eq(a,b);
} }


void decaf_point_from_hash_nonuniform (
decaf_point_t p,
const unsigned char ser[DECAF_SER_BYTES]
void decaf_448_point_from_hash_nonuniform (
decaf_448_point_t p,
const unsigned char ser[DECAF_448_SER_BYTES]
) { ) {
gf r,urr,a,b,c,dee,e,ur2_d,udr2_1; gf r,urr,a,b,c,dee,e,ur2_d,udr2_1;
(void)gf_deser(r,ser); (void)gf_deser(r,ser);
@@ -670,18 +670,18 @@ void decaf_point_from_hash_nonuniform (
gf_mul(p->t,b,e); gf_mul(p->t,b,e);
} }


void decaf_point_from_hash_uniform (
decaf_point_t pt,
const unsigned char hashed_data[2*DECAF_SER_BYTES]
void decaf_448_point_from_hash_uniform (
decaf_448_point_t pt,
const unsigned char hashed_data[2*DECAF_448_SER_BYTES]
) { ) {
decaf_point_t 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_448_point_t pt2;
decaf_448_point_from_hash_nonuniform(pt,hashed_data);
decaf_448_point_from_hash_nonuniform(pt2,&hashed_data[DECAF_448_SER_BYTES]);
decaf_448_point_add(pt,pt,pt2);
} }


decaf_bool_t decaf_point_valid (
const decaf_point_t p
decaf_bool_t decaf_448_point_valid (
const decaf_448_point_t p
) { ) {
gf a,b,c; gf a,b,c;
gf_mul(a,p->x,p->y); gf_mul(a,p->x,p->y);


+ 6
- 6
test/bench.c View File

@@ -266,12 +266,12 @@ int main(int argc, char **argv) {
when = now() - when; when = now() - when;
printf("barrett mac: %5.1fns\n", when * 1e9 / i); printf("barrett mac: %5.1fns\n", when * 1e9 / i);
decaf_scalar_t asc,bsc,csc;
decaf_448_scalar_t asc,bsc,csc;
memset(asc,0,sizeof(asc)); memset(asc,0,sizeof(asc));
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_scalar_mul(csc,asc,bsc);
decaf_448_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);
@@ -296,13 +296,13 @@ int main(int argc, char **argv) {
when = now() - when; when = now() - when;
printf("txt + txt : %5.1fns\n", when * 1e9 / i); printf("txt + txt : %5.1fns\n", when * 1e9 / i);


decaf_point_t Da,Db,Dc;
decaf_448_point_t Da,Db,Dc;
memset(Da,0,sizeof(Da)); memset(Da,0,sizeof(Da));
memset(Db,0,sizeof(Db)); memset(Db,0,sizeof(Db));
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_point_add(Da,Db,Dc);
decaf_448_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,14 +368,14 @@ 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_point_scalarmul(Da,Db,asc);
decaf_448_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);
when = now(); when = now();
for (i=0; i<nbase/10; i++) { for (i=0; i<nbase/10; i++) {
decaf_point_double_scalarmul(Da,Db,bsc,Dc,asc);
decaf_448_point_double_scalarmul(Da,Db,bsc,Dc,asc);
} }
when = now() - when; when = now() - when;
printf("decaf slo2: %5.1fµs\n", when * 1e6 / i); printf("decaf slo2: %5.1fµs\n", when * 1e6 / i);


+ 18
- 18
test/test_arithmetic.c View File

@@ -8,13 +8,13 @@
mpz_t mp_field; mpz_t mp_field;
mpz_t mp_scalar_field; mpz_t mp_scalar_field;


static void decaf_scalar_print (
static void decaf_448_scalar_print (
const char *descr, const char *descr,
const decaf_scalar_t scalar
const decaf_448_scalar_t scalar
) { ) {
int j; int j;
printf("%s = 0x", descr); printf("%s = 0x", descr);
for (j=DECAF_SCALAR_LIMBS-1; j>=0; j--) {
for (j=DECAF_448_SCALAR_LIMBS-1; j>=0; j--) {
printf(PRIxWORDfull, scalar->limb[j]); printf(PRIxWORDfull, scalar->limb[j]);
} }
printf("\n"); printf("\n");
@@ -35,24 +35,24 @@ static mask_t mpz_to_field (
} }


static mask_t mpz_to_scalar ( static mask_t mpz_to_scalar (
decaf_scalar_t out,
decaf_448_scalar_t out,
const mpz_t in const mpz_t in
) { ) {
uint8_t ser[DECAF_SCALAR_BYTES];
uint8_t ser[DECAF_448_SCALAR_BYTES];
mpz_t modded; mpz_t modded;
memset(ser,0,sizeof(ser)); memset(ser,0,sizeof(ser));
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_scalar_decode(out, ser);
mask_t succ = decaf_448_scalar_decode(out, ser);
return succ; return succ;
} }


static mask_t scalar_assert_eq_gmp( static mask_t scalar_assert_eq_gmp(
const char *descr, const char *descr,
const decaf_scalar_t a,
const decaf_scalar_t b,
const decaf_scalar_t x,
const decaf_448_scalar_t a,
const decaf_448_scalar_t b,
const decaf_448_scalar_t x,
const mpz_t ma, const mpz_t ma,
const mpz_t mb, const mpz_t mb,
const mpz_t y const mpz_t y
@@ -62,7 +62,7 @@ static mask_t scalar_assert_eq_gmp(
memset(yser,0,sizeof(yser)); memset(yser,0,sizeof(yser));
decaf_scalar_encode(xser, x);
decaf_448_scalar_encode(xser, x);
mpz_init(modded); mpz_init(modded);
mpz_mod(modded, y, mp_scalar_field); mpz_mod(modded, y, mp_scalar_field);
@@ -71,9 +71,9 @@ static mask_t scalar_assert_eq_gmp(
if (memcmp(xser,yser,FIELD_BYTES)) { if (memcmp(xser,yser,FIELD_BYTES)) {
youfail(); youfail();
printf(" Failed arithmetic test %s\n", descr); printf(" Failed arithmetic test %s\n", descr);
decaf_scalar_print(" a", a);
decaf_scalar_print(" b", b);
decaf_scalar_print(" decaf", x);
decaf_448_scalar_print(" a", a);
decaf_448_scalar_print(" b", b);
decaf_448_scalar_print(" decaf_448", x);
// printf(" gmpa = 0x"); // printf(" gmpa = 0x");
int j; int j;
@@ -217,22 +217,22 @@ static mask_t test_scalar (
const mpz_t x, const mpz_t x,
const mpz_t y const mpz_t y
) { ) {
decaf_scalar_t xx,yy,tt;
decaf_448_scalar_t xx,yy,tt;
mpz_t t; mpz_t t;
mask_t succ = MASK_SUCCESS; mask_t succ = MASK_SUCCESS;
succ = mpz_to_scalar(xx,x); succ = mpz_to_scalar(xx,x);
succ &= mpz_to_scalar(yy,y); succ &= mpz_to_scalar(yy,y);
mpz_init(t); mpz_init(t);
decaf_scalar_add(tt,xx,yy);
decaf_448_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_scalar_sub(tt,xx,yy);
decaf_448_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_scalar_mul(tt,xx,yy);
decaf_448_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);
@@ -322,7 +322,7 @@ int test_arithmetic (void) {
mpz_init(mp_field); mpz_init(mp_field);
mpz_import(mp_field, FIELD_BYTES, -1, 1, -1, 0, FIELD_MODULUS); mpz_import(mp_field, FIELD_BYTES, -1, 1, -1, 0, FIELD_MODULUS);
mpz_import(mp_scalar_field, DECAF_SCALAR_LIMBS, -1, sizeof(decaf_word_t), -1, 0, decaf_scalar_p);
mpz_import(mp_scalar_field, DECAF_448_SCALAR_LIMBS, -1, sizeof(decaf_word_t), -1, 0, decaf_448_scalar_p);
mpz_t x,y; mpz_t x,y;
mpz_init(x); mpz_init(x);


+ 21
- 21
test/test_pointops.c View File

@@ -157,14 +157,14 @@ add_double_test (
copy_tw_extensible(&textb, &text1); copy_tw_extensible(&textb, &text1);
add_tw_pniels_to_tw_extensible(&textb, &pn); add_tw_pniels_to_tw_extensible(&textb, &pn);


decaf_point_t ted3;
decaf_448_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_point_add(ted3, (struct decaf_point_s*)&ted1, (struct decaf_point_s*)&ted2);
decaf_448_point_add(ted3, (struct decaf_448_point_s*)&ted1, (struct decaf_448_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_point_eq((struct decaf_point_s*)&ted1, ted3)) {
if (~decaf_eq_tw_extended(&ted1, &ted2) | ~decaf_448_point_eq((struct decaf_448_point_s*)&ted1, ted3)) {
youfail(); youfail();
succ = 0; succ = 0;
printf(" Tw extended simple compat:\n"); printf(" Tw extended simple compat:\n");
@@ -362,13 +362,13 @@ int test_decaf_evil (void) {
decaf_serialize_tw_extended(out_ed, pt_ed); decaf_serialize_tw_extended(out_ed, pt_ed);
uint8_t ser_de[56], ser_ed[56]; uint8_t ser_de[56], ser_ed[56];
decaf_point_t pt_dec, pt_dec2;
decaf_448_point_t pt_dec, pt_dec2;
memcpy(pt_dec, pt_ed, sizeof(pt_dec)); memcpy(pt_dec, pt_ed, sizeof(pt_dec));
decaf_point_encode(ser_de, pt_dec);
mask_t succ_dec = decaf_point_decode(pt_dec2, ser_de, -1);
decaf_448_point_encode(ser_de, pt_dec);
mask_t succ_dec = decaf_448_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_448_point_t p,q,m;
uint8_t oo_base_ser[56], n_base_ser[56]; uint8_t oo_base_ser[56], n_base_ser[56];
field_a_t oo_base,tmp,tmp2; field_a_t oo_base,tmp,tmp2;
field_isr(tmp,base); field_isr(tmp,base);
@@ -378,17 +378,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_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);
decaf_448_point_from_hash_nonuniform (p,random_input);
decaf_448_point_from_hash_nonuniform (q,oo_base_ser);
decaf_448_point_from_hash_nonuniform (m,n_base_ser);
mask_t succ_nur = decaf_448_point_valid(p);
succ_nur &= decaf_448_point_valid(q);
succ_nur &= decaf_448_point_valid(m);
mask_t eq_neg, eq_pos; mask_t eq_neg, eq_pos;
eq_neg = decaf_point_eq(m,p);
decaf_point_add(m,p,q);
eq_pos = decaf_point_eq(m,decaf_point_identity);
eq_neg = decaf_448_point_eq(m,p);
decaf_448_point_add(m,p,q);
eq_pos = decaf_448_point_eq(m,decaf_448_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
@@ -396,9 +396,9 @@ 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_point_eq(pt_dec, pt_dec2)
|| (s_e & ~decaf_point_valid(pt_dec))
|| (succ_dec & ~decaf_point_valid(pt_dec2))
|| (s_e & ~decaf_448_point_eq(pt_dec, pt_dec2)
|| (s_e & ~decaf_448_point_valid(pt_dec))
|| (succ_dec & ~decaf_448_point_valid(pt_dec2))
|| ~succ_nur || ~succ_nur
|| ~eq_neg || ~eq_neg
|| ~eq_pos) || ~eq_pos)
@@ -436,13 +436,13 @@ int test_decaf (void) {
int i, hits = 0, fails = 0; int i, hits = 0, fails = 0;
if (~decaf_point_valid(decaf_point_base)) {
if (~decaf_448_point_valid(decaf_448_point_base)) {
youfail(); youfail();
printf(" Decaf base point invalid\n"); printf(" Decaf base point invalid\n");
fails++; fails++;
} }
if (~decaf_point_valid(decaf_point_identity)) {
if (~decaf_448_point_valid(decaf_448_point_identity)) {
youfail(); youfail();
printf(" Decaf identity point invalid\n"); printf(" Decaf identity point invalid\n");
fails++; fails++;


+ 4
- 4
test/test_scalarmul.c View File

@@ -111,10 +111,10 @@ single_scalarmul_compatibility_test (
scalarmul_vt(&work, scalar, nbits); scalarmul_vt(&work, scalar, nbits);
untwist_and_double_and_serialize(vt, &work); untwist_and_double_and_serialize(vt, &work);
decaf_point_t ed2;
decaf_448_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_point_scalarmul(ed2, (struct decaf_point_s *)ed, (struct decaf_scalar_s *)scalar);
decaf_448_point_scalarmul(ed2, (struct decaf_448_point_s *)ed, (struct decaf_448_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_point_encode(ser1, (struct decaf_point_s *)ed);
decaf_point_encode(ser2, ed2);
decaf_448_point_encode(ser1, (struct decaf_448_point_s *)ed);
decaf_448_point_encode(ser2, ed2);


/* check consistency mont vs window */ /* check consistency mont vs window */
consistent &= field_eq(mont, ct); consistent &= field_eq(mont, ct);


Loading…
Cancel
Save