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. | ||