CPU optimizations.

Use get_shared_key() in more places.
This commit is contained in:
irungentoo 2014-03-05 16:54:17 -05:00
parent 3a1f259cb9
commit 3bcc6e2ae5
7 changed files with 89 additions and 46 deletions

View File

@ -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;
}
}
@ -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.
@ -867,8 +888,9 @@ 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,
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,
@ -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,
@ -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,

View File

@ -146,7 +146,7 @@ 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];
@ -154,7 +154,7 @@ struct SHARED_KEYS {
uint8_t stored; /* 0 if not, 1 if is */
uint64_t time_last_requested;
} keys[256 * MAX_KEYS_PER_SLOT];
};
} Shared_Keys;
/*----------------------------------------------------------------------------------*/
@ -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
@ -185,10 +186,23 @@ typedef struct {
} DHT;
/*----------------------------------------------------------------------------------*/
/* 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);
/* 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);
/* 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);

View File

@ -173,9 +173,9 @@ 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,
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))
@ -219,9 +219,9 @@ 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,
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))
@ -268,9 +268,9 @@ 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,
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))

View File

@ -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)

View File

@ -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,

View File

@ -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.

View File

@ -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);
@ -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,