• Stars
    star
    487
  • Rank 90,352 (Top 2 %)
  • Language
    C
  • License
    zlib License
  • Created almost 12 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Portable C implementation of Ed25519, a high-speed high-security public-key signature system.

Ed25519

This is a portable implementation of Ed25519 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 licensed under the permissive zlib license.

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:

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];

Note: this library stores private keys in a different format than some other libraries, notably libsodium. They tend to store the concatenation of the seed and public_key as their private key representation. If you wish to be compatible with these libraries you must keep the seed around.

API

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.

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.

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.

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.

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.

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

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 released under the zlib license. See license.txt for details.

More Repositories

1

pdqsort

Pattern-defeating quicksort.
C++
2,334
star
2

glidesort

A Rust implementation of Glidesort, my stable adaptive quicksort/mergesort hybrid sorting algorithm.
Rust
1,571
star
3

slotmap

Slotmap data structure for Rust
Rust
1,104
star
4

polymur-hash

The PolymurHash universal hash function.
C
316
star
5

dev-on-windows

An opiniated guide to set up a development environment on Windows.
226
star
6

matt-parker-five-letter-clique

Rust
45
star
7

devector

Resizable contiguous sequence container with fast appends on either end.
C++
37
star
8

recursive

Easy recursion in Rust, without stack overflows.
Rust
28
star
9

num-ord

A wrapper type for cross-type numeric comparisons.
Rust
27
star
10

peekread

Rust crate for making Read streams peekable.
Rust
26
star
11

ReducePing

ReducePing is a small utility to tune the "TcpAckFrequency" setting of Windows to get better latency in TCP networked games.
C
20
star
12

aoc2022

My Advent of Code 2022 solutions, in Rust.
Rust
20
star
13

golf-cpu

Reference implementation of the GOLF CPU.
Python
17
star
14

pyglfw

Python bindings for GLFW
C
16
star
15

PyGG2

A Python rewrite of Gang Garrison 2
Python
14
star
16

pyth5

Clean-sheet rewrite of Pyth.
Python
13
star
17

bitwise-binary-search

Accompanying code for https://orlp.net/blog/bitwise-binary-search/.
C++
12
star
18

dotfiles

My dotfiles.
HTML
10
star
19

pygrafix

pygrafix is a Python/Cython hardware-accelerated 2D graphics library.
C
10
star
20

xcharter

XCharter font build.
Python
10
star
21

vim-bunlink

A replacement for :bdelete that decouples the concept of 'deleting a buffer' from 'closing a window'.
Vim Script
9
star
22

libop

My personal C++ library.
Objective-C
8
star
23

aoc2023

My Advent of Code 2023 solutions, in Rust.
Rust
7
star
24

vim-quick-replace

A quick find/replace plugin for Vim.
Vim Script
6
star
25

secudht

A secure design and implementation of the Kademlia DHT.
C
6
star
26

sum-bench

This is the code accompanying https://orlp.net/blog/taming-float-sums/.
Rust
6
star
27

multilive

Multiple poe.trade live searches at once.
JavaScript
5
star
28

iwyu

A small utility that helps you include the right C++ headers.
Python
4
star
29

aoc2021

My Advent of Code 2021 solutions, in Rust.
Rust
4
star
30

commonc

Various common C algorithms and things
C
3
star
31

stable-alloc-shim

A stable Rust shim for the unstable Allocator API.
Rust
3
star
32

synth

A real-time self-hosting MIDI software synth written in Rust from scratch.
Rust
3
star
33

qcon

Quake-style console for windows.
AutoHotkey
3
star
34

ncUI

A lightweight user interface for World of Warcraft - DEAD
Lua
3
star
35

deps

deps is a minimalistic building system for any process which consists of smaller processes that depend on each other.
Python
2
star
36

euler

My solutions for Project Euler.
C++
1
star
37

osrs-fragment-calc

OSRS fragment set calculator
HTML
1
star
38

hades-boons

Python
1
star
39

picture-in-picture

Java
1
star
40

Robotics2020-Final

This repository hosts my final project for the 2020 Robotics course at Leiden university.
JavaScript
1
star
41

boost-win-builds

Some Windows builds for Boost.
Shell
1
star
42

lolpriority

Little tool for Leage of Legends, automatically puts the LoLClient.exe process on low priority when the in-game client is open for extra performance.
C
1
star
43

amazons

Web-based Game of the Amazons
CSS
1
star
44

distris

Distributed socializing.
C++
1
star
45

p

C++
1
star
46

poe-trade-qol

Quality of life for PoE's trade site.
JavaScript
1
star
47

poedps

A Path of Exile weapon DPS calculator with optional crafting.
JavaScript
1
star
48

StrongholdCoords

An application for finding out the exact coordinates of end portal frames in Minecraft seeds.
Java
1
star
49

unite-git-repo

A source for Unite.vim that lists all files from the git repository root.
Vim Script
1
star
50

pyflat

pyflat is a Python hardware-accelerated 2D graphics library.
C
1
star