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