| @@ -58,21 +58,18 @@ static void hash_init_with_dom( | |||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| uint8_t for_prehash, | uint8_t for_prehash, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) { | ) { | ||||
| hash_init(hash); | hash_init(hash); | ||||
| #if NO_CONTEXT | #if NO_CONTEXT | ||||
| if (no_context) { | |||||
| if (context_len == 0 && context == ED25519_NO_CONTEXT) { | |||||
| (void)prehashed; | (void)prehashed; | ||||
| (void)for_prehash; | (void)for_prehash; | ||||
| (void)context; | (void)context; | ||||
| (void)context_len; | (void)context_len; | ||||
| return; | return; | ||||
| } | } | ||||
| #else | |||||
| (void)no_context; | |||||
| #endif | #endif | ||||
| const char *dom_s = "SigEd25519 no Ed25519 collisions"; | const char *dom_s = "SigEd25519 no Ed25519 collisions"; | ||||
| const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len}; | const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len}; | ||||
| @@ -134,8 +131,7 @@ void decaf_ed25519_sign ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) { | ) { | ||||
| API_NS(scalar_t) secret_scalar; | API_NS(scalar_t) secret_scalar; | ||||
| hash_ctx_t hash; | hash_ctx_t hash; | ||||
| @@ -155,7 +151,7 @@ void decaf_ed25519_sign ( | |||||
| API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser)); | API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser)); | ||||
| /* Hash to create the nonce */ | /* Hash to create the nonce */ | ||||
| hash_init_with_dom(hash,prehashed,0,context,context_len,no_context); | |||||
| hash_init_with_dom(hash,prehashed,0,context,context_len); | |||||
| hash_update(hash,expanded.seed,sizeof(expanded.seed)); | hash_update(hash,expanded.seed,sizeof(expanded.seed)); | ||||
| hash_update(hash,message,message_len); | hash_update(hash,message,message_len); | ||||
| decaf_bzero(&expanded, sizeof(expanded)); | decaf_bzero(&expanded, sizeof(expanded)); | ||||
| @@ -189,7 +185,7 @@ void decaf_ed25519_sign ( | |||||
| API_NS(scalar_t) challenge_scalar; | API_NS(scalar_t) challenge_scalar; | ||||
| { | { | ||||
| /* Compute the challenge */ | /* Compute the challenge */ | ||||
| hash_init_with_dom(hash,prehashed,0,context,context_len,no_context); | |||||
| hash_init_with_dom(hash,prehashed,0,context,context_len); | |||||
| hash_update(hash,nonce_point,sizeof(nonce_point)); | hash_update(hash,nonce_point,sizeof(nonce_point)); | ||||
| hash_update(hash,pubkey,DECAF_EDDSA_25519_PUBLIC_BYTES); | hash_update(hash,pubkey,DECAF_EDDSA_25519_PUBLIC_BYTES); | ||||
| hash_update(hash,message,message_len); | hash_update(hash,message,message_len); | ||||
| @@ -229,7 +225,7 @@ void decaf_ed25519_sign_prehash ( | |||||
| hash_destroy(hash_too); | hash_destroy(hash_too); | ||||
| } | } | ||||
| decaf_ed25519_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len,0); | |||||
| decaf_ed25519_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len); | |||||
| decaf_bzero(hash_output,sizeof(hash_output)); | decaf_bzero(hash_output,sizeof(hash_output)); | ||||
| } | } | ||||
| @@ -240,8 +236,7 @@ decaf_error_t decaf_ed25519_verify ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) { | ) { | ||||
| API_NS(point_t) pk_point, r_point; | 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_ignore_cofactor)(pk_point,pubkey); | ||||
| @@ -254,7 +249,7 @@ decaf_error_t decaf_ed25519_verify ( | |||||
| { | { | ||||
| /* Compute the challenge */ | /* Compute the challenge */ | ||||
| hash_ctx_t hash; | hash_ctx_t hash; | ||||
| hash_init_with_dom(hash,prehashed,0,context,context_len,no_context); | |||||
| hash_init_with_dom(hash,prehashed,0,context,context_len); | |||||
| hash_update(hash,signature,DECAF_EDDSA_25519_PUBLIC_BYTES); | hash_update(hash,signature,DECAF_EDDSA_25519_PUBLIC_BYTES); | ||||
| hash_update(hash,pubkey,DECAF_EDDSA_25519_PUBLIC_BYTES); | hash_update(hash,pubkey,DECAF_EDDSA_25519_PUBLIC_BYTES); | ||||
| hash_update(hash,message,message_len); | hash_update(hash,message,message_len); | ||||
| @@ -305,7 +300,7 @@ decaf_error_t decaf_ed25519_verify_prehash ( | |||||
| hash_destroy(hash_too); | hash_destroy(hash_too); | ||||
| } | } | ||||
| ret = decaf_ed25519_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len,0); | |||||
| ret = decaf_ed25519_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len); | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -58,21 +58,18 @@ static void hash_init_with_dom( | |||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| uint8_t for_prehash, | uint8_t for_prehash, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) { | ) { | ||||
| hash_init(hash); | hash_init(hash); | ||||
| #if NO_CONTEXT | #if NO_CONTEXT | ||||
| if (no_context) { | |||||
| if (context_len == 0 && context == ED448_NO_CONTEXT) { | |||||
| (void)prehashed; | (void)prehashed; | ||||
| (void)for_prehash; | (void)for_prehash; | ||||
| (void)context; | (void)context; | ||||
| (void)context_len; | (void)context_len; | ||||
| return; | return; | ||||
| } | } | ||||
| #else | |||||
| (void)no_context; | |||||
| #endif | #endif | ||||
| const char *dom_s = "SigEd448"; | const char *dom_s = "SigEd448"; | ||||
| const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len}; | const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len}; | ||||
| @@ -134,8 +131,7 @@ void decaf_ed448_sign ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) { | ) { | ||||
| API_NS(scalar_t) secret_scalar; | API_NS(scalar_t) secret_scalar; | ||||
| hash_ctx_t hash; | hash_ctx_t hash; | ||||
| @@ -155,7 +151,7 @@ void decaf_ed448_sign ( | |||||
| API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser)); | API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser)); | ||||
| /* Hash to create the nonce */ | /* Hash to create the nonce */ | ||||
| hash_init_with_dom(hash,prehashed,0,context,context_len,no_context); | |||||
| hash_init_with_dom(hash,prehashed,0,context,context_len); | |||||
| hash_update(hash,expanded.seed,sizeof(expanded.seed)); | hash_update(hash,expanded.seed,sizeof(expanded.seed)); | ||||
| hash_update(hash,message,message_len); | hash_update(hash,message,message_len); | ||||
| decaf_bzero(&expanded, sizeof(expanded)); | decaf_bzero(&expanded, sizeof(expanded)); | ||||
| @@ -189,7 +185,7 @@ void decaf_ed448_sign ( | |||||
| API_NS(scalar_t) challenge_scalar; | API_NS(scalar_t) challenge_scalar; | ||||
| { | { | ||||
| /* Compute the challenge */ | /* Compute the challenge */ | ||||
| hash_init_with_dom(hash,prehashed,0,context,context_len,no_context); | |||||
| hash_init_with_dom(hash,prehashed,0,context,context_len); | |||||
| hash_update(hash,nonce_point,sizeof(nonce_point)); | hash_update(hash,nonce_point,sizeof(nonce_point)); | ||||
| hash_update(hash,pubkey,DECAF_EDDSA_448_PUBLIC_BYTES); | hash_update(hash,pubkey,DECAF_EDDSA_448_PUBLIC_BYTES); | ||||
| hash_update(hash,message,message_len); | hash_update(hash,message,message_len); | ||||
| @@ -229,7 +225,7 @@ void decaf_ed448_sign_prehash ( | |||||
| hash_destroy(hash_too); | hash_destroy(hash_too); | ||||
| } | } | ||||
| decaf_ed448_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len,0); | |||||
| decaf_ed448_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len); | |||||
| decaf_bzero(hash_output,sizeof(hash_output)); | decaf_bzero(hash_output,sizeof(hash_output)); | ||||
| } | } | ||||
| @@ -240,8 +236,7 @@ decaf_error_t decaf_ed448_verify ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) { | ) { | ||||
| API_NS(point_t) pk_point, r_point; | 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_ignore_cofactor)(pk_point,pubkey); | ||||
| @@ -254,7 +249,7 @@ decaf_error_t decaf_ed448_verify ( | |||||
| { | { | ||||
| /* Compute the challenge */ | /* Compute the challenge */ | ||||
| hash_ctx_t hash; | hash_ctx_t hash; | ||||
| hash_init_with_dom(hash,prehashed,0,context,context_len,no_context); | |||||
| hash_init_with_dom(hash,prehashed,0,context,context_len); | |||||
| hash_update(hash,signature,DECAF_EDDSA_448_PUBLIC_BYTES); | hash_update(hash,signature,DECAF_EDDSA_448_PUBLIC_BYTES); | ||||
| hash_update(hash,pubkey,DECAF_EDDSA_448_PUBLIC_BYTES); | hash_update(hash,pubkey,DECAF_EDDSA_448_PUBLIC_BYTES); | ||||
| hash_update(hash,message,message_len); | hash_update(hash,message,message_len); | ||||
| @@ -305,7 +300,7 @@ decaf_error_t decaf_ed448_verify_prehash ( | |||||
| hash_destroy(hash_too); | hash_destroy(hash_too); | ||||
| } | } | ||||
| ret = decaf_ed448_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len,0); | |||||
| ret = decaf_ed448_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len); | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -34,7 +34,8 @@ extern "C" { | |||||
| /** Does EdDSA support non-contextual signatures? */ | /** Does EdDSA support non-contextual signatures? */ | ||||
| #define DECAF_EDDSA_25519_NO_CONTEXT 1 | #define DECAF_EDDSA_25519_NO_CONTEXT 1 | ||||
| const uint8_t * const ED25519_NO_CONTEXT = (const uint8_t * const)(25519); | |||||
| /** Prehash context renaming macros. */ | /** Prehash context renaming macros. */ | ||||
| #define decaf_ed25519_prehash_ctx_s decaf_sha512_ctx_s | #define decaf_ed25519_prehash_ctx_s decaf_sha512_ctx_s | ||||
| #define decaf_ed25519_prehash_ctx_t decaf_sha512_ctx_t | #define decaf_ed25519_prehash_ctx_t decaf_sha512_ctx_t | ||||
| @@ -64,7 +65,6 @@ void decaf_ed25519_derive_public_key ( | |||||
| * @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign. | * @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign. | ||||
| * @param [in] context A "context" for this signature of up to 255 bytes. | * @param [in] context A "context" for this signature of up to 255 bytes. | ||||
| * @param [in] context_len Length of the context. | * @param [in] context_len Length of the context. | ||||
| * @param [in] no_context Nonzero if no context should be used (only Ed25519 supported). | |||||
| * | * | ||||
| * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | ||||
| * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | ||||
| @@ -79,8 +79,7 @@ void decaf_ed25519_sign ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) API_VIS __attribute__((nonnull(1,2,3))) NOINLINE; | ) API_VIS __attribute__((nonnull(1,2,3))) NOINLINE; | ||||
| /** | /** | ||||
| @@ -128,7 +127,6 @@ void decaf_ed25519_prehash_init ( | |||||
| * @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify. | * @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify. | ||||
| * @param [in] context A "context" for this signature of up to 255 bytes. | * @param [in] context A "context" for this signature of up to 255 bytes. | ||||
| * @param [in] context_len Length of the context. | * @param [in] context_len Length of the context. | ||||
| * @param [in] no_context Nonzero if no context should be used (only Ed25519 supported). | |||||
| * | * | ||||
| * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | ||||
| * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | ||||
| @@ -142,8 +140,7 @@ decaf_error_t decaf_ed25519_verify ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) API_VIS __attribute__((nonnull(1,2))) NOINLINE; | ) API_VIS __attribute__((nonnull(1,2))) NOINLINE; | ||||
| /** | /** | ||||
| @@ -141,8 +141,7 @@ public: | |||||
| */ | */ | ||||
| inline SecureBuffer sign ( | inline SecureBuffer sign ( | ||||
| const Block &message, | const Block &message, | ||||
| const Block &context = Block(NULL,0), | |||||
| const bool no_context = false | |||||
| const Block &context = Block(NULL,0) | |||||
| ) const /* TODO: this exn spec tickles a Clang bug? | ) const /* TODO: this exn spec tickles a Clang bug? | ||||
| * throw(LengthException, std::bad_alloc) | * throw(LengthException, std::bad_alloc) | ||||
| */ { | */ { | ||||
| @@ -159,8 +158,7 @@ public: | |||||
| message.size(), | message.size(), | ||||
| 0, | 0, | ||||
| context.data(), | context.data(), | ||||
| context.size(), | |||||
| no_context | |||||
| context.size() | |||||
| ); | ); | ||||
| return out; | return out; | ||||
| } | } | ||||
| @@ -247,8 +245,7 @@ public: | |||||
| inline decaf_error_t WARN_UNUSED verify_noexcept ( | inline decaf_error_t WARN_UNUSED verify_noexcept ( | ||||
| const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig, | const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig, | ||||
| const Block &message, | const Block &message, | ||||
| const Block &context = Block(NULL,0), | |||||
| const bool no_context = false | |||||
| const Block &context = Block(NULL,0) | |||||
| ) const /*NOEXCEPT*/ { | ) const /*NOEXCEPT*/ { | ||||
| if (context.size() > 255) { | if (context.size() > 255) { | ||||
| return DECAF_FAILURE; | return DECAF_FAILURE; | ||||
| @@ -261,8 +258,7 @@ public: | |||||
| message.size(), | message.size(), | ||||
| 0, | 0, | ||||
| context.data(), | context.data(), | ||||
| context.size(), | |||||
| no_context | |||||
| context.size() | |||||
| ); | ); | ||||
| } | } | ||||
| @@ -276,14 +272,13 @@ public: | |||||
| inline void verify ( | inline void verify ( | ||||
| const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig, | const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig, | ||||
| const Block &message, | const Block &message, | ||||
| const Block &context = Block(NULL,0), | |||||
| const bool no_context = false | |||||
| const Block &context = Block(NULL,0) | |||||
| ) const /*throw(LengthException,CryptoException)*/ { | ) const /*throw(LengthException,CryptoException)*/ { | ||||
| if (context.size() > 255) { | if (context.size() > 255) { | ||||
| throw LengthException(); | throw LengthException(); | ||||
| } | } | ||||
| if (DECAF_SUCCESS != verify_noexcept( sig, message, context, no_context )) { | |||||
| if (DECAF_SUCCESS != verify_noexcept( sig, message, context )) { | |||||
| throw CryptoException(); | throw CryptoException(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -34,7 +34,7 @@ extern "C" { | |||||
| /** Does EdDSA support non-contextual signatures? */ | /** Does EdDSA support non-contextual signatures? */ | ||||
| #define DECAF_EDDSA_448_NO_CONTEXT 0 | #define DECAF_EDDSA_448_NO_CONTEXT 0 | ||||
| /** Prehash context renaming macros. */ | /** Prehash context renaming macros. */ | ||||
| #define decaf_ed448_prehash_ctx_s decaf_shake256_ctx_s | #define decaf_ed448_prehash_ctx_s decaf_shake256_ctx_s | ||||
| #define decaf_ed448_prehash_ctx_t decaf_shake256_ctx_t | #define decaf_ed448_prehash_ctx_t decaf_shake256_ctx_t | ||||
| @@ -64,7 +64,6 @@ void decaf_ed448_derive_public_key ( | |||||
| * @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign. | * @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign. | ||||
| * @param [in] context A "context" for this signature of up to 255 bytes. | * @param [in] context A "context" for this signature of up to 255 bytes. | ||||
| * @param [in] context_len Length of the context. | * @param [in] context_len Length of the context. | ||||
| * @param [in] no_context Nonzero if no context should be used (only Ed25519 supported). | |||||
| * | * | ||||
| * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | ||||
| * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | ||||
| @@ -79,8 +78,7 @@ void decaf_ed448_sign ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) API_VIS __attribute__((nonnull(1,2,3))) NOINLINE; | ) API_VIS __attribute__((nonnull(1,2,3))) NOINLINE; | ||||
| /** | /** | ||||
| @@ -128,7 +126,6 @@ void decaf_ed448_prehash_init ( | |||||
| * @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify. | * @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify. | ||||
| * @param [in] context A "context" for this signature of up to 255 bytes. | * @param [in] context A "context" for this signature of up to 255 bytes. | ||||
| * @param [in] context_len Length of the context. | * @param [in] context_len Length of the context. | ||||
| * @param [in] no_context Nonzero if no context should be used (only Ed25519 supported). | |||||
| * | * | ||||
| * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | ||||
| * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | ||||
| @@ -142,8 +139,7 @@ decaf_error_t decaf_ed448_verify ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) API_VIS __attribute__((nonnull(1,2))) NOINLINE; | ) API_VIS __attribute__((nonnull(1,2))) NOINLINE; | ||||
| /** | /** | ||||
| @@ -141,8 +141,7 @@ public: | |||||
| */ | */ | ||||
| inline SecureBuffer sign ( | inline SecureBuffer sign ( | ||||
| const Block &message, | const Block &message, | ||||
| const Block &context = Block(NULL,0), | |||||
| const bool no_context = false | |||||
| const Block &context = Block(NULL,0) | |||||
| ) const /* TODO: this exn spec tickles a Clang bug? | ) const /* TODO: this exn spec tickles a Clang bug? | ||||
| * throw(LengthException, std::bad_alloc) | * throw(LengthException, std::bad_alloc) | ||||
| */ { | */ { | ||||
| @@ -159,8 +158,7 @@ public: | |||||
| message.size(), | message.size(), | ||||
| 0, | 0, | ||||
| context.data(), | context.data(), | ||||
| context.size(), | |||||
| no_context | |||||
| context.size() | |||||
| ); | ); | ||||
| return out; | return out; | ||||
| } | } | ||||
| @@ -247,8 +245,7 @@ public: | |||||
| inline decaf_error_t WARN_UNUSED verify_noexcept ( | inline decaf_error_t WARN_UNUSED verify_noexcept ( | ||||
| const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig, | const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig, | ||||
| const Block &message, | const Block &message, | ||||
| const Block &context = Block(NULL,0), | |||||
| const bool no_context = false | |||||
| const Block &context = Block(NULL,0) | |||||
| ) const /*NOEXCEPT*/ { | ) const /*NOEXCEPT*/ { | ||||
| if (context.size() > 255) { | if (context.size() > 255) { | ||||
| return DECAF_FAILURE; | return DECAF_FAILURE; | ||||
| @@ -261,8 +258,7 @@ public: | |||||
| message.size(), | message.size(), | ||||
| 0, | 0, | ||||
| context.data(), | context.data(), | ||||
| context.size(), | |||||
| no_context | |||||
| context.size() | |||||
| ); | ); | ||||
| } | } | ||||
| @@ -276,14 +272,13 @@ public: | |||||
| inline void verify ( | inline void verify ( | ||||
| const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig, | const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig, | ||||
| const Block &message, | const Block &message, | ||||
| const Block &context = Block(NULL,0), | |||||
| const bool no_context = false | |||||
| const Block &context = Block(NULL,0) | |||||
| ) const /*throw(LengthException,CryptoException)*/ { | ) const /*throw(LengthException,CryptoException)*/ { | ||||
| if (context.size() > 255) { | if (context.size() > 255) { | ||||
| throw LengthException(); | throw LengthException(); | ||||
| } | } | ||||
| if (DECAF_SUCCESS != verify_noexcept( sig, message, context, no_context )) { | |||||
| if (DECAF_SUCCESS != verify_noexcept( sig, message, context )) { | |||||
| throw CryptoException(); | throw CryptoException(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -49,21 +49,18 @@ static void hash_init_with_dom( | |||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| uint8_t for_prehash, | uint8_t for_prehash, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) { | ) { | ||||
| hash_init(hash); | hash_init(hash); | ||||
| #if NO_CONTEXT | #if NO_CONTEXT | ||||
| if (no_context) { | |||||
| if (context_len == 0 && context == ED$(gf_shortname)_NO_CONTEXT) { | |||||
| (void)prehashed; | (void)prehashed; | ||||
| (void)for_prehash; | (void)for_prehash; | ||||
| (void)context; | (void)context; | ||||
| (void)context_len; | (void)context_len; | ||||
| return; | return; | ||||
| } | } | ||||
| #else | |||||
| (void)no_context; | |||||
| #endif | #endif | ||||
| const char *dom_s = "$(eddsa_dom)"; | const char *dom_s = "$(eddsa_dom)"; | ||||
| const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len}; | const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len}; | ||||
| @@ -125,8 +122,7 @@ void decaf_ed$(gf_shortname)_sign ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) { | ) { | ||||
| API_NS(scalar_t) secret_scalar; | API_NS(scalar_t) secret_scalar; | ||||
| hash_ctx_t hash; | hash_ctx_t hash; | ||||
| @@ -146,7 +142,7 @@ void decaf_ed$(gf_shortname)_sign ( | |||||
| API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser)); | API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser)); | ||||
| /* Hash to create the nonce */ | /* Hash to create the nonce */ | ||||
| hash_init_with_dom(hash,prehashed,0,context,context_len,no_context); | |||||
| hash_init_with_dom(hash,prehashed,0,context,context_len); | |||||
| hash_update(hash,expanded.seed,sizeof(expanded.seed)); | hash_update(hash,expanded.seed,sizeof(expanded.seed)); | ||||
| hash_update(hash,message,message_len); | hash_update(hash,message,message_len); | ||||
| decaf_bzero(&expanded, sizeof(expanded)); | decaf_bzero(&expanded, sizeof(expanded)); | ||||
| @@ -180,7 +176,7 @@ void decaf_ed$(gf_shortname)_sign ( | |||||
| API_NS(scalar_t) challenge_scalar; | API_NS(scalar_t) challenge_scalar; | ||||
| { | { | ||||
| /* Compute the challenge */ | /* Compute the challenge */ | ||||
| hash_init_with_dom(hash,prehashed,0,context,context_len,no_context); | |||||
| hash_init_with_dom(hash,prehashed,0,context,context_len); | |||||
| hash_update(hash,nonce_point,sizeof(nonce_point)); | hash_update(hash,nonce_point,sizeof(nonce_point)); | ||||
| hash_update(hash,pubkey,DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES); | hash_update(hash,pubkey,DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES); | ||||
| hash_update(hash,message,message_len); | hash_update(hash,message,message_len); | ||||
| @@ -220,7 +216,7 @@ void decaf_ed$(gf_shortname)_sign_prehash ( | |||||
| hash_destroy(hash_too); | hash_destroy(hash_too); | ||||
| } | } | ||||
| decaf_ed$(gf_shortname)_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len,0); | |||||
| decaf_ed$(gf_shortname)_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len); | |||||
| decaf_bzero(hash_output,sizeof(hash_output)); | decaf_bzero(hash_output,sizeof(hash_output)); | ||||
| } | } | ||||
| @@ -231,8 +227,7 @@ decaf_error_t decaf_ed$(gf_shortname)_verify ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) { | ) { | ||||
| API_NS(point_t) pk_point, r_point; | 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_ignore_cofactor)(pk_point,pubkey); | ||||
| @@ -245,7 +240,7 @@ decaf_error_t decaf_ed$(gf_shortname)_verify ( | |||||
| { | { | ||||
| /* Compute the challenge */ | /* Compute the challenge */ | ||||
| hash_ctx_t hash; | hash_ctx_t hash; | ||||
| hash_init_with_dom(hash,prehashed,0,context,context_len,no_context); | |||||
| hash_init_with_dom(hash,prehashed,0,context,context_len); | |||||
| hash_update(hash,signature,DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES); | hash_update(hash,signature,DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES); | ||||
| hash_update(hash,pubkey,DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES); | hash_update(hash,pubkey,DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES); | ||||
| hash_update(hash,message,message_len); | hash_update(hash,message,message_len); | ||||
| @@ -296,7 +291,7 @@ decaf_error_t decaf_ed$(gf_shortname)_verify_prehash ( | |||||
| hash_destroy(hash_too); | hash_destroy(hash_too); | ||||
| } | } | ||||
| ret = decaf_ed$(gf_shortname)_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len,0); | |||||
| ret = decaf_ed$(gf_shortname)_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len); | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -19,7 +19,7 @@ extern "C" { | |||||
| /** Does EdDSA support non-contextual signatures? */ | /** Does EdDSA support non-contextual signatures? */ | ||||
| #define DECAF_EDDSA_$(gf_shortname)_NO_CONTEXT $(eddsa_no_context) | #define DECAF_EDDSA_$(gf_shortname)_NO_CONTEXT $(eddsa_no_context) | ||||
| $("const uint8_t * const ED" + gf_shortname + "_NO_CONTEXT = (const uint8_t * const)(" + gf_shortname + ");\n" if eddsa_no_context else "") | |||||
| /** Prehash context renaming macros. */ | /** Prehash context renaming macros. */ | ||||
| #define decaf_ed$(gf_shortname)_prehash_ctx_s decaf_$(eddsa_hash)_ctx_s | #define decaf_ed$(gf_shortname)_prehash_ctx_s decaf_$(eddsa_hash)_ctx_s | ||||
| #define decaf_ed$(gf_shortname)_prehash_ctx_t decaf_$(eddsa_hash)_ctx_t | #define decaf_ed$(gf_shortname)_prehash_ctx_t decaf_$(eddsa_hash)_ctx_t | ||||
| @@ -49,7 +49,6 @@ void decaf_ed$(gf_shortname)_derive_public_key ( | |||||
| * @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign. | * @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign. | ||||
| * @param [in] context A "context" for this signature of up to 255 bytes. | * @param [in] context A "context" for this signature of up to 255 bytes. | ||||
| * @param [in] context_len Length of the context. | * @param [in] context_len Length of the context. | ||||
| * @param [in] no_context Nonzero if no context should be used (only Ed25519 supported). | |||||
| * | * | ||||
| * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | ||||
| * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | ||||
| @@ -64,8 +63,7 @@ void decaf_ed$(gf_shortname)_sign ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) API_VIS __attribute__((nonnull(1,2,3))) NOINLINE; | ) API_VIS __attribute__((nonnull(1,2,3))) NOINLINE; | ||||
| /** | /** | ||||
| @@ -113,7 +111,6 @@ void decaf_ed$(gf_shortname)_prehash_init ( | |||||
| * @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify. | * @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify. | ||||
| * @param [in] context A "context" for this signature of up to 255 bytes. | * @param [in] context A "context" for this signature of up to 255 bytes. | ||||
| * @param [in] context_len Length of the context. | * @param [in] context_len Length of the context. | ||||
| * @param [in] no_context Nonzero if no context should be used (only Ed25519 supported). | |||||
| * | * | ||||
| * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed | ||||
| * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is | ||||
| @@ -127,8 +124,7 @@ decaf_error_t decaf_ed$(gf_shortname)_verify ( | |||||
| size_t message_len, | size_t message_len, | ||||
| uint8_t prehashed, | uint8_t prehashed, | ||||
| const uint8_t *context, | const uint8_t *context, | ||||
| uint8_t context_len, | |||||
| uint8_t no_context | |||||
| uint8_t context_len | |||||
| ) API_VIS __attribute__((nonnull(1,2))) NOINLINE; | ) API_VIS __attribute__((nonnull(1,2))) NOINLINE; | ||||
| /** | /** | ||||
| @@ -125,8 +125,7 @@ public: | |||||
| */ | */ | ||||
| inline SecureBuffer sign ( | inline SecureBuffer sign ( | ||||
| const Block &message, | const Block &message, | ||||
| const Block &context = Block(NULL,0), | |||||
| const bool no_context = false | |||||
| const Block &context = Block(NULL,0) | |||||
| ) const /* TODO: this exn spec tickles a Clang bug? | ) const /* TODO: this exn spec tickles a Clang bug? | ||||
| * throw(LengthException, std::bad_alloc) | * throw(LengthException, std::bad_alloc) | ||||
| */ { | */ { | ||||
| @@ -143,8 +142,7 @@ public: | |||||
| message.size(), | message.size(), | ||||
| 0, | 0, | ||||
| context.data(), | context.data(), | ||||
| context.size(), | |||||
| no_context | |||||
| context.size() | |||||
| ); | ); | ||||
| return out; | return out; | ||||
| } | } | ||||
| @@ -231,8 +229,7 @@ public: | |||||
| inline decaf_error_t WARN_UNUSED verify_noexcept ( | inline decaf_error_t WARN_UNUSED verify_noexcept ( | ||||
| const FixedBlock<DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES> &sig, | const FixedBlock<DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES> &sig, | ||||
| const Block &message, | const Block &message, | ||||
| const Block &context = Block(NULL,0), | |||||
| const bool no_context = false | |||||
| const Block &context = Block(NULL,0) | |||||
| ) const /*NOEXCEPT*/ { | ) const /*NOEXCEPT*/ { | ||||
| if (context.size() > 255) { | if (context.size() > 255) { | ||||
| return DECAF_FAILURE; | return DECAF_FAILURE; | ||||
| @@ -245,8 +242,7 @@ public: | |||||
| message.size(), | message.size(), | ||||
| 0, | 0, | ||||
| context.data(), | context.data(), | ||||
| context.size(), | |||||
| no_context | |||||
| context.size() | |||||
| ); | ); | ||||
| } | } | ||||
| @@ -260,14 +256,13 @@ public: | |||||
| inline void verify ( | inline void verify ( | ||||
| const FixedBlock<DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES> &sig, | const FixedBlock<DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES> &sig, | ||||
| const Block &message, | const Block &message, | ||||
| const Block &context = Block(NULL,0), | |||||
| const bool no_context = false | |||||
| const Block &context = Block(NULL,0) | |||||
| ) const /*throw(LengthException,CryptoException)*/ { | ) const /*throw(LengthException,CryptoException)*/ { | ||||
| if (context.size() > 255) { | if (context.size() > 255) { | ||||
| throw LengthException(); | throw LengthException(); | ||||
| } | } | ||||
| if (DECAF_SUCCESS != verify_noexcept( sig, message, context, no_context )) { | |||||
| if (DECAF_SUCCESS != verify_noexcept( sig, message, context )) { | |||||
| throw CryptoException(); | throw CryptoException(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -469,7 +469,7 @@ static void test_cfrg_crypto() { | |||||
| } | } | ||||
| } | } | ||||
| static const bool eddsa_prehashed[], eddsa_no_context[]; | |||||
| static const bool eddsa_prehashed[]; | |||||
| static const Block eddsa_sk[], eddsa_pk[], eddsa_message[], eddsa_context[], eddsa_sig[]; | static const Block eddsa_sk[], eddsa_pk[], eddsa_message[], eddsa_context[], eddsa_sig[]; | ||||
| static void test_cfrg_vectors() { | static void test_cfrg_vectors() { | ||||
| @@ -499,7 +499,7 @@ static void test_cfrg_vectors() { | |||||
| typename EdDSA<Group>::PrivateKeyPh priv2(eddsa_sk[t]); | typename EdDSA<Group>::PrivateKeyPh priv2(eddsa_sk[t]); | ||||
| sig = priv2.sign_with_prehash(eddsa_message[t],eddsa_context[t]); | sig = priv2.sign_with_prehash(eddsa_message[t],eddsa_context[t]); | ||||
| } else { | } else { | ||||
| sig = priv.sign(eddsa_message[t],eddsa_context[t],eddsa_no_context[t]); | |||||
| sig = priv.sign(eddsa_message[t],eddsa_context[t]); | |||||
| } | } | ||||
| if (!memeq(SecureBuffer(eddsa_sig[t]),sig)) { | if (!memeq(SecureBuffer(eddsa_sig[t]),sig)) { | ||||
| @@ -346,15 +346,6 @@ template<> const Block Tests<Ed448Goldilocks>::eddsa_context[] = { | |||||
| Block(NULL,0), | Block(NULL,0), | ||||
| Block(ed448_eddsa_context[0],3) | Block(ed448_eddsa_context[0],3) | ||||
| }; | }; | ||||
| template<> const bool Tests<Ed448Goldilocks>::eddsa_no_context[] = { | |||||
| false, | |||||
| false, | |||||
| false, | |||||
| false, | |||||
| false, | |||||
| false, | |||||
| false | |||||
| }; | |||||
| template<> const Block Tests<Ed448Goldilocks>::eddsa_sig[] = { | template<> const Block Tests<Ed448Goldilocks>::eddsa_sig[] = { | ||||
| Block(ed448_eddsa_sig[0],114), | Block(ed448_eddsa_sig[0],114), | ||||
| Block(ed448_eddsa_sig[1],114), | Block(ed448_eddsa_sig[1],114), | ||||
| @@ -516,21 +507,13 @@ template<> const Block Tests<IsoEd25519>::eddsa_pk[] = { | |||||
| Block(ed25519_eddsa_pk[4],32) | Block(ed25519_eddsa_pk[4],32) | ||||
| }; | }; | ||||
| template<> const Block Tests<IsoEd25519>::eddsa_context[] = { | template<> const Block Tests<IsoEd25519>::eddsa_context[] = { | ||||
| Block(NULL,0), | |||||
| Block(NULL,0), | |||||
| Block(NULL,0), | |||||
| Block(ED25519_NO_CONTEXT,0), | |||||
| Block(ED25519_NO_CONTEXT,0), | |||||
| Block(ED25519_NO_CONTEXT,0), | |||||
| Block(NULL,0), | Block(NULL,0), | ||||
| Block(ed25519_eddsa_context[0],3), | Block(ed25519_eddsa_context[0],3), | ||||
| Block(ed25519_eddsa_context[1],3) | Block(ed25519_eddsa_context[1],3) | ||||
| }; | }; | ||||
| template<> const bool Tests<IsoEd25519>::eddsa_no_context[] = { | |||||
| true, | |||||
| true, | |||||
| true, | |||||
| false, | |||||
| false, | |||||
| false | |||||
| }; | |||||
| template<> const Block Tests<IsoEd25519>::eddsa_message[] = { | template<> const Block Tests<IsoEd25519>::eddsa_message[] = { | ||||
| Block(ed25519_eddsa_message[0],0), | Block(ed25519_eddsa_message[0],0), | ||||
| Block(ed25519_eddsa_message[1],1), | Block(ed25519_eddsa_message[1],1), | ||||