ed25519/readme.md

167 lines
5.7 KiB
Markdown
Raw Normal View History

2013-01-22 05:04:36 -05:00
Ed25519
2013-03-18 12:27:24 -04:00
=======
2013-01-22 05:04:36 -05:00
2013-01-22 05:31:58 -05:00
This is a portable implementation of [Ed25519](http://ed25519.cr.yp.to/) based
2013-03-24 17:37:43 -04:00
on the SUPERCOP "ref10" implementation. Additionally there is key exchanging
and scalar addition included to further aid building a PKI using Ed25519. All
2015-03-13 06:41:10 -04:00
code is licensed under the permissive zlib license.
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-03-24 17:37:43 -04:00
generation which uses standard OS cryptography APIs (`CryptGenRandom` on
Windows, `/dev/urandom` on nix). If you wish to be entirely 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
2013-04-11 12:35:02 -04:00
(which is simply a 256 bit (32 byte) cryptographic random number generator).
2013-01-22 05:51:53 -05:00
Performance
-----------
2013-03-24 17:37:43 -04:00
On a Windows 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-03-28 15:13:40 -04:00
Seed generation: 64us (15625 per second)
Key generation: 88us (11364 per second)
2013-03-27 17:07:38 -04:00
Message signing (short message): 87us (11494 per second)
Message verifying (short message): 228us (4386 per second)
Scalar addition: 100us (10000 per second)
Key exchange: 220us (4545 per second)
2013-01-22 05:51:53 -05:00
The speeds on other machines may vary. Sign/verify times will be higher with
2013-03-27 13:12:58 -04:00
longer messages. The implementation significantly benefits from 64 bit
architectures, if possible compile as 64 bit.
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
-----
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-03-24 17:37:43 -04:00
There are no defined types for seeds, private keys, public keys, shared secrets
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];
unsigned char public_key[32];
unsigned char private_key[64];
2013-02-04 11:57:09 -05:00
unsigned char scalar[32];
2013-03-24 17:37:43 -04:00
unsigned char shared_secret[32];
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-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
2014-05-16 11:16:26 -04: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
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.
2013-01-22 05:15:39 -05:00
2013-01-22 05:34:38 -05:00
```c
void ed25519_sign(unsigned char *signature,
2013-03-13 06:36:02 -04:00
const unsigned char *message, size_t message_len,
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 12:04:05 -05:00
Creates a signature of the given message with the given key pair. `signature`
must be a writable 64 byte buffer. `message` must have at least `message_len`
bytes to be read.
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,
const unsigned char *public_key);
2013-01-22 05:34:38 -05:00
```
2013-01-22 05:22:43 -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`
2013-02-04 12:04:05 -05:00
bytes to be read. Returns 1 if the signature matches, 0 otherwise.
2013-01-22 05:22:43 -05:00
2013-02-04 11:56:19 -05:00
```c
void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key,
const unsigned char *scalar);
```
2013-02-04 12:04:05 -05:00
Adds `scalar` to the given key pair where scalar is a 32 byte buffer (possibly
generated with `ed25519_create_seed`), generating a new key pair. You can
calculate the public key sum without knowing the private key and vice versa by
2013-02-04 12:14:11 -05:00
passing in `NULL` for the key you don't know. This is useful for enforcing
2013-03-24 17:37:43 -04:00
randomness on a key pair by a third party while only knowing the public key,
among other things. Warning: the last bit of the scalar is ignored - if
comparing scalars make sure to clear it with `scalar[31] &= 127`.
```c
void ed25519_key_exchange(unsigned char *shared_secret,
const unsigned char *public_key, const unsigned char *private_key);
```
Performs a key exchange on the given public key and private key, producing a
shared secret. It is recommended to hash the shared secret before using it.
`shared_secret` must be a 32 byte writable buffer where the shared secret will
be stored.
2013-02-04 11:56:19 -05:00
2013-01-22 05:22:43 -05:00
Example
-------
2013-03-24 17:37:43 -04:00
2013-01-22 05:34:38 -05:00
```c
unsigned char seed[32], public_key[32], private_key[64], signature[64];
2013-03-24 18:32:21 -04:00
unsigned char other_public_key[32], other_private_key[64], shared_secret[32];
2013-01-22 05:34:38 -05:00
const unsigned char message[] = "TEST MESSAGE";
2013-02-04 12:04:05 -05:00
/* create a random seed, and a key pair out of that seed */
2013-01-22 05:34:38 -05:00
if (ed25519_create_seed(seed)) {
printf("error while generating seed\n");
exit(1);
}
ed25519_create_keypair(public_key, private_key, seed);
2013-01-22 05:34:38 -05:00
2013-02-04 12:04:05 -05:00
/* create signature on the message with the key pair */
ed25519_sign(signature, message, strlen(message), public_key, private_key);
2013-01-22 05:34:38 -05:00
/* verify the signature */
if (ed25519_verify(signature, message, strlen(message), public_key)) {
2013-01-22 05:34:38 -05:00
printf("valid signature\n");
} else {
printf("invalid signature\n");
2013-01-22 05:34:38 -05:00
}
2013-03-24 18:32:21 -04:00
/* create a dummy keypair to use for a key exchange, normally you'd only have
the public key and receive it through some communication channel */
if (ed25519_create_seed(seed)) {
printf("error while generating seed\n");
exit(1);
}
ed25519_create_keypair(other_public_key, other_private_key, seed);
/* do a key exchange with other_public_key */
ed25519_key_exchange(shared_secret, other_public_key, private_key);
2013-03-24 18:33:27 -04:00
/*
the magic here is that ed25519_key_exchange(shared_secret, public_key,
other_private_key); would result in the same shared_secret
*/
2013-03-24 18:32:21 -04:00
```
2013-03-24 17:37:43 -04:00
License
-------
All code is in the public domain.