diff --git a/include/sha512.h b/include/sha512.h index 469a597..68b636d 100644 --- a/include/sha512.h +++ b/include/sha512.h @@ -1,6 +1,8 @@ #ifndef SHA512_H #define SHA512_H +#include + #ifdef USE_OPENSSL #include @@ -17,8 +19,28 @@ unsigned char buf[128]; } sha512_context; #endif -int _ed_sha512_init(sha512_context * md); -int _ed_sha512_final(sha512_context * md, unsigned char *out); -int _ed_sha512_update(sha512_context * md, const unsigned char *in, size_t inlen); -int _ed_sha512(const unsigned char *message, size_t message_len, unsigned char *out); + +typedef struct sha512_functions_ { + int(*_ed_sha512_init)(sha512_context*); + int(*_ed_sha512_final)(sha512_context*, unsigned char *); + int(*_ed_sha512_update)(sha512_context*, const unsigned char *, size_t); +} sha512_functions; +extern sha512_functions _ed_sha512_functions; + +void _ed_sha512_validate() { + assert(_ed_sha512_functions._ed_sha512_init); + assert(_ed_sha512_functions._ed_sha512_final); + assert(_ed_sha512_functions._ed_sha512_update); +} +int _ed_sha512(const unsigned char *message, size_t message_len, unsigned char *out) { + _ed_sha512_validate(); + + int result = 1; + sha512_context ctx; + result &= _ed_sha512_functions._ed_sha512_init(&ctx); + result &= _ed_sha512_functions._ed_sha512_update(&ctx, message, message_len); + result &= _ed_sha512_functions._ed_sha512_final(&ctx, out); + return result; +} + #endif diff --git a/src/add_scalar.c b/src/add_scalar.c index 9263b7b..d5e8919 100644 --- a/src/add_scalar.c +++ b/src/add_scalar.c @@ -31,10 +31,11 @@ void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, c sc_muladd(private_key, SC_1, n, private_key); // https://github.com/orlp/ed25519/issues/3 - _ed_sha512_init(&hash); - _ed_sha512_update(&hash, private_key + 32, 32); - _ed_sha512_update(&hash, scalar, 32); - _ed_sha512_final(&hash, hashbuf); + _ed_sha512_validate(); + _ed_sha512_functions._ed_sha512_init(&hash); + _ed_sha512_functions._ed_sha512_update(&hash, private_key + 32, 32); + _ed_sha512_functions._ed_sha512_update(&hash, scalar, 32); + _ed_sha512_functions._ed_sha512_final(&hash, hashbuf); for (i = 0; i < 32; ++i) { private_key[32 + i] = hashbuf[i]; } diff --git a/src/sha512.c b/src/sha512.c index 7cb1a17..bdcb972 100644 --- a/src/sha512.c +++ b/src/sha512.c @@ -269,3 +269,9 @@ int _ed_sha512(const unsigned char *message, size_t message_len, unsigned char * if ((ret = _ed_sha512_final(&ctx, out))) return ret; return 0; } + +extern sha512_functions _ed_sha512_functions = { + _ed_sha512_init, + _ed_sha512_final, + _ed_sha512_update +}; \ No newline at end of file diff --git a/src/sha512_openssl.c b/src/sha512_openssl.c index 27573c2..a3a9712 100644 --- a/src/sha512_openssl.c +++ b/src/sha512_openssl.c @@ -1,6 +1,7 @@ #include #include "../include/sha512.h" + int _ed_sha512_init(sha512_context * md) { return SHA512_Init(md) != 1; /* Returns 0 on success */ } @@ -13,6 +14,8 @@ int _ed_sha512_update(sha512_context * md, const unsigned char *in, size_t inlen return SHA512_Update(md, in, inlen) != 1; /* Returns 0 on success */ } -int _ed_sha512(const unsigned char *message, size_t message_len, unsigned char *out) { - return SHA512(message, message_len, out) != 0; /* Returns 0 on success */ -} \ No newline at end of file +extern sha512_functions _ed_sha512_functions = { + _ed_sha512_init, + _ed_sha512_final, + _ed_sha512_update +}; \ No newline at end of file diff --git a/src/sign.c b/src/sign.c index 1a0c898..7b7e190 100644 --- a/src/sign.c +++ b/src/sign.c @@ -11,20 +11,21 @@ void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t ge_p3 R; - _ed_sha512_init(&hash); - _ed_sha512_update(&hash, private_key + 32, 32); - _ed_sha512_update(&hash, message, message_len); - _ed_sha512_final(&hash, r); + _ed_sha512_validate(); + _ed_sha512_functions._ed_sha512_init(&hash); + _ed_sha512_functions._ed_sha512_update(&hash, private_key + 32, 32); + _ed_sha512_functions._ed_sha512_update(&hash, message, message_len); + _ed_sha512_functions._ed_sha512_final(&hash, r); sc_reduce(r); ge_scalarmult_base(&R, r); ge_p3_tobytes(signature, &R); - _ed_sha512_init(&hash); - _ed_sha512_update(&hash, signature, 32); - _ed_sha512_update(&hash, public_key, 32); - _ed_sha512_update(&hash, message, message_len); - _ed_sha512_final(&hash, hram); + _ed_sha512_functions._ed_sha512_init(&hash); + _ed_sha512_functions._ed_sha512_update(&hash, signature, 32); + _ed_sha512_functions._ed_sha512_update(&hash, public_key, 32); + _ed_sha512_functions._ed_sha512_update(&hash, message, message_len); + _ed_sha512_functions._ed_sha512_final(&hash, hram); sc_reduce(hram); sc_muladd(signature + 32, hram, private_key, r); diff --git a/src/verify.c b/src/verify.c index b51f169..b010a28 100644 --- a/src/verify.c +++ b/src/verify.c @@ -59,11 +59,11 @@ int ed25519_verify(const unsigned char *signature, const unsigned char *message, return 0; } - _ed_sha512_init(&hash); - _ed_sha512_update(&hash, signature, 32); - _ed_sha512_update(&hash, public_key, 32); - _ed_sha512_update(&hash, message, message_len); - _ed_sha512_final(&hash, h); + _ed_sha512_functions._ed_sha512_init(&hash); + _ed_sha512_functions._ed_sha512_update(&hash, signature, 32); + _ed_sha512_functions._ed_sha512_update(&hash, public_key, 32); + _ed_sha512_functions._ed_sha512_update(&hash, message, message_len); + _ed_sha512_functions._ed_sha512_final(&hash, h); sc_reduce(h); ge_double_scalarmult_vartime(&R, h, &A, signature + 32);