aboutsummaryrefslogtreecommitdiff
path: root/readme.md
diff options
context:
space:
mode:
authorMark Haines <mark.haines@matrix.org>2015-03-03 11:14:50 +0000
committerMark Haines <mark.haines@matrix.org>2015-03-03 11:14:50 +0000
commit498dfabf9848286be003b42941c323a045d9fa46 (patch)
treee22dbf371b9a7ac3aa545af40ba6982809a45c55 /readme.md
Squashed 'lib/ed25519/' content from commit 1fc4a2f
git-subtree-dir: lib/ed25519 git-subtree-split: 1fc4a2ff69fe111875bd5efcc8523e40b18cf673
Diffstat (limited to 'readme.md')
-rw-r--r--readme.md166
1 files changed, 166 insertions, 0 deletions
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..676a631
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,166 @@
+Ed25519
+=======
+
+This is a portable implementation of [Ed25519](http://ed25519.cr.yp.to/) based
+on the SUPERCOP "ref10" implementation. Additionally there is key exchanging
+and scalar addition included to further aid building a PKI using Ed25519. All
+code is in the public domain.
+
+All code is pure ANSI C without any dependencies, except for the random seed
+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
+(which is simply a 256 bit (32 byte) cryptographic random number generator).
+
+
+Performance
+-----------
+
+On a Windows machine with an Intel Pentium B970 @ 2.3GHz I got the following
+speeds (running on only one a single core):
+
+ Seed generation: 64us (15625 per second)
+ Key generation: 88us (11364 per second)
+ 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)
+
+The speeds on other machines may vary. Sign/verify times will be higher with
+longer messages. The implementation significantly benefits from 64 bit
+architectures, if possible compile as 64 bit.
+
+
+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.
+
+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:
+
+```c
+unsigned char seed[32];
+unsigned char signature[64];
+unsigned char public_key[32];
+unsigned char private_key[64];
+unsigned char scalar[32];
+unsigned char shared_secret[32];
+```
+
+API
+---
+
+```c
+int ed25519_create_seed(unsigned char *seed);
+```
+
+Creates a 32 byte random seed in `seed` for key generation. `seed` must be a
+writable 32 byte buffer. Returns 0 on success, and nonzero on failure.
+
+```c
+void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key,
+ const unsigned char *seed);
+```
+
+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.
+
+```c
+void ed25519_sign(unsigned char *signature,
+ const unsigned char *message, size_t message_len,
+ const unsigned char *public_key, const unsigned char *private_key);
+```
+
+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.
+
+```c
+int ed25519_verify(const unsigned char *signature,
+ const unsigned char *message, size_t message_len,
+ const unsigned char *public_key);
+```
+
+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`
+bytes to be read. Returns 1 if the signature matches, 0 otherwise.
+
+```c
+void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key,
+ const unsigned char *scalar);
+```
+
+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
+passing in `NULL` for the key you don't know. This is useful for enforcing
+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.
+
+Example
+-------
+
+```c
+unsigned char seed[32], public_key[32], private_key[64], signature[64];
+unsigned char other_public_key[32], other_private_key[64], shared_secret[32];
+const unsigned char message[] = "TEST MESSAGE";
+
+/* create a random seed, and a key pair out of that seed */
+if (ed25519_create_seed(seed)) {
+ printf("error while generating seed\n");
+ exit(1);
+}
+
+ed25519_create_keypair(public_key, private_key, seed);
+
+/* create signature on the message with the key pair */
+ed25519_sign(signature, message, strlen(message), public_key, private_key);
+
+/* verify the signature */
+if (ed25519_verify(signature, message, strlen(message), public_key)) {
+ printf("valid signature\n");
+} else {
+ printf("invalid signature\n");
+}
+
+/* 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);
+
+/*
+ the magic here is that ed25519_key_exchange(shared_secret, public_key,
+ other_private_key); would result in the same shared_secret
+*/
+
+```
+
+License
+-------
+All code is in the public domain.