ascon: add Nonce type alias (#43)

Adds a type alias for Ascon nonces, set to `[u8; 16]`.

From the Ascon paper section 2.4:

https://link.springer.com/article/10.1007/s00145-021-09398-9

> The 320-bit initial state of Ascon is formed by the secret key K of
> k bits and nonce N of 128 bits
This commit is contained in:
Tony Arcieri 2023-02-25 19:23:59 -07:00 committed by GitHub
parent 37bc658306
commit 11cb7366da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 12 deletions

View File

@ -1,6 +1,6 @@
//! Authenticated Encryption with Associated Data.
use crate::{Ascon, Key, KEY_SIZE, RATE, S_SIZE};
use crate::{Ascon, Key, Nonce, KEY_SIZE, RATE, S_SIZE};
use alloc::{vec, vec::Vec};
/// Ascon(a,b) `b`-parameter.
@ -23,7 +23,7 @@ pub enum DecryptFail {
}
/// AEAD encryption.
pub fn encrypt(key: &Key, iv: &[u8], message: &[u8], aad: &[u8]) -> (Vec<u8>, Tag) {
pub fn encrypt(key: &Key, nonce: &Nonce, message: &[u8], aad: &[u8]) -> (Vec<u8>, Tag) {
let s = aad.len() / RATE + 1;
let t = message.len() / RATE + 1;
let l = message.len() % RATE;
@ -42,7 +42,7 @@ pub fn encrypt(key: &Key, iv: &[u8], message: &[u8], aad: &[u8]) -> (Vec<u8>, Ta
mm[message.len()] = 0x80;
// init
let mut ss = Ascon::new(key, iv);
let mut ss = Ascon::new(key, nonce);
// aad
if !aad.is_empty() {
@ -78,7 +78,7 @@ pub fn encrypt(key: &Key, iv: &[u8], message: &[u8], aad: &[u8]) -> (Vec<u8>, Ta
/// AEAD decryption.
pub fn decrypt(
key: &Key,
iv: &[u8],
nonce: &Nonce,
ciphertext: &[u8],
aad: &[u8],
tag: &[u8],
@ -99,7 +99,7 @@ pub fn decrypt(
aa[aad.len()] = 0x80;
// init
let mut ss = Ascon::new(key, iv);
let mut ss = Ascon::new(key, nonce);
// aad
if !aad.is_empty() {

View File

@ -25,6 +25,9 @@ use core::convert::TryInto;
/// Size of an Ascon key in bytes.
const KEY_SIZE: usize = 16;
/// Size of an Ascon nonce in bytes.
const NONCE_SIZE: usize = 16;
/// State size in bits.
const S_BITS: usize = 320;
@ -37,6 +40,9 @@ const RATE: usize = 128 / 8;
/// Ascon permutation key.
pub type Key = [u8; KEY_SIZE];
/// Ascon nonce.
pub type Nonce = [u8; NONCE_SIZE];
/// Ascon permutation state.
type State = [u8; S_SIZE];
@ -48,23 +54,22 @@ pub struct Ascon<const A: usize = 12, const B: usize = 8> {
impl<const A: usize, const B: usize> Ascon<A, B> {
/// Initialize Ascon permutation.
// TODO(tarcieri): validate length of key and nonce
pub fn new(key: &Key, nonce: &[u8]) -> Self {
pub fn new(key: &Key, nonce: &Nonce) -> Self {
let mut state = [0; S_SIZE];
state[0] = KEY_SIZE as u8 * 8;
state[1] = RATE as u8 * 8;
state[2] = A as u8;
state[3] = B as u8;
let mut pos = S_SIZE - 2 * KEY_SIZE;
state[pos..pos + key.len()].copy_from_slice(key);
pos += KEY_SIZE;
state[pos..pos + nonce.len()].copy_from_slice(nonce);
let pos = S_SIZE - KEY_SIZE - NONCE_SIZE;
let (k, n) = state[pos..].split_at_mut(KEY_SIZE);
k.copy_from_slice(key);
n.copy_from_slice(nonce);
permutation(&mut state, 12 - A, A);
for (i, &b) in key.iter().enumerate() {
state[pos + i] ^= b;
state[pos + KEY_SIZE + i] ^= b;
}
Self { key: *key, state }