diff --git a/src/per_curve/decaf.tmpl.h b/src/per_curve/decaf.tmpl.h index e188131..a91499c 100644 --- a/src/per_curve/decaf.tmpl.h +++ b/src/per_curve/decaf.tmpl.h @@ -45,7 +45,7 @@ typedef struct gf_$(gf_shortname)_s { #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)_PUBLIC_BYTES + $(C_NS)_PRIVATE_BYTES) /* TODO: change name? */ +#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) @@ -425,6 +425,29 @@ 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] 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 NONNULL NOINLINE; /** * @brief EdDSA point encoding. diff --git a/src/per_curve/decaf.tmpl.hxx b/src/per_curve/decaf.tmpl.hxx index 625d07a..048f97e 100644 --- a/src/per_curve/decaf.tmpl.hxx +++ b/src/per_curve/decaf.tmpl.hxx @@ -658,12 +658,37 @@ public: /** The size of a private key */ static const size_t PRIVATE_BYTES = $(C_NS)_EDDSA_PRIVATE_BYTES; + /** The size of a private key */ + static const size_t SIGNATURE_BYTES = $(C_NS)_EDDSA_SIGNATURE_BYTES; + /* TODO: make into a nice class. Change name. Possibly move to another include file. */ static inline SecureBuffer generate_key ( - const FixedBlock &secret + const FixedBlock &priv ) { SecureBuffer out(PUBLIC_BYTES); - $(c_ns)_eddsa_derive_public_key(out.data(), secret.data()); + $(c_ns)_eddsa_derive_public_key(out.data(), priv.data()); + return out; + } + + static inline SecureBuffer sign ( + const FixedBlock &priv, + const FixedBlock &pub, + const Block &context, + const Block &message, + bool prehashed = false + ) throw(LengthException) { + if (context.size() > 255) { 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 + ); return out; } }; diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index 4a9a72b..e4b481d 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -456,7 +456,7 @@ static void test_cfrg_crypto() { } } -static const Block eddsa_sk, eddsa_pk; +static const Block eddsa_sk, eddsa_pk, eddsa_sig0; static void test_cfrg_vectors() { Test test("CFRG test vectors"); @@ -465,8 +465,6 @@ static void test_cfrg_vectors() { int the_ntests = (NTESTS < 1000000) ? 1000 : 1000000; - - /* EdDSA */ if (eddsa_sk.size()) { SecureBuffer eddsa_pk2 = EdDSA::generate_key(eddsa_sk); @@ -477,7 +475,19 @@ static void test_cfrg_vectors() { for (unsigned i=0; i const Block Tests::eddsa_sk(ed448_eddsa_sk,57); template<> const Block Tests::eddsa_pk(ed448_eddsa_pk,57); +template<> const Block Tests::eddsa_sig0(ed448_eddsa_sig0,114); template<> const Block Tests::eddsa_sk(NULL,0); /* TODO */ template<> const Block Tests::eddsa_pk(NULL,0); /* TODO */ +template<> const Block Tests::eddsa_sig0(NULL,0); /* TODO */ int main(int argc, char **argv) { (void) argc; (void) argv; - run_for_all_curves(); if (passing) printf("Passed all tests.\n"); return passing ? 0 : 1;