Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/ed25519.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsign
void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar);
void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key);

void * ED25519_DECLSPEC ed25519_verify_begin(const unsigned char *signature, const unsigned char *public_key);
void ED25519_DECLSPEC ed25519_verify_update(void * hash, const unsigned char *message, size_t message_len);
int ED25519_DECLSPEC ed25519_verify_end(void * hash, const unsigned char *signature);


#ifdef __cplusplus
}
Expand Down
57 changes: 56 additions & 1 deletion src/verify.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#include <malloc.h>
#include <string.h>

#include "ed25519.h"
#include "sha512.h"
#include "ge.h"
Expand Down Expand Up @@ -64,7 +67,7 @@ int ed25519_verify(const unsigned char *signature, const unsigned char *message,
sha512_update(&hash, public_key, 32);
sha512_update(&hash, message, message_len);
sha512_final(&hash, h);

sc_reduce(h);
ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
ge_tobytes(checker, &R);
Expand All @@ -75,3 +78,55 @@ int ed25519_verify(const unsigned char *signature, const unsigned char *message,

return 1;
}

typedef struct context_
{
sha512_context hash;
ge_p3 A;
} context;

void * ed25519_verify_begin(const unsigned char *signature, const unsigned char *public_key) {
ge_p3 A;

if (signature[63] & 224) {
return NULL;
}

if (ge_frombytes_negate_vartime(&A, public_key) != 0) {
return NULL;
}

context * ctx = (context*) malloc(sizeof(context));

memcpy(&ctx->A, &A, sizeof(A));

sha512_init(&ctx->hash);
sha512_update(&ctx->hash, signature, 32);
sha512_update(&ctx->hash, public_key, 32);

return ctx;
}

void ed25519_verify_update(void * ctx, const unsigned char *message, size_t message_len) {
sha512_update(&((context*)ctx)->hash, message, message_len);
}

int ed25519_verify_end(void * ctx, const unsigned char *signature) {
unsigned char h[64];
unsigned char checker[32];
ge_p2 R;

sha512_final(&((context*)ctx)->hash, h);

sc_reduce(h);
ge_double_scalarmult_vartime(&R, h, &((context*)ctx)->A, signature + 32);
ge_tobytes(checker, &R);

free(ctx);

if (!consttime_equal(checker, signature)) {
return 0;
}

return 1;
}