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
|
a shared library, only copy `ed25519.h` and define `ED25519_DLL` before
|
||||||
importing. A windows DLL is pre-built.
|
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
|
signatures. Instead simple `unsigned char` buffers are used with the following
|
||||||
sizes:
|
sizes:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
unsigned char seed[32];
|
unsigned char seed[32];
|
||||||
unsigned char signature[64];
|
unsigned char signature[64];
|
||||||
unsigned char verify_key[32];
|
unsigned char public_key[32];
|
||||||
unsigned char signing_key[64];
|
unsigned char private_key[64];
|
||||||
```
|
```
|
||||||
|
|
||||||
API
|
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.
|
writable 32 byte buffer. Returns 0 on success, and nonzero on failure.
|
||||||
|
|
||||||
```c
|
```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
|
Creates a new key pair from the given seed. `public_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.
|
byte buffer, `private_key` must be a writable 64 byte buffer and `seed` must be a 32 byte buffer.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void ed25519_sign(unsigned char *signature,
|
void ed25519_sign(unsigned char *signature,
|
||||||
const unsigned char *message, size_t message_len,
|
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
|
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
|
be read. The given keypair must be a keypair generated by `ed25519_create_keypair`.
|
||||||
`ed25519_create_keypair`.
|
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int ed25519_verify(const unsigned char *signature,
|
int ed25519_verify(const unsigned char *signature,
|
||||||
const unsigned char *message, size_t message_len,
|
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
|
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
|
be read. `public_key` must be a 32 byte public key generated by
|
||||||
`ed25519_create_keypair`. Returns 0 if the signature matches, 1 otherwise.
|
`ed25519_create_keypair`. Returns 1 if the signature matches, 0 otherwise.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
```c
|
```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";
|
const unsigned char message[] = "TEST MESSAGE";
|
||||||
|
|
||||||
/* create a random seed, and a keypair out of that seed */
|
/* create a random seed, and a keypair out of that seed */
|
||||||
@ -92,15 +91,15 @@ if (ed25519_create_seed(seed)) {
|
|||||||
exit(1);
|
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 */
|
/* create signature on the message with the keypair */
|
||||||
ed25519_sign(signature, message, strlen(message), sign_key);
|
ed25519_sign(signature, message, strlen(message), public_key, private_key);
|
||||||
|
|
||||||
/* verify the signature */
|
/* verify the signature */
|
||||||
if (ed25519_verify(signature, message, strlen(message), verify_key)) {
|
if (ed25519_verify(signature, message, strlen(message), public_key)) {
|
||||||
printf("invalid signature\n");
|
|
||||||
} else {
|
|
||||||
printf("valid signature\n");
|
printf("valid signature\n");
|
||||||
|
} else {
|
||||||
|
printf("invalid signature\n");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -24,13 +24,13 @@ extern "C" {
|
|||||||
int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed);
|
int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *verify_key, unsigned char *sign_key, const unsigned char *seed);
|
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 *sign_key);
|
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 *verify_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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,24 +3,14 @@
|
|||||||
#include "ge.h"
|
#include "ge.h"
|
||||||
|
|
||||||
|
|
||||||
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) {
|
||||||
unsigned char h[64];
|
|
||||||
ge_p3 A;
|
ge_p3 A;
|
||||||
int i;
|
|
||||||
|
|
||||||
sha512(seed, 32, h);
|
sha512(seed, 32, private_key);
|
||||||
h[0] &= 248;
|
private_key[0] &= 248;
|
||||||
h[31] &= 63;
|
private_key[31] &= 63;
|
||||||
h[31] |= 64;
|
private_key[31] |= 64;
|
||||||
|
|
||||||
ge_scalarmult_base(&A, h);
|
ge_scalarmult_base(&A, private_key);
|
||||||
ge_p3_tobytes(verify_key, &A);
|
ge_p3_tobytes(public_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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
19
src/sign.c
19
src/sign.c
@ -4,20 +4,15 @@
|
|||||||
#include "sc.h"
|
#include "sc.h"
|
||||||
|
|
||||||
|
|
||||||
void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *sign_key) {
|
void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) {
|
||||||
unsigned char az[64];
|
|
||||||
unsigned char r[64];
|
|
||||||
unsigned char hram[64];
|
|
||||||
ge_p3 R;
|
|
||||||
sha512_context hash;
|
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_init(&hash);
|
||||||
sha512_update(&hash, az + 32, 32);
|
sha512_update(&hash, private_key + 32, 32);
|
||||||
sha512_update(&hash, message, message_len);
|
sha512_update(&hash, message, message_len);
|
||||||
sha512_final(&hash, r);
|
sha512_final(&hash, r);
|
||||||
|
|
||||||
@ -27,10 +22,10 @@ void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t
|
|||||||
|
|
||||||
sha512_init(&hash);
|
sha512_init(&hash);
|
||||||
sha512_update(&hash, signature, 32);
|
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_update(&hash, message, message_len);
|
||||||
sha512_final(&hash, hram);
|
sha512_final(&hash, hram);
|
||||||
|
|
||||||
sc_reduce(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;
|
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 h[64];
|
||||||
unsigned char checker[32];
|
unsigned char checker[32];
|
||||||
sha512_context hash;
|
sha512_context hash;
|
||||||
@ -52,16 +52,16 @@ int ed25519_verify(const unsigned char *signature, const unsigned char *message,
|
|||||||
ge_p2 R;
|
ge_p2 R;
|
||||||
|
|
||||||
if (signature[63] & 224) {
|
if (signature[63] & 224) {
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ge_frombytes_negate_vartime(&A, verify_key) != 0) {
|
if (ge_frombytes_negate_vartime(&A, public_key) != 0) {
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sha512_init(&hash);
|
sha512_init(&hash);
|
||||||
sha512_update(&hash, signature, 32);
|
sha512_update(&hash, signature, 32);
|
||||||
sha512_update(&hash, verify_key, 32);
|
sha512_update(&hash, public_key, 32);
|
||||||
sha512_update(&hash, message, message_len);
|
sha512_update(&hash, message, message_len);
|
||||||
sha512_final(&hash, h);
|
sha512_final(&hash, h);
|
||||||
|
|
||||||
@ -70,8 +70,8 @@ int ed25519_verify(const unsigned char *signature, const unsigned char *message,
|
|||||||
ge_tobytes(checker, &R);
|
ge_tobytes(checker, &R);
|
||||||
|
|
||||||
if (!consttime_equal(checker, signature)) {
|
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!";
|
const char message[] = "Hello, world!";
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
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];
|
unsigned char signature[64];
|
||||||
|
|
||||||
clock_t start;
|
clock_t start;
|
||||||
clock_t end;
|
clock_t end;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
/* create a random seed, and a keypair out of that seed */
|
/* create a random seed, and a keypair out of that seed */
|
||||||
ed25519_create_seed(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 */
|
/* create signature on the message with the keypair */
|
||||||
ed25519_sign(signature, message, strlen(message), sign_key);
|
ed25519_sign(signature, message, strlen(message), public_key, private_key);
|
||||||
|
|
||||||
/* verify the signature */
|
/* verify the signature */
|
||||||
if (ed25519_verify(signature, message, strlen(message), verify_key)) {
|
if (ed25519_verify(signature, message, strlen(message), public_key)) {
|
||||||
printf("invalid signature\n");
|
|
||||||
} else {
|
|
||||||
printf("valid signature\n");
|
printf("valid signature\n");
|
||||||
|
} else {
|
||||||
|
printf("invalid signature\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make a slight adjustment and verify again */
|
/* make a slight adjustment and verify again */
|
||||||
signature[44] ^= 0x10;
|
signature[44] ^= 0x10;
|
||||||
if (ed25519_verify(signature, message, strlen(message), verify_key)) {
|
if (ed25519_verify(signature, message, strlen(message), public_key)) {
|
||||||
printf("correctly detected signature change\n");
|
printf("did not detect signature change\n");
|
||||||
} else {
|
} else {
|
||||||
printf("incorrectly accepted signature change\n");
|
printf("correctly detected signature change\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test performance */
|
/* test performance */
|
||||||
printf("testing sign performance: ");
|
printf("testing sign performance: ");
|
||||||
start = clock();
|
start = clock();
|
||||||
for (i = 0; i < 10000; ++i) {
|
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();
|
end = clock();
|
||||||
|
|
||||||
@ -51,11 +53,11 @@ int main(int argc, char *argv[]) {
|
|||||||
printf("testing verify performance: ");
|
printf("testing verify performance: ");
|
||||||
start = clock();
|
start = clock();
|
||||||
for (i = 0; i < 10000; ++i) {
|
for (i = 0; i < 10000; ++i) {
|
||||||
ed25519_verify(signature, message, strlen(message), verify_key);
|
ed25519_verify(signature, message, strlen(message), public_key);
|
||||||
}
|
}
|
||||||
end = clock();
|
end = clock();
|
||||||
|
|
||||||
printf("%fus per signature\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000);
|
printf("%fus per signature\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user