do not compress private keys - changed terminologiy from verify/sign to public/private

This commit is contained in:
Orson Peters 2013-02-04 13:34:01 +01:00
parent 4ea108d944
commit b0de745a0c
7 changed files with 61 additions and 75 deletions

Binary file not shown.

View File

@ -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");
}
```
```

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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
View File

@ -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;
}
}