Skip to content

Commit

Permalink
CPU optimizations.
Browse files Browse the repository at this point in the history
Use get_shared_key() in more places.
  • Loading branch information
irungentoo committed Mar 5, 2014
1 parent 3a1f259 commit 3bcc6e2
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 45 deletions.
75 changes: 49 additions & 26 deletions toxcore/DHT.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,29 +114,33 @@ static int client_id_cmp(ClientPair p1, ClientPair p2)
return c;
}

/* Copy shared_key to decrypt DHT packet from client_id into shared_key
/* Shared key generations are costly, it is therefor smart to store commonly used
* ones so that they can re used later without being computed again.
*
* If shared key is already in shared_keys, copy it to shared_key.
* else generate it into shared_key and copy it to shared_keys
*/
void DHT_get_shared_key(DHT *dht, uint8_t *shared_key, uint8_t *client_id)
void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, uint8_t *secret_key, uint8_t *client_id)
{
uint32_t i, num = ~0, curr = 0;

for (i = 0; i < MAX_KEYS_PER_SLOT; ++i) {
int index = client_id[30] * MAX_KEYS_PER_SLOT + i;

if (dht->shared_keys.keys[index].stored) {
if (memcmp(client_id, dht->shared_keys.keys[index].client_id, CLIENT_ID_SIZE) == 0) {
memcpy(shared_key, dht->shared_keys.keys[index].shared_key, crypto_box_BEFORENMBYTES);
++dht->shared_keys.keys[index].times_requested;
dht->shared_keys.keys[index].time_last_requested = unix_time();
if (shared_keys->keys[index].stored) {
if (memcmp(client_id, shared_keys->keys[index].client_id, CLIENT_ID_SIZE) == 0) {
memcpy(shared_key, shared_keys->keys[index].shared_key, crypto_box_BEFORENMBYTES);
++shared_keys->keys[index].times_requested;
shared_keys->keys[index].time_last_requested = unix_time();
return;
}

if (num != 0) {
if (is_timeout(dht->shared_keys.keys[index].time_last_requested, KEYS_TIMEOUT)) {
if (is_timeout(shared_keys->keys[index].time_last_requested, KEYS_TIMEOUT)) {
num = 0;
curr = index;
} else if (num > dht->shared_keys.keys[index].times_requested) {
num = dht->shared_keys.keys[index].times_requested;
} else if (num > shared_keys->keys[index].times_requested) {
num = shared_keys->keys[index].times_requested;
curr = index;
}
}
Expand All @@ -148,17 +152,34 @@ void DHT_get_shared_key(DHT *dht, uint8_t *shared_key, uint8_t *client_id)
}
}

encrypt_precompute(client_id, dht->self_secret_key, shared_key);
encrypt_precompute(client_id, secret_key, shared_key);

if (num != (uint32_t)~0) {
dht->shared_keys.keys[curr].stored = 1;
dht->shared_keys.keys[curr].times_requested = 1;
memcpy(dht->shared_keys.keys[curr].client_id, client_id, CLIENT_ID_SIZE);
memcpy(dht->shared_keys.keys[curr].shared_key, shared_key, crypto_box_BEFORENMBYTES);
dht->shared_keys.keys[curr].time_last_requested = unix_time();
shared_keys->keys[curr].stored = 1;
shared_keys->keys[curr].times_requested = 1;
memcpy(shared_keys->keys[curr].client_id, client_id, CLIENT_ID_SIZE);
memcpy(shared_keys->keys[curr].shared_key, shared_key, crypto_box_BEFORENMBYTES);
shared_keys->keys[curr].time_last_requested = unix_time();
}
}

/* Copy shared_key to decrypt DHT packet from client_id into shared_key
* for packets that we recieve.
*/
void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, uint8_t *client_id)
{
return get_shared_key(&dht->shared_keys_recv, shared_key, dht->self_secret_key, client_id);
}

/* Copy shared_key to decrypt DHT packet from client_id into shared_key
* for packets that we send.
*/
void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, uint8_t *client_id)
{
return get_shared_key(&dht->shared_keys_sent, shared_key, dht->self_secret_key, client_id);
}


/* Check if client with client_id is already in list of length length.
* If it is then set its corresponding timestamp to current time.
* If the id is already in the list with a different ip_port, update it.
Expand Down Expand Up @@ -867,12 +888,13 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
memcpy(plain, client_id, CLIENT_ID_SIZE);
memcpy(plain + CLIENT_ID_SIZE, encrypted_message, NODES_ENCRYPTED_MESSAGE_LENGTH);

int len = encrypt_data( public_key,
dht->self_secret_key,
nonce,
plain,
CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH,
encrypt );
uint8_t shared_key[crypto_box_BEFORENMBYTES];
DHT_get_shared_key_sent(dht, shared_key, public_key);
int len = encrypt_data_fast( shared_key,
nonce,
plain,
CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH,
encrypt );

if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES)
return -1;
Expand Down Expand Up @@ -1036,7 +1058,7 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32
uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH];
uint8_t shared_key[crypto_box_BEFORENMBYTES];

DHT_get_shared_key(dht, shared_key, packet + 1);
DHT_get_shared_key_recv(dht, shared_key, packet + 1);
int len = decrypt_data_fast( shared_key,
packet + 1 + CLIENT_ID_SIZE,
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
Expand Down Expand Up @@ -1111,9 +1133,10 @@ static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet,
if (num_nodes > MAX_SENT_NODES) /* too long */
return 1;

int len = decrypt_data(
packet + 1,
dht->self_secret_key,
uint8_t shared_key[crypto_box_BEFORENMBYTES];
DHT_get_shared_key_sent(dht, shared_key, packet + 1);
int len = decrypt_data_fast(
shared_key,
packet + 1 + CLIENT_ID_SIZE,
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
Expand Down
22 changes: 18 additions & 4 deletions toxcore/DHT.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,15 @@ typedef struct {
/* struct to store some shared keys so we don't have to regenerate them for each request. */
#define MAX_KEYS_PER_SLOT 4
#define KEYS_TIMEOUT 600
struct SHARED_KEYS {
typedef struct {
struct {
uint8_t client_id[CLIENT_ID_SIZE];
uint8_t shared_key[crypto_box_BEFORENMBYTES];
uint32_t times_requested;
uint8_t stored; /* 0 if not, 1 if is */
uint64_t time_last_requested;
} keys[256 * MAX_KEYS_PER_SLOT];
};
} Shared_Keys;

/*----------------------------------------------------------------------------------*/

Expand All @@ -175,7 +175,8 @@ typedef struct {
DHT_Friend *friends_list;
uint16_t num_friends;

struct SHARED_KEYS shared_keys;
Shared_Keys shared_keys_recv;
Shared_Keys shared_keys_sent;

struct PING *ping;
#ifdef ENABLE_ASSOC_DHT
Expand All @@ -185,10 +186,23 @@ typedef struct {
} DHT;
/*----------------------------------------------------------------------------------*/

/* Shared key generations are costly, it is therefor smart to store commonly used
* ones so that they can re used later without being computed again.
*
* If shared key is already in shared_keys, copy it to shared_key.
* else generate it into shared_key and copy it to shared_keys
*/
void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, uint8_t *secret_key, uint8_t *client_id);

/* Copy shared_key to decrypt DHT packet from client_id into shared_key
* for packets that we recieve.
*/
void DHT_get_shared_key(DHT *dht, uint8_t *shared_key, uint8_t *client_id);
void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, uint8_t *client_id);

/* Copy shared_key to decrypt DHT packet from client_id into shared_key
* for packets that we send.
*/
void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, uint8_t *client_id);

void DHT_getnodes(DHT *dht, IP_Port *from_ipp, uint8_t *from_id, uint8_t *which_id);

Expand Down
24 changes: 12 additions & 12 deletions toxcore/onion.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ static int handle_send_initial(void *object, IP_Port source, uint8_t *packet, ui
change_symmetric_key(onion);

uint8_t plain[MAX_ONION_SIZE];

int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion->dht->self_secret_key, packet + 1,
packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), plain);
uint8_t shared_key[crypto_box_BEFORENMBYTES];
get_shared_key(&onion->shared_keys_1, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
int len = decrypt_data_fast(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), plain);

if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES))
return 1;
Expand Down Expand Up @@ -219,10 +219,10 @@ static int handle_send_1(void *object, IP_Port source, uint8_t *packet, uint32_t
change_symmetric_key(onion);

uint8_t plain[MAX_ONION_SIZE];

int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion->dht->self_secret_key, packet + 1,
packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1), plain);
uint8_t shared_key[crypto_box_BEFORENMBYTES];
get_shared_key(&onion->shared_keys_2, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
int len = decrypt_data_fast(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1), plain);

if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1 + crypto_box_MACBYTES))
return 1;
Expand Down Expand Up @@ -268,10 +268,10 @@ static int handle_send_2(void *object, IP_Port source, uint8_t *packet, uint32_t
change_symmetric_key(onion);

uint8_t plain[MAX_ONION_SIZE];

int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion->dht->self_secret_key, packet + 1,
packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2), plain);
uint8_t shared_key[crypto_box_BEFORENMBYTES];
get_shared_key(&onion->shared_keys_3, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
int len = decrypt_data_fast(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2), plain);

if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2 + crypto_box_MACBYTES))
return 1;
Expand Down
4 changes: 4 additions & 0 deletions toxcore/onion.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ typedef struct {
Networking_Core *net;
uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES];
uint64_t timestamp;

Shared_Keys shared_keys_1;
Shared_Keys shared_keys_2;
Shared_Keys shared_keys_3;
} Onion;

#define ONION_RETURN_1 (crypto_secretbox_NONCEBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES)
Expand Down
2 changes: 1 addition & 1 deletion toxcore/onion_announce.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet

uint8_t *packet_public_key = packet + 1 + crypto_box_NONCEBYTES;
uint8_t shared_key[crypto_box_BEFORENMBYTES];
encrypt_precompute(packet_public_key, onion_a->dht->self_secret_key, shared_key);
get_shared_key(&onion_a->shared_keys_recv, shared_key, onion_a->dht->self_secret_key, packet_public_key);

uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
int len = decrypt_data_fast(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
Expand Down
2 changes: 2 additions & 0 deletions toxcore/onion_announce.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ typedef struct {
Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES];
/* This is crypto_secretbox_KEYBYTES long just so we can use new_symmetric_key() to fill it */
uint8_t secret_bytes[crypto_secretbox_KEYBYTES];

Shared_Keys shared_keys_recv;
} Onion_Announce;

/* Create and send an onion announce request packet.
Expand Down
4 changes: 2 additions & 2 deletions toxcore/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
uint8_t shared_key[crypto_box_BEFORENMBYTES];

// generate key to encrypt ping_id with recipient privkey
encrypt_precompute(client_id, ping->dht->self_secret_key, shared_key);
DHT_get_shared_key_sent(ping->dht, shared_key, client_id);
// Generate random ping_id.
ping_id = add_ping(ping, ipp, shared_key);

Expand Down Expand Up @@ -218,7 +218,7 @@ static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint
uint8_t shared_key[crypto_box_BEFORENMBYTES];

// Decrypt ping_id
DHT_get_shared_key(dht, shared_key, packet + 1);
DHT_get_shared_key_recv(dht, shared_key, packet + 1);
rc = decrypt_data_fast(shared_key,
packet + 1 + CLIENT_ID_SIZE,
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
Expand Down

0 comments on commit 3bcc6e2

Please sign in to comment.