| @@ -3,7 +3,6 @@ | |||
| * @brief Example Decaf crypto routines | |||
| */ | |||
| #include "f_field.h" /* for SER_BYTES; FUTURE: find a better way to do this? */ | |||
| #include <decaf/crypto.h> | |||
| #include <string.h> | |||
| @@ -11,6 +10,7 @@ | |||
| #define API_NS(_id) $(c_ns)_##_id | |||
| #define SCALAR_BITS $(C_NS)_SCALAR_BITS | |||
| #define SCALAR_BYTES ((SCALAR_BITS + 7)/8) | |||
| #define SER_BYTES $(C_NS)_SER_BYTES | |||
| /* TODO: canonicalize and freeze the STROBE constants in this file | |||
| * (and STROBE itself for that matter) | |||
| @@ -1076,7 +1076,7 @@ void API_NS(point_encode_like_eddsa) ( | |||
| gf_add( u, x, t ); // x^2 + y^2 | |||
| gf_add( z, q->y, q->x ); | |||
| gf_sqr ( y, z); | |||
| gf_sub ( y, y, u ); // 2xy | |||
| gf_sub ( y, u, y ); // -2xy | |||
| gf_sub ( z, t, x ); // y^2 - x^2 | |||
| gf_sqr ( x, q->z ); | |||
| gf_add ( t, x, x); | |||
| @@ -1093,7 +1093,7 @@ void API_NS(point_encode_like_eddsa) ( | |||
| { | |||
| API_NS(point_double)(q,q); | |||
| API_NS(point_double)(q,q); | |||
| gf_div_qnr(x, q->x); | |||
| gf_mul_qnr(x, q->x); | |||
| gf_copy(y, q->y); | |||
| gf_copy(z, q->z); | |||
| } | |||
| @@ -1106,7 +1106,7 @@ void API_NS(point_encode_like_eddsa) ( | |||
| gf_add( u, x, t ); | |||
| gf_add( z, q->y, q->x ); | |||
| gf_sqr ( y, z); | |||
| gf_sub ( y, y, u ); | |||
| gf_sub ( y, u, y ); | |||
| gf_sub ( z, t, x ); | |||
| gf_sqr ( x, q->z ); | |||
| gf_add ( t, x, x); | |||
| @@ -1167,7 +1167,7 @@ decaf_error_t API_NS(point_decode_like_eddsa) ( | |||
| succ &= gf_isr(p->t,p->x); /* 1/sqrt(num * denom) */ | |||
| gf_mul(p->x,p->t,p->z); /* sqrt(num / denom) */ | |||
| gf_cond_neg(p->x,gf_lobit(p->x)^low); | |||
| gf_cond_neg(p->x,~gf_lobit(p->x)^low); | |||
| gf_copy(p->z,ONE); | |||
| #if EDDSA_USE_SIGMA_ISOGENY | |||
| @@ -679,7 +679,6 @@ void $(c_ns)_scalar_destroy ( | |||
| /** | |||
| * @brief Overwrite point with zeros. | |||
| * @todo Use this internally. | |||
| */ | |||
| void $(c_ns)_point_destroy ( | |||
| $(c_ns)_point_t point | |||
| @@ -23,7 +23,7 @@ | |||
| #define EDDSA_USE_SIGMA_ISOGENY $(eddsa_sigma_iso) | |||
| #define COFACTOR $(cofactor) | |||
| static void clamp( | |||
| static void clamp ( | |||
| uint8_t secret_scalar_ser[$(C_NS)_EDDSA_PRIVATE_BYTES] | |||
| ) { | |||
| /* Blarg */ | |||
| @@ -78,9 +78,8 @@ void API_NS(eddsa_derive_public_key) ( | |||
| API_NS(scalar_t) secret_scalar; | |||
| API_NS(scalar_decode_long)(secret_scalar, secret_scalar_ser, sizeof(secret_scalar_ser)); | |||
| /* TODO: write documentation for why (due to isogenies) this needs to be quartered */ | |||
| API_NS(scalar_sub)(secret_scalar,API_NS(scalar_zero),secret_scalar); | |||
| /* TODO: write documentation for why (due to isogenies) this needs to be quartered/eighthed */ | |||
| for (unsigned int c = 1; c < COFACTOR/(1+EDDSA_USE_SIGMA_ISOGENY); c <<= 1) { | |||
| API_NS(scalar_halve)(secret_scalar,secret_scalar); | |||
| } | |||
| @@ -149,9 +148,8 @@ void API_NS(eddsa_sign) ( | |||
| { | |||
| /* Scalarmul to create the nonce-point */ | |||
| API_NS(scalar_t) nonce_scalar_2; | |||
| API_NS(scalar_sub)(nonce_scalar_2,API_NS(scalar_zero),nonce_scalar); | |||
| for (unsigned int c = 1; c < COFACTOR/(1+EDDSA_USE_SIGMA_ISOGENY); c <<= 1) { | |||
| API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar); | |||
| for (unsigned int c = 2; c < COFACTOR/(1+EDDSA_USE_SIGMA_ISOGENY); c <<= 1) { | |||
| API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2); | |||
| } | |||
| @@ -233,7 +231,6 @@ decaf_error_t API_NS(eddsa_verify) ( | |||
| &signature[$(C_NS)_EDDSA_PUBLIC_BYTES], | |||
| $(C_NS)_EDDSA_PRIVATE_BYTES | |||
| ); | |||
| API_NS(scalar_sub)(response_scalar, API_NS(scalar_zero), response_scalar); /* TODO because nega-base point */ | |||
| #if EDDSA_USE_SIGMA_ISOGENY | |||
| API_NS(scalar_add)(response_scalar,response_scalar,response_scalar); | |||
| #endif | |||
| @@ -68,8 +68,10 @@ void decaf_sha3_update ( | |||
| * @param [inout] sponge The context. | |||
| * @param [out] out The output data. | |||
| * @param [in] len The requested output data length in bytes. | |||
| * @return DECAF_FAILURE if the sponge has exhausted its output capacity. | |||
| * @return DECAF_SUCCESS otherwise. | |||
| */ | |||
| void decaf_sha3_output ( | |||
| decaf_error_t decaf_sha3_output ( | |||
| decaf_keccak_sponge_t sponge, | |||
| uint8_t * __restrict__ out, | |||
| size_t len | |||
| @@ -83,7 +85,7 @@ void decaf_sha3_output ( | |||
| * @param [out] out The output data. | |||
| * @param [in] len The requested output data length in bytes. | |||
| */ | |||
| void decaf_sha3_final ( | |||
| decaf_error_t decaf_sha3_final ( | |||
| decaf_keccak_sponge_t sponge, | |||
| uint8_t * __restrict__ out, | |||
| size_t len | |||
| @@ -58,7 +58,9 @@ public: | |||
| inline SecureBuffer output(size_t len) throw(std::bad_alloc, LengthException) { | |||
| if (len > max_output_size()) throw LengthException(); | |||
| SecureBuffer buffer(len); | |||
| decaf_sha3_output(sp,buffer.data(),len); | |||
| if (DECAF_SUCCESS != decaf_sha3_output(sp,buffer.data(),len)) { | |||
| throw LengthException(); | |||
| } | |||
| return buffer; | |||
| } | |||
| @@ -66,21 +68,28 @@ public: | |||
| inline SecureBuffer final(size_t len) throw(std::bad_alloc, LengthException) { | |||
| if (len > max_output_size()) throw LengthException(); | |||
| SecureBuffer buffer(len); | |||
| decaf_sha3_final(sp,buffer.data(),len); | |||
| if (DECAF_SUCCESS != decaf_sha3_final(sp,buffer.data(),len)) { | |||
| throw LengthException(); | |||
| } | |||
| return buffer; | |||
| } | |||
| /** | |||
| * @brief Output bytes from the sponge. | |||
| * @todo make this throw exceptions. | |||
| /** @brief Output bytes from the sponge. Throw LengthException if you've | |||
| * output too many bytes from a SHA-3 instance. | |||
| */ | |||
| inline void output(Buffer b) throw(LengthException) { | |||
| decaf_sha3_output(sp,b.data(),b.size()); | |||
| if (DECAF_SUCCESS != decaf_sha3_output(sp,b.data(),b.size())) { | |||
| throw LengthException(); | |||
| } | |||
| } | |||
| /** @brief Output bytes from the sponge and reinitialize it. */ | |||
| /** @brief Output bytes from the sponge and reinitialize it. Throw | |||
| * LengthException if you've output too many bytes from a SHA3 instance. | |||
| */ | |||
| inline void final(Buffer b) throw(LengthException) { | |||
| decaf_sha3_final(sp,b.data(),b.size()); | |||
| if (DECAF_SUCCESS != decaf_sha3_final(sp,b.data(),b.size())) { | |||
| throw LengthException(); | |||
| } | |||
| } | |||
| /** @brief Return the sponge's default output size. */ | |||
| @@ -94,12 +103,12 @@ public: | |||
| } | |||
| /** Output the default number of bytes. */ | |||
| inline SecureBuffer output() throw(std::bad_alloc) { | |||
| inline SecureBuffer output() throw(std::bad_alloc,LengthException) { | |||
| return output(default_output_size()); | |||
| } | |||
| /** Output the default number of bytes, and reset hash. */ | |||
| inline SecureBuffer final() throw(std::bad_alloc) { | |||
| inline SecureBuffer final() throw(std::bad_alloc,LengthException) { | |||
| return final(default_output_size()); | |||
| } | |||
| @@ -165,17 +165,22 @@ void decaf_sha3_update ( | |||
| } | |||
| } | |||
| void decaf_sha3_output ( | |||
| decaf_error_t decaf_sha3_output ( | |||
| decaf_keccak_sponge_t decaf_sponge, | |||
| uint8_t * __restrict__ out, | |||
| size_t len | |||
| ) { | |||
| decaf_error_t ret = DECAF_SUCCESS; | |||
| assert(decaf_sponge->params->position < decaf_sponge->params->rate); | |||
| assert(decaf_sponge->params->rate < sizeof(decaf_sponge->state)); | |||
| if (decaf_sponge->params->max_out != 0xFF) { | |||
| assert(decaf_sponge->params->client >= len); | |||
| decaf_sponge->params->client -= len; | |||
| if (decaf_sponge->params->client >= len) { | |||
| decaf_sponge->params->client -= len; | |||
| } else { | |||
| decaf_sponge->params->client = 0; | |||
| ret = DECAF_FAILURE; | |||
| } | |||
| } | |||
| switch (decaf_sponge->params->flags) { | |||
| @@ -198,7 +203,7 @@ void decaf_sha3_output ( | |||
| if (cando > len) { | |||
| memcpy(out, state, len); | |||
| decaf_sponge->params->position += len; | |||
| return; | |||
| return ret; | |||
| } else { | |||
| memcpy(out, state, cando); | |||
| dokeccak(decaf_sponge); | |||
| @@ -206,15 +211,17 @@ void decaf_sha3_output ( | |||
| out += cando; | |||
| } | |||
| } | |||
| return ret; | |||
| } | |||
| void decaf_sha3_final ( | |||
| decaf_error_t decaf_sha3_final ( | |||
| decaf_keccak_sponge_t decaf_sponge, | |||
| uint8_t * __restrict__ out, | |||
| size_t len | |||
| ) { | |||
| decaf_sha3_output(decaf_sponge,out,len); | |||
| decaf_error_t ret = decaf_sha3_output(decaf_sponge,out,len); | |||
| decaf_sha3_reset(decaf_sponge); | |||
| return ret; | |||
| } | |||
| void decaf_sha3_reset ( | |||