Module proj_crypto::symmetric [] [src]

Symmetric encryption module.

This module provides an interface for symmetric (secret key) cryptography.

Cryptography

Ratcheting

For the n'th message, the keys are hashed n times. The nonce is also hashed. In a system which does not allow for message loss and re-ordering, this provides forward secrecy for the symmetric keys as each key can be destroyed immediately after use. SHA-256 is used because this matches the key length of chacha20.

Secure Channel

Authenticates first with HMAC-SHA512 (only the first 256 bytes are used). This was chosen as it is the default authentication mechanism in sodiumoxide. Then we encrypt using ChaCha20. ChaCha20 was chosen over the sodiumoxide default (xsalsa20) because I will not be using a random nonse and chacha is more resistant to crypt analysis (see it's introductory paper). The key is used from the ratcheting system.

Example (Encrypted Authentication)

use sodiumoxide::randombytes;
use std::str;
 
sodiumoxide::init();
let message = "hello world!";
let k_e = &randombytes::randombytes(32);
let k_a = &randombytes::randombytes(32);
let message_number: u16 = 0;

let mut state = State::new(k_e, k_a);
let ciphertext = state.authenticated_encryption(message.as_bytes(), message_number);
let plaintext = state.authenticated_decryption(&ciphertext, message_number).unwrap();

assert_eq!(message, str::from_utf8(&plaintext).unwrap());

// some stuff happens. Now we no-longer need keys for messages numbered less than 8

state.increase_iter_to(8);

// crypto still works for message numbers starting from 8:
let ciphertext8 = state.authenticated_encryption(message.as_bytes(), 8);
let plaintext8 = state.authenticated_decryption(&ciphertext8, 8).unwrap();

assert_eq!(message, str::from_utf8(&plaintext8).unwrap());

Example (Plain Authentication)

use sodiumoxide::randombytes;
use std::str;
 
sodiumoxide::init();
let message = "hello world!".as_bytes();
let k_e = &randombytes::randombytes(32);
let k_a = &randombytes::randombytes(32);
let message_number: u16 = 0;

let mut state = State::new(k_e, k_a);
let state = State::new(k_e, k_a);
let auth_tag = state.plain_auth_tag(message, message_number);

assert!( state.verify_auth_tag(&auth_tag, message, message_number) );

Structs

Digest

A wrapper around sha256::Digest so that we can implement Drop on it to clean up the memory when it goes out of scope. This is necessary because often our shared secret keys are sha256 digests.

State

Stores the state of the symmetric encryption system. Memory is zeroed when this goes out of scope

Constants

AUTH_TAG_BYTES

The length of an authentication tag in bytes