2013-01-22 05:04:36 -05:00
|
|
|
Ed25519
|
|
|
|
-------
|
|
|
|
|
2013-01-22 05:31:58 -05:00
|
|
|
This is a portable implementation of [Ed25519](http://ed25519.cr.yp.to/) based
|
|
|
|
on the SUPERCOP "ref10" implementation. All code is in the public domain.
|
2013-01-22 05:04:36 -05:00
|
|
|
|
2013-01-22 05:15:39 -05:00
|
|
|
All code is pure ANSI C without any dependencies, except for the random seed
|
2013-02-04 07:42:59 -05:00
|
|
|
generation which uses standard OS cryptography APIs. If you wish to be entirely
|
2013-02-04 07:47:10 -05:00
|
|
|
portable define `ED25519_NO_SEED`. This disables the `ed25519_create_seed`
|
|
|
|
function, so if your application requires key generation you must supply your
|
|
|
|
own seeding function (simply a 32 byte random number generator).
|
2013-01-22 05:51:53 -05:00
|
|
|
|
|
|
|
|
|
|
|
Performance
|
|
|
|
-----------
|
|
|
|
|
2013-02-04 07:47:10 -05:00
|
|
|
On a machine with an Intel Pentium B970 @ 2.3GHz I got the following speeds (running
|
|
|
|
on only one a single core):
|
2013-01-22 05:51:53 -05:00
|
|
|
|
2013-02-04 07:42:59 -05:00
|
|
|
Seed + key generation: 345us
|
|
|
|
Message signing (short message): 256us
|
|
|
|
Message verifying (short message): 777us
|
2013-01-22 05:51:53 -05:00
|
|
|
|
2013-02-04 07:42:59 -05:00
|
|
|
The speeds on other machines may vary. Sign/verify times will be higher with
|
|
|
|
longer messages.
|
2013-01-22 05:51:53 -05:00
|
|
|
|
2013-01-22 05:07:11 -05:00
|
|
|
|
2013-01-22 05:04:36 -05:00
|
|
|
Usage
|
|
|
|
-----
|
|
|
|
|
2013-02-04 07:42:59 -05:00
|
|
|
Simply add all .c and .h files in the `src/` folder to your project and 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.
|
2013-01-22 05:04:36 -05:00
|
|
|
|
2013-02-04 07:42:59 -05:00
|
|
|
There are no defined types for seeds, private keys, public keys or signatures.
|
|
|
|
Instead simple `unsigned char` buffers are used with the following sizes:
|
2013-01-22 05:04:36 -05:00
|
|
|
|
2013-01-22 05:34:38 -05:00
|
|
|
```c
|
|
|
|
unsigned char seed[32];
|
|
|
|
unsigned char signature[64];
|
2013-02-04 07:34:01 -05:00
|
|
|
unsigned char public_key[32];
|
|
|
|
unsigned char private_key[64];
|
2013-01-22 05:34:38 -05:00
|
|
|
```
|
2013-01-22 05:15:39 -05:00
|
|
|
|
|
|
|
API
|
|
|
|
---
|
|
|
|
|
2013-01-22 05:34:38 -05:00
|
|
|
```c
|
|
|
|
int ed25519_create_seed(unsigned char *seed);
|
|
|
|
```
|
2013-02-04 07:42:59 -05:00
|
|
|
|
2013-01-22 05:15:39 -05:00
|
|
|
Creates a 32 byte random seed in `seed` for key generation. `seed` must be a
|
2013-01-22 05:22:43 -05:00
|
|
|
writable 32 byte buffer. Returns 0 on success, and nonzero on failure.
|
2013-01-22 05:15:39 -05:00
|
|
|
|
2013-01-22 05:34:38 -05:00
|
|
|
```c
|
2013-02-04 07:34:01 -05:00
|
|
|
void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed);
|
2013-01-22 05:34:38 -05:00
|
|
|
```
|
2013-01-22 05:15:39 -05:00
|
|
|
|
2013-02-04 07:34:01 -05:00
|
|
|
Creates a new key pair from the given seed. `public_key` must be a writable 32
|
2013-02-04 07:42:59 -05:00
|
|
|
byte buffer, `private_key` must be a writable 64 byte buffer and `seed` must be
|
|
|
|
a 32 byte buffer.
|
2013-01-22 05:15:39 -05:00
|
|
|
|
2013-01-22 05:34:38 -05:00
|
|
|
```c
|
|
|
|
void ed25519_sign(unsigned char *signature,
|
|
|
|
const unsigned char *message, size_t message_len,
|
2013-02-04 07:34:01 -05:00
|
|
|
const unsigned char *public_key, const unsigned char *private_key);
|
2013-01-22 05:34:38 -05:00
|
|
|
```
|
2013-01-22 05:22:43 -05:00
|
|
|
|
2013-02-04 07:42:59 -05:00
|
|
|
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. The given keypair must be a
|
|
|
|
keypair generated by `ed25519_create_keypair`.
|
2013-01-22 05:22:43 -05:00
|
|
|
|
2013-01-22 05:34:38 -05:00
|
|
|
```c
|
|
|
|
int ed25519_verify(const unsigned char *signature,
|
|
|
|
const unsigned char *message, size_t message_len,
|
2013-02-04 07:34:01 -05:00
|
|
|
const unsigned char *public_key);
|
2013-01-22 05:34:38 -05:00
|
|
|
```
|
2013-01-22 05:22:43 -05:00
|
|
|
|
2013-02-04 07:42:59 -05:00
|
|
|
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. `public_key` must be a 32 byte public key generated by
|
2013-02-04 07:34:01 -05:00
|
|
|
`ed25519_create_keypair`. Returns 1 if the signature matches, 0 otherwise.
|
2013-01-22 05:22:43 -05:00
|
|
|
|
|
|
|
Example
|
|
|
|
-------
|
2013-01-22 05:34:38 -05:00
|
|
|
```c
|
2013-02-04 07:34:01 -05:00
|
|
|
unsigned char seed[32], public_key[32], private_key[64], signature[64];
|
2013-01-22 05:34:38 -05:00
|
|
|
const unsigned char message[] = "TEST MESSAGE";
|
|
|
|
|
|
|
|
/* create a random seed, and a keypair out of that seed */
|
|
|
|
if (ed25519_create_seed(seed)) {
|
|
|
|
printf("error while generating seed\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2013-02-04 07:34:01 -05:00
|
|
|
ed25519_create_keypair(public_key, private_key, seed);
|
2013-01-22 05:34:38 -05:00
|
|
|
|
2013-02-04 07:34:01 -05:00
|
|
|
/* create signature on the message with the keypair */
|
|
|
|
ed25519_sign(signature, message, strlen(message), public_key, private_key);
|
2013-01-22 05:34:38 -05:00
|
|
|
|
|
|
|
/* verify the signature */
|
2013-02-04 07:34:01 -05:00
|
|
|
if (ed25519_verify(signature, message, strlen(message), public_key)) {
|
2013-01-22 05:34:38 -05:00
|
|
|
printf("valid signature\n");
|
2013-02-04 07:34:01 -05:00
|
|
|
} else {
|
|
|
|
printf("invalid signature\n");
|
2013-01-22 05:34:38 -05:00
|
|
|
}
|
2013-02-04 07:34:01 -05:00
|
|
|
```
|