1Ed25519 2======= 3 4This is a portable implementation of [Ed25519](http://ed25519.cr.yp.to/) based 5on the SUPERCOP "ref10" implementation. Additionally there is key exchanging 6and scalar addition included to further aid building a PKI using Ed25519. All 7code is licensed under the permissive zlib license. 8 9All code is pure ANSI C without any dependencies, except for the random seed 10generation which uses standard OS cryptography APIs (`CryptGenRandom` on 11Windows, `/dev/urandom` on nix). If you wish to be entirely portable define 12`ED25519_NO_SEED`. This disables the `ed25519_create_seed` function, so if your 13application requires key generation you must supply your own seeding function 14(which is simply a 256 bit (32 byte) cryptographic random number generator). 15 16 17Performance 18----------- 19 20On a Windows machine with an Intel Pentium B970 @ 2.3GHz I got the following 21speeds (running on only one a single core): 22 23 Seed generation: 64us (15625 per second) 24 Key generation: 88us (11364 per second) 25 Message signing (short message): 87us (11494 per second) 26 Message verifying (short message): 228us (4386 per second) 27 Scalar addition: 100us (10000 per second) 28 Key exchange: 220us (4545 per second) 29 30The speeds on other machines may vary. Sign/verify times will be higher with 31longer messages. The implementation significantly benefits from 64 bit 32architectures, if possible compile as 64 bit. 33 34 35Usage 36----- 37 38Simply add all .c and .h files in the `src/` folder to your project and include 39`ed25519.h` in any file you want to use the API. If you prefer to use a shared 40library, only copy `ed25519.h` and define `ED25519_DLL` before importing. A 41windows DLL is pre-built. 42 43There are no defined types for seeds, private keys, public keys, shared secrets 44or signatures. Instead simple `unsigned char` buffers are used with the 45following sizes: 46 47```c 48unsigned char seed[32]; 49unsigned char signature[64]; 50unsigned char public_key[32]; 51unsigned char private_key[64]; 52unsigned char scalar[32]; 53unsigned char shared_secret[32]; 54``` 55 56API 57--- 58 59```c 60int ed25519_create_seed(unsigned char *seed); 61``` 62 63Creates a 32 byte random seed in `seed` for key generation. `seed` must be a 64writable 32 byte buffer. Returns 0 on success, and nonzero on failure. 65 66```c 67void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, 68 const unsigned char *seed); 69``` 70 71Creates a new key pair from the given seed. `public_key` must be a writable 32 72byte buffer, `private_key` must be a writable 64 byte buffer and `seed` must be 73a 32 byte buffer. 74 75```c 76void ed25519_sign(unsigned char *signature, 77 const unsigned char *message, size_t message_len, 78 const unsigned char *public_key, const unsigned char *private_key); 79``` 80 81Creates a signature of the given message with the given key pair. `signature` 82must be a writable 64 byte buffer. `message` must have at least `message_len` 83bytes to be read. 84 85```c 86int ed25519_verify(const unsigned char *signature, 87 const unsigned char *message, size_t message_len, 88 const unsigned char *public_key); 89``` 90 91Verifies the signature on the given message using `public_key`. `signature` 92must be a readable 64 byte buffer. `message` must have at least `message_len` 93bytes to be read. Returns 1 if the signature matches, 0 otherwise. 94 95```c 96void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, 97 const unsigned char *scalar); 98``` 99 100Adds `scalar` to the given key pair where scalar is a 32 byte buffer (possibly 101generated with `ed25519_create_seed`), generating a new key pair. You can 102calculate the public key sum without knowing the private key and vice versa by 103passing in `NULL` for the key you don't know. This is useful for enforcing 104randomness on a key pair by a third party while only knowing the public key, 105among other things. Warning: the last bit of the scalar is ignored - if 106comparing scalars make sure to clear it with `scalar[31] &= 127`. 107 108 109```c 110void ed25519_key_exchange(unsigned char *shared_secret, 111 const unsigned char *public_key, const unsigned char *private_key); 112``` 113 114Performs a key exchange on the given public key and private key, producing a 115shared secret. It is recommended to hash the shared secret before using it. 116`shared_secret` must be a 32 byte writable buffer where the shared secret will 117be stored. 118 119Example 120------- 121 122```c 123unsigned char seed[32], public_key[32], private_key[64], signature[64]; 124unsigned char other_public_key[32], other_private_key[64], shared_secret[32]; 125const unsigned char message[] = "TEST MESSAGE"; 126 127/* create a random seed, and a key pair out of that seed */ 128if (ed25519_create_seed(seed)) { 129 printf("error while generating seed\n"); 130 exit(1); 131} 132 133ed25519_create_keypair(public_key, private_key, seed); 134 135/* create signature on the message with the key pair */ 136ed25519_sign(signature, message, strlen(message), public_key, private_key); 137 138/* verify the signature */ 139if (ed25519_verify(signature, message, strlen(message), public_key)) { 140 printf("valid signature\n"); 141} else { 142 printf("invalid signature\n"); 143} 144 145/* create a dummy keypair to use for a key exchange, normally you'd only have 146the public key and receive it through some communication channel */ 147if (ed25519_create_seed(seed)) { 148 printf("error while generating seed\n"); 149 exit(1); 150} 151 152ed25519_create_keypair(other_public_key, other_private_key, seed); 153 154/* do a key exchange with other_public_key */ 155ed25519_key_exchange(shared_secret, other_public_key, private_key); 156 157/* 158 the magic here is that ed25519_key_exchange(shared_secret, public_key, 159 other_private_key); would result in the same shared_secret 160*/ 161 162``` 163 164License 165------- 166All code is released under the zlib license. See license.txt for details. 167