do not compress private keys - changed terminologiy from verify/sign to public/private
This commit is contained in:
parent
4ea108d944
commit
b0de745a0c
BIN
ed25519.dll
BIN
ed25519.dll
Binary file not shown.
43
readme.md
43
readme.md
@ -31,15 +31,15 @@ include `ed25519.h` in any file you want to use the API. If you prefer to use
|
||||
a shared library, only copy `ed25519.h` and define `ED25519_DLL` before
|
||||
importing. A windows DLL is pre-built.
|
||||
|
||||
There are no defined types for seeds, signing keys, verifying keys or
|
||||
There are no defined types for seeds, private keys, public keys or
|
||||
signatures. Instead simple `unsigned char` buffers are used with the following
|
||||
sizes:
|
||||
|
||||
```c
|
||||
unsigned char seed[32];
|
||||
unsigned char signature[64];
|
||||
unsigned char verify_key[32];
|
||||
unsigned char signing_key[64];
|
||||
unsigned char public_key[32];
|
||||
unsigned char private_key[64];
|
||||
```
|
||||
|
||||
API
|
||||
@ -52,38 +52,37 @@ Creates a 32 byte random seed in `seed` for key generation. `seed` must be a
|
||||
writable 32 byte buffer. Returns 0 on success, and nonzero on failure.
|
||||
|
||||
```c
|
||||
void ed25519_create_keypair(unsigned char *verify_key, unsigned char *sign_key, const unsigned char *seed);
|
||||
void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed);
|
||||
```
|
||||
|
||||
Creates a new key pair from the given seed. `verify_key` must be a writable 32
|
||||
byte buffer, `sign_key` must be a writable 64 byte buffer and `seed` must be a 32 byte buffer.
|
||||
Creates a new key pair from the given seed. `public_key` must be a writable 32
|
||||
byte buffer, `private_key` must be a writable 64 byte buffer and `seed` must be a 32 byte buffer.
|
||||
|
||||
```c
|
||||
void ed25519_sign(unsigned char *signature,
|
||||
const unsigned char *message, size_t message_len,
|
||||
const unsigned char *sign_key);
|
||||
const unsigned char *public_key, const unsigned char *private_key);
|
||||
```
|
||||
|
||||
Creates a signature of the given message with `sign_key`. `signature` must be
|
||||
Creates a signature of the given message with the keypair `(public_key, private_key)`. `signature` must be
|
||||
a writable 64 byte buffer. `message` must have at least `message_len` bytes to
|
||||
be read. `sign_key` must be a 64 byte signing key generated by
|
||||
`ed25519_create_keypair`.
|
||||
be read. The given keypair must be a keypair generated by `ed25519_create_keypair`.
|
||||
|
||||
```c
|
||||
int ed25519_verify(const unsigned char *signature,
|
||||
const unsigned char *message, size_t message_len,
|
||||
const unsigned char *verify_key);
|
||||
const unsigned char *public_key);
|
||||
```
|
||||
|
||||
Verifies the signature on the given message using verify_key. `signature` must be
|
||||
Verifies the signature on the given message using `public_key`. `signature` must be
|
||||
a readable 64 byte buffer. `message` must have at least `message_len` bytes to
|
||||
be read. `sign_key` must be a 32 byte verifying key generated by
|
||||
`ed25519_create_keypair`. Returns 0 if the signature matches, 1 otherwise.
|
||||
be read. `public_key` must be a 32 byte public key generated by
|
||||
`ed25519_create_keypair`. Returns 1 if the signature matches, 0 otherwise.
|
||||
|
||||
Example
|
||||
-------
|
||||
```c
|
||||
unsigned char seed[32], sign_key[64], verify_key[32], signature[64];
|
||||
unsigned char seed[32], public_key[32], private_key[64], signature[64];
|
||||
const unsigned char message[] = "TEST MESSAGE";
|
||||
|
||||
/* create a random seed, and a keypair out of that seed */
|
||||
@ -92,15 +91,15 @@ if (ed25519_create_seed(seed)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ed25519_create_keypair(verify_key, sign_key, seed);
|
||||
ed25519_create_keypair(public_key, private_key, seed);
|
||||
|
||||
/* create signature on the message with the sign key */
|
||||
ed25519_sign(signature, message, strlen(message), sign_key);
|
||||
/* create signature on the message with the keypair */
|
||||
ed25519_sign(signature, message, strlen(message), public_key, private_key);
|
||||
|
||||
/* verify the signature */
|
||||
if (ed25519_verify(signature, message, strlen(message), verify_key)) {
|
||||
printf("invalid signature\n");
|
||||
} else {
|
||||
if (ed25519_verify(signature, message, strlen(message), public_key)) {
|
||||
printf("valid signature\n");
|
||||
} else {
|
||||
printf("invalid signature\n");
|
||||
}
|
||||
```
|
||||
```
|
||||
|
@ -24,13 +24,13 @@ extern "C" {
|
||||
int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed);
|
||||
#endif
|
||||
|
||||
void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *verify_key, unsigned char *sign_key, const unsigned char *seed);
|
||||
void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *sign_key);
|
||||
int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *verify_key);
|
||||
void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed);
|
||||
void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key);
|
||||
int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *private_key);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -3,24 +3,14 @@
|
||||
#include "ge.h"
|
||||
|
||||
|
||||
void ed25519_create_keypair(unsigned char *verify_key, unsigned char *sign_key, const unsigned char *seed) {
|
||||
unsigned char h[64];
|
||||
void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) {
|
||||
ge_p3 A;
|
||||
int i;
|
||||
|
||||
sha512(seed, 32, h);
|
||||
h[0] &= 248;
|
||||
h[31] &= 63;
|
||||
h[31] |= 64;
|
||||
sha512(seed, 32, private_key);
|
||||
private_key[0] &= 248;
|
||||
private_key[31] &= 63;
|
||||
private_key[31] |= 64;
|
||||
|
||||
ge_scalarmult_base(&A, h);
|
||||
ge_p3_tobytes(verify_key, &A);
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
sign_key[i] = seed[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
sign_key[32 + i] = verify_key[i];
|
||||
}
|
||||
ge_scalarmult_base(&A, private_key);
|
||||
ge_p3_tobytes(public_key, &A);
|
||||
}
|
||||
|
19
src/sign.c
19
src/sign.c
@ -4,20 +4,15 @@
|
||||
#include "sc.h"
|
||||
|
||||
|
||||
void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *sign_key) {
|
||||
unsigned char az[64];
|
||||
unsigned char r[64];
|
||||
unsigned char hram[64];
|
||||
ge_p3 R;
|
||||
void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) {
|
||||
sha512_context hash;
|
||||
unsigned char hram[64];
|
||||
unsigned char r[64];
|
||||
ge_p3 R;
|
||||
|
||||
sha512(sign_key, 32, az);
|
||||
az[0] &= 248;
|
||||
az[31] &= 63;
|
||||
az[31] |= 64;
|
||||
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, az + 32, 32);
|
||||
sha512_update(&hash, private_key + 32, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, r);
|
||||
|
||||
@ -27,10 +22,10 @@ void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t
|
||||
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, signature, 32);
|
||||
sha512_update(&hash, sign_key + 32, 32);
|
||||
sha512_update(&hash, public_key, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, hram);
|
||||
|
||||
sc_reduce(hram);
|
||||
sc_muladd(signature + 32, hram, az, r);
|
||||
sc_muladd(signature + 32, hram, private_key, r);
|
||||
}
|
||||
|
14
src/verify.c
14
src/verify.c
@ -44,7 +44,7 @@ static int consttime_equal(const unsigned char *x, const unsigned char *y) {
|
||||
return !r;
|
||||
}
|
||||
|
||||
int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *verify_key) {
|
||||
int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) {
|
||||
unsigned char h[64];
|
||||
unsigned char checker[32];
|
||||
sha512_context hash;
|
||||
@ -52,16 +52,16 @@ int ed25519_verify(const unsigned char *signature, const unsigned char *message,
|
||||
ge_p2 R;
|
||||
|
||||
if (signature[63] & 224) {
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ge_frombytes_negate_vartime(&A, verify_key) != 0) {
|
||||
return -1;
|
||||
if (ge_frombytes_negate_vartime(&A, public_key) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, signature, 32);
|
||||
sha512_update(&hash, verify_key, 32);
|
||||
sha512_update(&hash, public_key, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, h);
|
||||
|
||||
@ -70,8 +70,8 @@ int ed25519_verify(const unsigned char *signature, const unsigned char *message,
|
||||
ge_tobytes(checker, &R);
|
||||
|
||||
if (!consttime_equal(checker, signature)) {
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
28
test.c
28
test.c
@ -9,40 +9,42 @@
|
||||
const char message[] = "Hello, world!";
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
unsigned char sign_key[64], verify_key[32], seed[32];
|
||||
unsigned char public_key[32], private_key[64], seed[32];
|
||||
unsigned char signature[64];
|
||||
|
||||
clock_t start;
|
||||
clock_t end;
|
||||
int i;
|
||||
|
||||
FILE *f;
|
||||
|
||||
/* create a random seed, and a keypair out of that seed */
|
||||
ed25519_create_seed(seed);
|
||||
ed25519_create_keypair(verify_key, sign_key, seed);
|
||||
ed25519_create_keypair(public_key, private_key, seed);
|
||||
|
||||
/* create signature on the message with the sign key */
|
||||
ed25519_sign(signature, message, strlen(message), sign_key);
|
||||
/* create signature on the message with the keypair */
|
||||
ed25519_sign(signature, message, strlen(message), public_key, private_key);
|
||||
|
||||
/* verify the signature */
|
||||
if (ed25519_verify(signature, message, strlen(message), verify_key)) {
|
||||
printf("invalid signature\n");
|
||||
} else {
|
||||
if (ed25519_verify(signature, message, strlen(message), public_key)) {
|
||||
printf("valid signature\n");
|
||||
} else {
|
||||
printf("invalid signature\n");
|
||||
}
|
||||
|
||||
/* make a slight adjustment and verify again */
|
||||
signature[44] ^= 0x10;
|
||||
if (ed25519_verify(signature, message, strlen(message), verify_key)) {
|
||||
printf("correctly detected signature change\n");
|
||||
if (ed25519_verify(signature, message, strlen(message), public_key)) {
|
||||
printf("did not detect signature change\n");
|
||||
} else {
|
||||
printf("incorrectly accepted signature change\n");
|
||||
printf("correctly detected signature change\n");
|
||||
}
|
||||
|
||||
/* test performance */
|
||||
printf("testing sign performance: ");
|
||||
start = clock();
|
||||
for (i = 0; i < 10000; ++i) {
|
||||
ed25519_sign(signature, message, strlen(message), sign_key);
|
||||
ed25519_sign(signature, message, strlen(message), public_key, private_key);
|
||||
}
|
||||
end = clock();
|
||||
|
||||
@ -51,11 +53,11 @@ int main(int argc, char *argv[]) {
|
||||
printf("testing verify performance: ");
|
||||
start = clock();
|
||||
for (i = 0; i < 10000; ++i) {
|
||||
ed25519_verify(signature, message, strlen(message), verify_key);
|
||||
ed25519_verify(signature, message, strlen(message), public_key);
|
||||
}
|
||||
end = clock();
|
||||
|
||||
printf("%fus per signature\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user