• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..01-Aug-2019-

add_scalar.cH A D01-Aug-20192.1 KiB7044

ed25519.hH A D01-Aug-20191.2 KiB3929

fe.cH A D01-Aug-201937.9 KiB1,4921,178

fe.hH A D01-Aug-2019980 4223

fixedint.hH A D01-Aug-20192.5 KiB7351

ge.cH A D01-Aug-201910.1 KiB468338

ge.hH A D01-Aug-20191.6 KiB7549

key_exchange.cH A D01-Aug-20191.8 KiB8064

keypair.cH A D01-Aug-2019380 1712

precomp_data.hH A D01-Aug-201995.5 KiB1,3921,388

readme.mdH A D01-Aug-20195.7 KiB167128

sc.cH A D01-Aug-201922.3 KiB810774

sc.hH A D01-Aug-2019267 135

seed.cH A D01-Aug-2019644 4130

sha512.cH A D01-Aug-201910.8 KiB276189

sha512.hH A D01-Aug-2019489 2214

sign.cH A D01-Aug-20191,005 3931

verify.cH A D01-Aug-20191.3 KiB7867

readme.md

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