Branch data Line data Source code
1 : :
2 : : #ifndef COMPACT_DISABLE_X25519
3 : : #include "compact_x25519.h"
4 : : #include "c25519/c25519.h"
5 : : #include "c25519/sha512.h"
6 : : #include "compact_wipe.h"
7 : :
8 : 0 : void compact_x25519_keygen(
9 : : uint8_t private_key[X25519_KEY_SIZE],
10 : : uint8_t public_key[X25519_KEY_SIZE],
11 : : uint8_t random_seed[X25519_KEY_SIZE]
12 : : ) {
13 : 0 : memcpy(private_key, random_seed, X25519_KEY_SIZE);
14 : 0 : compact_wipe(random_seed, X25519_KEY_SIZE);
15 : 0 : c25519_prepare(private_key);
16 : 0 : c25519_smult(public_key, c25519_base_x, private_key);
17 : 0 : }
18 : :
19 : 0 : void compact_x25519_shared(
20 : : uint8_t shared_secret[X25519_SHARED_SIZE],
21 : : const uint8_t my_private_key[X25519_KEY_SIZE],
22 : : const uint8_t their_public_key[X25519_KEY_SIZE]
23 : : ) {
24 : 0 : c25519_smult(shared_secret, their_public_key, my_private_key);
25 : 0 : }
26 : :
27 : : #ifndef COMPACT_DISABLE_X25519_DERIVE
28 : : #if (X25519_KEY_SIZE + (2 * X25519_KEY_SIZE)) > SHA512_BLOCK_SIZE
29 : : #error "Unexpected key sizes"
30 : : #endif
31 : :
32 : 0 : static uint8_t* append(uint8_t *dst, const void * source, size_t length) {
33 : 0 : memcpy(dst, source, length);
34 : 0 : return dst + length;
35 : : }
36 : :
37 : 0 : void compact_x25519_derive_encryption_key(
38 : : uint8_t *encryption_key,
39 : : size_t key_size,
40 : : const uint8_t shared_secret[X25519_SHARED_SIZE],
41 : : const uint8_t public_key1[X25519_KEY_SIZE],
42 : : const uint8_t public_key2[X25519_KEY_SIZE]
43 : : ) {
44 : 0 : if (key_size > SHA512_HASH_SIZE) {
45 : : key_size = SHA512_HASH_SIZE;
46 : : }
47 : 0 : uint8_t key_data[X25519_SHARED_SIZE + 2 * X25519_KEY_SIZE];
48 : 0 : uint8_t *p = key_data;
49 : 0 : p = append(p, shared_secret, X25519_SHARED_SIZE);
50 : 0 : p = append(p, public_key1, X25519_KEY_SIZE);
51 : 0 : append(p, public_key2, X25519_KEY_SIZE);
52 : :
53 : 0 : struct sha512_state hasher;
54 : 0 : sha512_init(&hasher);
55 : 0 : sha512_final(&hasher, key_data, sizeof(key_data));
56 : 0 : sha512_get(&hasher, encryption_key, 0, key_size);
57 : :
58 : 0 : compact_wipe(key_data, X25519_SHARED_SIZE); // clear the session key at least
59 : 0 : }
60 : : #endif
61 : : #endif
|