From 9d0bac672f8502a92887f00ce98ad1b8b67a8493 Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Tue, 23 Feb 2016 10:47:48 -0800 Subject: [PATCH] move context arguments to the end of hash functions. Ed25519 doesnt support contexts. --- Makefile | 6 +- src/gen_headers/curve_data.py | 11 +++- src/per_curve/decaf.tmpl.c | 1 + src/per_curve/decaf.tmpl.h | 94 ---------------------------- src/per_curve/decaf.tmpl.hxx | 51 ++++++++++----- src/per_curve/eddsa.tmpl.c | 99 +++++++++++++++++------------ src/per_curve/eddsa.tmpl.h | 113 ++++++++++++++++++++++++++++++++++ test/test_decaf.cxx | 10 +-- 8 files changed, 232 insertions(+), 153 deletions(-) create mode 100644 src/per_curve/eddsa.tmpl.h diff --git a/Makefile b/Makefile index 9ce4eb6..11ab14f 100644 --- a/Makefile +++ b/Makefile @@ -169,7 +169,8 @@ LIBCOMPONENTS += $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/$(1)/elligator.o $$(BU $$(BUILD_OBJ)/$(1)/crypto.o $$(BUILD_OBJ)/$(1)/eddsa.o $$(BUILD_OBJ)/$(1)/decaf_tables.o PER_OBJ_DIRS += $$(BUILD_OBJ)/$(1) GLOBAL_HEADERS_OF_$(1) = $(BUILD_INC)/decaf/decaf_$(3).h $(BUILD_INC)/decaf/decaf_$(3).hxx \ - $(BUILD_INC)/decaf/crypto_$(3).h $(BUILD_INC)/decaf/crypto_$(3).hxx + $(BUILD_INC)/decaf/crypto_$(3).h $(BUILD_INC)/decaf/crypto_$(3).hxx \ + $(BUILD_INC)/decaf/eddsa_$(3).h HEADERS_OF_$(1) = $$(HEADERS_OF_$(2)) $$(GLOBAL_HEADERS_OF_$(1)) HEADERS += $$(GLOBAL_HEADERS_OF_$(1)) @@ -182,6 +183,9 @@ $$(BUILD_H)/$(1)/%.h: src/per_curve/%.tmpl.h src/gen_headers/* $$(HEADERS_OF_$(2 $$(BUILD_INC)/decaf/decaf_$(3).%: src/per_curve/decaf.tmpl.% src/gen_headers/* $$(HEADERS_OF_$(2)) python -B src/gen_headers/template.py --per=curve --item=$(1) --guard=$$(@:$(BUILD_INC)/%=%) -o $$@ $$< +$$(BUILD_INC)/decaf/eddsa_$(3).%: src/per_curve/eddsa.tmpl.% src/gen_headers/* $$(HEADERS_OF_$(2)) + python -B src/gen_headers/template.py --per=curve --item=$(1) --guard=$$(@:$(BUILD_INC)/%=%) -o $$@ $$< + $$(BUILD_INC)/decaf/elligator_$(3).%: src/per_curve/elligator.tmpl.% src/gen_headers/* $$(HEADERS_OF_$(2)) python -B src/gen_headers/template.py --per=curve --item=$(1) --guard=$$(@:$(BUILD_INC)/%=%) -o $$@ $$< diff --git a/src/gen_headers/curve_data.py b/src/gen_headers/curve_data.py index 0aaea64..0250c11 100644 --- a/src/gen_headers/curve_data.py +++ b/src/gen_headers/curve_data.py @@ -33,7 +33,10 @@ curve_data = { "combs":comb_config(3,5,17), "wnaf":wnaf_config(5,3), - "window_bits":4 + "window_bits":4, + + "eddsa_hash": "sha512", + "eddsa_supports_contexts": 0 }, "ed448goldilocks" : { "name" : "Ed448-Goldilocks", @@ -101,6 +104,12 @@ for curve,data in curve_data.iteritems(): if "iso_to" not in data: data["iso_to"] = data["name"] + + if "eddsa_hash" not in data: + data["edddsa"] = "sha512" + + if "eddsa_supports_contexts" not in data: + data["eddsa_supports_contexts"] = 1 if "cxx_ns" not in data: data["cxx_ns"] = data["name"].replace("-","") diff --git a/src/per_curve/decaf.tmpl.c b/src/per_curve/decaf.tmpl.c index 65fa107..5c6b5da 100644 --- a/src/per_curve/decaf.tmpl.c +++ b/src/per_curve/decaf.tmpl.c @@ -5,6 +5,7 @@ #include "field.h" #include +#include /* Template stuff */ #define API_NS(_id) $(c_ns)_##_id diff --git a/src/per_curve/decaf.tmpl.h b/src/per_curve/decaf.tmpl.h index e8c14ba..48f6329 100644 --- a/src/per_curve/decaf.tmpl.h +++ b/src/per_curve/decaf.tmpl.h @@ -37,16 +37,6 @@ typedef struct gf_$(gf_shortname)_s { /** Number of bits in the "which" field of an elligator inverse */ #define $(C_NS)_INVERT_ELLIGATOR_WHICH_BITS $(ceil_log2(cofactor) + 7 + elligator_onto - ((gf_bits-2) % 8)) -/* TODO: move to a different file? */ -/** Number of bytes in an EdDSA public key. */ -#define $(C_NS)_EDDSA_PUBLIC_BYTES $((gf_bits)/8 + 1) /* TODO: change name? */ - -/** Number of bytes in an EdDSA private key. */ -#define $(C_NS)_EDDSA_PRIVATE_BYTES $(C_NS)_EDDSA_PUBLIC_BYTES /* TODO: change name? */ - -/** Number of bytes in an EdDSA private key. */ -#define $(C_NS)_EDDSA_SIGNATURE_BYTES ($(C_NS)_EDDSA_PUBLIC_BYTES + $(C_NS)_EDDSA_PRIVATE_BYTES) /* TODO: change name? */ - /** Number of bytes in an x$(gf_shortname) public key */ #define X$(gf_shortname)_PUBLIC_BYTES $((gf_bits-1)/8 + 1) @@ -414,90 +404,6 @@ void $(c_ns)_x_base_scalarmul ( const uint8_t scalar[X$(gf_shortname)_PRIVATE_BYTES] ) API_VIS NONNULL NOINLINE; -/** - * @brief EdDSA key generation. This function uses a different (non-Decaf) - * encoding. - * - * @param [out] pubkey The public key. - * @param [in] privkey The private key. - */ -void $(c_ns)_eddsa_derive_public_key ( - uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES], - const uint8_t privkey[$(C_NS)_EDDSA_PRIVATE_BYTES] -) API_VIS NONNULL NOINLINE; - -/** - * @brief EdDSA signing. - * - * @param [out] signature The signature. - * @param [in] privkey The private key. - * @param [in] pubkey The public key. - * @param [in] context A "context" for this signature of up to 255 bytes. - * @param [in] context_len Length of the context. - * @param [in] message The message to sign. - * @param [in] message_len The length of the message. - * @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign. - */ -void $(c_ns)_eddsa_sign ( - uint8_t signature[$(C_NS)_EDDSA_SIGNATURE_BYTES], - const uint8_t privkey[$(C_NS)_EDDSA_PRIVATE_BYTES], - const uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES], - const uint8_t *context, - uint8_t context_len, - const uint8_t *message, - size_t message_len, - uint8_t prehashed -) API_VIS __attribute__((nonnull(1,2,3))) NOINLINE; - -/** - * @brief EdDSA signature verification. - * - * Uses the standard (i.e. less-strict) verification formula. - * - * @param [in] signature The signature. - * @param [in] pubkey The public key. - * @param [in] context A "context" for this signature of up to 255 bytes. - * @param [in] context_len Length of the context. - * @param [in] message The message to verify. - * @param [in] message_len The length of the message. - * @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify. - */ -decaf_error_t $(c_ns)_eddsa_verify ( - const uint8_t signature[$(C_NS)_EDDSA_SIGNATURE_BYTES], - const uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES], - const uint8_t *context, - uint8_t context_len, - const uint8_t *message, - size_t message_len, - uint8_t prehashed -) API_VIS __attribute__((nonnull(1,2))) NOINLINE; - -/** - * @brief EdDSA point encoding. - * - * @param [out] enc The encoded point. - * @param [in] p The point. - * - * FIXME: encode and decode aren't inverses of each other: they - * multiply by a factor. Rename to reflect this once the base - * point doctrine is worked out. - */ -void $(c_ns)_point_encode_like_eddsa ( - uint8_t enc[$(C_NS)_EDDSA_PUBLIC_BYTES], - const $(c_ns)_point_t p -) API_VIS NONNULL NOINLINE; - -/** - * @brief EdDSA point encoding. - * - * @param [out] enc The encoded point. - * @param [in] p The point. - */ -decaf_error_t $(c_ns)_point_decode_like_eddsa ( - $(c_ns)_point_t p, - const uint8_t enc[$(C_NS)_EDDSA_PUBLIC_BYTES] -) API_VIS NONNULL NOINLINE; - /** * @brief Precompute a table for fast scalar multiplication. * Some implementations do not include precomputed points; for diff --git a/src/per_curve/decaf.tmpl.hxx b/src/per_curve/decaf.tmpl.hxx index e020bbc..36f5aec 100644 --- a/src/per_curve/decaf.tmpl.hxx +++ b/src/per_curve/decaf.tmpl.hxx @@ -21,6 +21,7 @@ #include /* for memcpy */ #include +#include /* TODO: move eddsa to another file? */ #include #include #include @@ -685,6 +686,9 @@ public: /** The size of a private key */ static const size_t SIGNATURE_BYTES = $(C_NS)_EDDSA_SIGNATURE_BYTES; + /** Do we support contexts for signatures? If not, they must always be NULL */ + static const bool SUPPORTS_CONTEXTS = $(C_NS)_EDDSA_SUPPORTS_CONTEXTS; + static inline SecureBuffer generate_key ( const FixedBlock &priv ) { @@ -696,21 +700,28 @@ public: static inline SecureBuffer sign ( const FixedBlock &priv, const FixedBlock &pub, - const Block &context, const Block &message, - bool prehashed = false + bool prehashed = false, + const Block &context = Block(NULL,0) ) throw(LengthException) { - if (context.size() > 255) { throw LengthException(); } + if (context.size() > 255 + || (context.size() != 0 && !SUPPORTS_CONTEXTS) + ) { + throw LengthException(); + } + SecureBuffer out(SIGNATURE_BYTES); $(c_ns)_eddsa_sign ( out.data(), priv.data(), pub.data(), - context.data(), - context.size(), message.data(), message.size(), prehashed +#if $(C_NS)_EDDSA_SUPPORTS_CONTEXTS + , context.data(), + context.size() +#endif ); return out; } @@ -718,31 +729,43 @@ public: static inline decaf_error_t WARN_UNUSED verify_noexcept ( const FixedBlock &sig, const FixedBlock &pub, - const Block &context, const Block &message, - bool prehashed = false + bool prehashed = false, + const Block &context = Block(NULL,0) ) { - if (context.size() > 255) return DECAF_FAILURE; + if (context.size() > 255 + || (context.size() != 0 && !SUPPORTS_CONTEXTS) + ) { + return DECAF_FAILURE; + } + return $(c_ns)_eddsa_verify ( sig.data(), pub.data(), - context.data(), - context.size(), message.data(), message.size(), prehashed +#if $(C_NS)_EDDSA_SUPPORTS_CONTEXTS + , context.data(), + context.size() +#endif ); } static inline void verify ( const FixedBlock &sig, const FixedBlock &pub, - const Block &context, const Block &message, - bool prehashed = false + bool prehashed = false, + const Block &context = Block(NULL,0) ) throw(LengthException,CryptoException) { - if (context.size() > 255) { throw LengthException(); } - if (DECAF_SUCCESS != verify_noexcept( sig, pub, context, message, prehashed )) { + if (context.size() > 255 + || (context.size() != 0 && !SUPPORTS_CONTEXTS) + ) { + throw LengthException(); + } + + if (DECAF_SUCCESS != verify_noexcept( sig, pub, message, prehashed, context )) { throw CryptoException(); } } diff --git a/src/per_curve/eddsa.tmpl.c b/src/per_curve/eddsa.tmpl.c index 0a5c398..18ff20f 100644 --- a/src/per_curve/eddsa.tmpl.c +++ b/src/per_curve/eddsa.tmpl.c @@ -3,7 +3,7 @@ * @brief EdDSA routines. */ -#include "decaf.h" +#include #include "decaf/shake.h" #include "word.h" #include @@ -11,6 +11,15 @@ #define API_NAME "$(c_ns)" #define API_NS(_id) $(c_ns)_##_id +#define hash_ctx_t shake256_ctx_t +#define hash_init shake256_init +#define hash_update shake256_update +#define hash_final shake256_final +#define hash_destroy shake256_destroy +#define hash_hash shake256_hash + +#define SUPPORTS_CONTEXTS $(C_NS)_EDDSA_SUPPORTS_CONTEXTS + static void clamp( uint8_t secret_scalar_ser[$(C_NS)_EDDSA_PRIVATE_BYTES] ) { @@ -22,6 +31,21 @@ static void clamp( if (hibit == 0) secret_scalar_ser[$(C_NS)_EDDSA_PRIVATE_BYTES - 2] |= 0x80; } +static void hash_init_with_dom( + hash_ctx_t hash, + uint8_t prehashed, + const uint8_t *context, + uint8_t context_len +) { + const char *domS = "SigEd448"; + const uint8_t dom[2] = {1+word_is_zero(prehashed), context_len}; + + hash_init(hash); + hash_update(hash,(const unsigned char *)domS, strlen(domS)); + hash_update(hash,dom,2); + hash_update(hash,context,context_len); +} + void API_NS(eddsa_derive_public_key) ( uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES], const uint8_t privkey[$(C_NS)_EDDSA_PRIVATE_BYTES] @@ -29,7 +53,7 @@ void API_NS(eddsa_derive_public_key) ( /* only this much used for keygen */ uint8_t secret_scalar_ser[$(C_NS)_EDDSA_PRIVATE_BYTES]; - shake256_hash( + hash_hash( secret_scalar_ser, sizeof(secret_scalar_ser), privkey, @@ -55,30 +79,33 @@ void API_NS(eddsa_derive_public_key) ( decaf_bzero(secret_scalar_ser, sizeof(secret_scalar_ser)); } -static const char *domS = "SigEd448"; - void API_NS(eddsa_sign) ( uint8_t signature[$(C_NS)_EDDSA_SIGNATURE_BYTES], const uint8_t privkey[$(C_NS)_EDDSA_PRIVATE_BYTES], const uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES], - const uint8_t *context, - uint8_t context_len, const uint8_t *message, size_t message_len, uint8_t prehashed +#if SUPPORTS_CONTEXTS + , const uint8_t *context, + uint8_t context_len +#endif ) { +#if !SUPPORTS_CONTEXTS + const uint8_t *const context = NULL; + const uint8_t context_len = 0; +#endif /* FIXME: of course, need a different hash for Curve25519 */ API_NS(scalar_t) secret_scalar; - shake256_ctx_t shake; - const uint8_t dom[2] = {1+word_is_zero(prehashed), context_len}; + hash_ctx_t hash; { /* Schedule the secret key */ struct { uint8_t secret_scalar_ser[$(C_NS)_EDDSA_PRIVATE_BYTES]; uint8_t seed[$(C_NS)_EDDSA_PRIVATE_BYTES]; } __attribute__((packed)) expanded; - shake256_hash( + hash_hash( (uint8_t *)&expanded, sizeof(expanded), privkey, @@ -88,12 +115,9 @@ void API_NS(eddsa_sign) ( API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser)); /* Hash to create the nonce */ - shake256_init(shake); - shake256_update(shake,(const unsigned char *)domS, strlen(domS)); - shake256_update(shake,dom,2); - shake256_update(shake,context,context_len); - shake256_update(shake,expanded.seed,sizeof(expanded.seed)); - shake256_update(shake,message,message_len); + hash_init_with_dom(hash,prehashed,context,context_len); + hash_update(hash,expanded.seed,sizeof(expanded.seed)); + hash_update(hash,message,message_len); decaf_bzero(&expanded, sizeof(expanded)); } @@ -101,7 +125,7 @@ void API_NS(eddsa_sign) ( API_NS(scalar_t) nonce_scalar; { uint8_t nonce[2*$(C_NS)_EDDSA_PRIVATE_BYTES]; - shake256_final(shake,nonce,sizeof(nonce)); + hash_final(hash,nonce,sizeof(nonce)); API_NS(scalar_decode_long)(nonce_scalar, nonce, sizeof(nonce)); decaf_bzero(nonce, sizeof(nonce)); } @@ -123,16 +147,13 @@ void API_NS(eddsa_sign) ( API_NS(scalar_t) challenge_scalar; { /* Compute the challenge */ - shake256_init(shake); - shake256_update(shake,(const unsigned char *)domS, strlen(domS)); - shake256_update(shake,dom,2); - shake256_update(shake,context,context_len); - shake256_update(shake,nonce_point,sizeof(nonce_point)); - shake256_update(shake,pubkey,$(C_NS)_EDDSA_PUBLIC_BYTES); - shake256_update(shake,message,message_len); + hash_init_with_dom(hash,prehashed,context,context_len); + hash_update(hash,nonce_point,sizeof(nonce_point)); + hash_update(hash,pubkey,$(C_NS)_EDDSA_PUBLIC_BYTES); + hash_update(hash,message,message_len); uint8_t challenge[2*$(C_NS)_EDDSA_PRIVATE_BYTES]; - shake256_final(shake,challenge,sizeof(challenge)); - shake256_destroy(shake); + hash_final(hash,challenge,sizeof(challenge)); + hash_destroy(hash); API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge)); decaf_bzero(challenge,sizeof(challenge)); } @@ -153,12 +174,18 @@ void API_NS(eddsa_sign) ( decaf_error_t API_NS(eddsa_verify) ( const uint8_t signature[$(C_NS)_EDDSA_SIGNATURE_BYTES], const uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES], - const uint8_t *context, - uint8_t context_len, const uint8_t *message, size_t message_len, uint8_t prehashed +#if SUPPORTS_CONTEXTS + , const uint8_t *context, + uint8_t context_len +#endif ) { +#if !SUPPORTS_CONTEXTS + const uint8_t *const context = NULL; + const uint8_t context_len = 0; +#endif API_NS(point_t) pk_point, r_point; decaf_error_t error = API_NS(point_decode_like_eddsa)(pk_point,pubkey); if (DECAF_SUCCESS != error) { return error; } @@ -169,18 +196,14 @@ decaf_error_t API_NS(eddsa_verify) ( API_NS(scalar_t) challenge_scalar; { /* Compute the challenge */ - shake256_ctx_t shake; - const uint8_t dom[2] = {1+word_is_zero(prehashed), context_len}; - shake256_init(shake); - shake256_update(shake,(const unsigned char *)domS, strlen(domS)); - shake256_update(shake,dom,2); - shake256_update(shake,context,context_len); - shake256_update(shake,signature,$(C_NS)_EDDSA_PUBLIC_BYTES); - shake256_update(shake,pubkey,$(C_NS)_EDDSA_PUBLIC_BYTES); - shake256_update(shake,message,message_len); + hash_ctx_t hash; + hash_init_with_dom(hash,prehashed,context,context_len); + hash_update(hash,signature,$(C_NS)_EDDSA_PUBLIC_BYTES); + hash_update(hash,pubkey,$(C_NS)_EDDSA_PUBLIC_BYTES); + hash_update(hash,message,message_len); uint8_t challenge[2*$(C_NS)_EDDSA_PRIVATE_BYTES]; - shake256_final(shake,challenge,sizeof(challenge)); - shake256_destroy(shake); + hash_final(hash,challenge,sizeof(challenge)); + hash_destroy(hash); API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge)); decaf_bzero(challenge,sizeof(challenge)); } diff --git a/src/per_curve/eddsa.tmpl.h b/src/per_curve/eddsa.tmpl.h new file mode 100644 index 0000000..076554e --- /dev/null +++ b/src/per_curve/eddsa.tmpl.h @@ -0,0 +1,113 @@ +/** @brief A group of prime order p, based on $(iso_to). */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Number of bytes in an EdDSA public key. */ +#define $(C_NS)_EDDSA_PUBLIC_BYTES $((gf_bits)/8 + 1) /* TODO: change name? */ + +/** Number of bytes in an EdDSA private key. */ +#define $(C_NS)_EDDSA_PRIVATE_BYTES $(C_NS)_EDDSA_PUBLIC_BYTES /* TODO: change name? */ + +/** Number of bytes in an EdDSA private key. */ +#define $(C_NS)_EDDSA_SIGNATURE_BYTES ($(C_NS)_EDDSA_PUBLIC_BYTES + $(C_NS)_EDDSA_PRIVATE_BYTES) /* TODO: change name? */ + +/** Does EdDSA support contexts? */ +#define $(C_NS)_EDDSA_SUPPORTS_CONTEXTS $(eddsa_supports_contexts) + +/** + * @brief EdDSA key generation. This function uses a different (non-Decaf) + * encoding. + * + * @param [out] pubkey The public key. + * @param [in] privkey The private key. + */ +void $(c_ns)_eddsa_derive_public_key ( + uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES], + const uint8_t privkey[$(C_NS)_EDDSA_PRIVATE_BYTES] +) API_VIS NONNULL NOINLINE; + +/** + * @brief EdDSA signing. + * + * @param [out] signature The signature. + * @param [in] privkey The private key. + * @param [in] pubkey The public key. + * @param [in] context A "context" for this signature of up to 255 bytes. + * @param [in] context_len Length of the context. + * @param [in] message The message to sign. + * @param [in] message_len The length of the message. + * @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign. + */ +void $(c_ns)_eddsa_sign ( + uint8_t signature[$(C_NS)_EDDSA_SIGNATURE_BYTES], + const uint8_t privkey[$(C_NS)_EDDSA_PRIVATE_BYTES], + const uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES], + const uint8_t *message, + size_t message_len, + uint8_t prehashed +#if $(C_NS)_EDDSA_SUPPORTS_CONTEXTS + , const uint8_t *context, + uint8_t context_len +#endif +) API_VIS __attribute__((nonnull(1,2,3))) NOINLINE; + +/** + * @brief EdDSA signature verification. + * + * Uses the standard (i.e. less-strict) verification formula. + * + * @param [in] signature The signature. + * @param [in] pubkey The public key. + * @param [in] context A "context" for this signature of up to 255 bytes. + * @param [in] context_len Length of the context. + * @param [in] message The message to verify. + * @param [in] message_len The length of the message. + * @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify. + */ +decaf_error_t $(c_ns)_eddsa_verify ( + const uint8_t signature[$(C_NS)_EDDSA_SIGNATURE_BYTES], + const uint8_t pubkey[$(C_NS)_EDDSA_PUBLIC_BYTES], + const uint8_t *message, + size_t message_len, + uint8_t prehashed +#if $(C_NS)_EDDSA_SUPPORTS_CONTEXTS + , const uint8_t *context, + uint8_t context_len +#endif +) API_VIS __attribute__((nonnull(1,2))) NOINLINE; + + + +/** + * @brief EdDSA point encoding. Used internally, exposed externally. + * + * @param [out] enc The encoded point. + * @param [in] p The point. + * + * FIXME: encode and decode aren't inverses of each other: they + * multiply by a factor. Rename to reflect this once the base + * point doctrine is worked out. + */ +void $(c_ns)_point_encode_like_eddsa ( + uint8_t enc[$(C_NS)_EDDSA_PUBLIC_BYTES], + const $(c_ns)_point_t p +) API_VIS NONNULL NOINLINE; + +/** + * @brief EdDSA point encoding. + * + * @param [out] enc The encoded point. + * @param [in] p The point. + */ +decaf_error_t $(c_ns)_point_decode_like_eddsa ( + $(c_ns)_point_t p, + const uint8_t enc[$(C_NS)_EDDSA_PUBLIC_BYTES] +) API_VIS NONNULL NOINLINE; + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index ce11da3..4dd6362 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -488,7 +488,7 @@ static void test_cfrg_vectors() { for (unsigned i=0; i