mirror of
https://github.com/logos-blockchain/sponges.git
synced 2026-07-30 02:23:31 +00:00
ascon: 2018 edition upgrade, lints, docs (#34)
- Bumps the crate's edition to 2018, which is MSRV-compatible - Adds a more expansive set of lints - Adds the `missing_docs` lint, and adds docs where missing
This commit is contained in:
parent
5831f8bd51
commit
2e113f5f96
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -4,7 +4,7 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ascon"
|
||||
version = "0.1.4"
|
||||
version = "0.2.0-pre"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
@ -1,10 +1,18 @@
|
||||
[package]
|
||||
name = "ascon"
|
||||
version = "0.1.4"
|
||||
authors = ["quininer kel <quininer@live.com>"]
|
||||
description = "A implementation of ASCON authenticated encryption."
|
||||
repository = "https://github.com/quininer/ascon"
|
||||
version = "0.2.0-pre"
|
||||
description = """
|
||||
Pure Rust implementation of Ascon, a family of authenticated encryption and
|
||||
hashing algorithms designed to be lightweight and easy to implement
|
||||
"""
|
||||
authors = ["quininer kel <quininer@live.com>", "RustCrypto Developers"]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
documentation = "https://docs.rs/ascon"
|
||||
repository = "https://github.com/RustCrypto/sponges/tree/master/ascon"
|
||||
keywords = ["crypto", "sponge"]
|
||||
categories = ["cryptography", "no-std"]
|
||||
readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
byteorder = { version = "1.0", default-features = false }
|
||||
|
||||
@ -64,6 +64,7 @@ dual licensed as above, without any additional terms or conditions.
|
||||
[//]: # (links)
|
||||
|
||||
[RustCrypto]: https://github.com/rustcrypto
|
||||
[Ascon]: https://ascon.iaik.tugraz.at/
|
||||
[New standard for lightweight cryptography]: https://www.nist.gov/news-events/news/2023/02/nist-selects-lightweight-cryptography-algorithms-protect-small-devices
|
||||
[NIST Lightweight Cryptography]: https://csrc.nist.gov/projects/lightweight-cryptography/finalists
|
||||
[CAESAR competition]: https://competitions.cr.yp.to/caesar-submissions.html
|
||||
|
||||
111
ascon/src/lib.rs
111
ascon/src/lib.rs
@ -1,9 +1,42 @@
|
||||
extern crate byteorder;
|
||||
//! Pure Rust implementation of [Ascon], a family of authenticated encryption and
|
||||
//! hashing algorithms designed to be lightweight and easy to implement.
|
||||
//!
|
||||
//! ## About
|
||||
//!
|
||||
//! Ascon is a family of lightweight algorithms built on a core permutation
|
||||
//! algorithm. These algorithms include:
|
||||
//!
|
||||
//! - Authenticated Encryption with Associated Data (AEAD)
|
||||
//! - Hash functions (HASH) and extendible-output functions (XOF)
|
||||
//! - Pseudo-random functions (PRF) and message authentication codes (MAC)
|
||||
//!
|
||||
//! Ascon has been selected as [new standard for lightweight cryptography] in the
|
||||
//! [NIST Lightweight Cryptography] competition, and has also been selected as the
|
||||
//! primary choice for lightweight authenticated encryption in the final
|
||||
//! portfolio of the [CAESAR competition].
|
||||
//!
|
||||
//! [Ascon]: https://ascon.iaik.tugraz.at/
|
||||
//! [New standard for lightweight cryptography]: https://www.nist.gov/news-events/news/2023/02/nist-selects-lightweight-cryptography-algorithms-protect-small-devices
|
||||
//! [NIST Lightweight Cryptography]: https://csrc.nist.gov/projects/lightweight-cryptography/finalists
|
||||
//! [CAESAR competition]: https://competitions.cr.yp.to/caesar-submissions.html
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
|
||||
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
|
||||
)]
|
||||
#![warn(
|
||||
clippy::mod_module_files,
|
||||
clippy::unwrap_used,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unused_lifetimes,
|
||||
unused_qualifications
|
||||
)]
|
||||
|
||||
mod ops;
|
||||
mod util;
|
||||
|
||||
use ops::{finalization, initialization, permutation, process_aad};
|
||||
use crate::ops::{finalization, initialization, permutation, process_aad};
|
||||
|
||||
const KEY_LEN: usize = 16;
|
||||
const S_SIZE: usize = 320 / 8;
|
||||
@ -11,12 +44,17 @@ const RATE: usize = 128 / 8;
|
||||
const A: usize = 12;
|
||||
const B: usize = 8;
|
||||
|
||||
/// Decryption errors.
|
||||
#[derive(Debug)]
|
||||
pub enum DecryptFail {
|
||||
/// Invalid tag length.
|
||||
TagLengthError,
|
||||
|
||||
/// Authentication failure (invalid tag).
|
||||
AuthenticationFail,
|
||||
}
|
||||
|
||||
/// AEAD encryption.
|
||||
pub fn aead_encrypt(key: &[u8], iv: &[u8], message: &[u8], aad: &[u8]) -> (Vec<u8>, [u8; KEY_LEN]) {
|
||||
let s = aad.len() / RATE + 1;
|
||||
let t = message.len() / RATE + 1;
|
||||
@ -69,6 +107,7 @@ pub fn aead_encrypt(key: &[u8], iv: &[u8], message: &[u8], aad: &[u8]) -> (Vec<u
|
||||
(output, tag)
|
||||
}
|
||||
|
||||
/// AEAD decryption.
|
||||
pub fn aead_decrypt(
|
||||
key: &[u8],
|
||||
iv: &[u8],
|
||||
@ -127,36 +166,42 @@ pub fn aead_decrypt(
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ascon_test() {
|
||||
let key = [0; 16];
|
||||
let iv = [0; 16];
|
||||
let aad = [0; 16];
|
||||
let message = [0; 64];
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{aead_decrypt, aead_encrypt};
|
||||
use crate::util;
|
||||
|
||||
let (ciphertext, tag) = aead_encrypt(&key, &iv, &message, &aad);
|
||||
let plaintext = aead_decrypt(&key, &iv, &ciphertext, &aad, &tag).unwrap();
|
||||
assert_eq!(plaintext, &message[..]);
|
||||
assert!(util::eq(&message, &plaintext));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ascon_tv_test() {
|
||||
let key = [0; 16];
|
||||
let iv = [0; 16];
|
||||
let aad = b"ASCON";
|
||||
let message = b"ascon";
|
||||
|
||||
let (ciphertext, tag) = aead_encrypt(&key, &iv, message, aad);
|
||||
assert_eq!(ciphertext, [0x4c, 0x8c, 0x42, 0x89, 0x49]);
|
||||
assert_eq!(
|
||||
tag,
|
||||
[
|
||||
0x65, 0xfd, 0x17, 0xb6, 0xd3, 0x0c, 0xd8, 0x76, 0xa0, 0x5a, 0x8e, 0xfc, 0xec, 0xad,
|
||||
0x99, 0x3a
|
||||
]
|
||||
);
|
||||
|
||||
let plaintext = aead_decrypt(&key, &iv, &ciphertext, aad, &tag).unwrap();
|
||||
assert_eq!(plaintext, message);
|
||||
#[test]
|
||||
fn ascon_test() {
|
||||
let key = [0; 16];
|
||||
let iv = [0; 16];
|
||||
let aad = [0; 16];
|
||||
let message = [0; 64];
|
||||
|
||||
let (ciphertext, tag) = aead_encrypt(&key, &iv, &message, &aad);
|
||||
let plaintext = aead_decrypt(&key, &iv, &ciphertext, &aad, &tag).unwrap();
|
||||
assert_eq!(plaintext, &message[..]);
|
||||
assert!(util::eq(&message, &plaintext));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ascon_tv_test() {
|
||||
let key = [0; 16];
|
||||
let iv = [0; 16];
|
||||
let aad = b"ASCON";
|
||||
let message = b"ascon";
|
||||
|
||||
let (ciphertext, tag) = aead_encrypt(&key, &iv, message, aad);
|
||||
assert_eq!(ciphertext, [0x4c, 0x8c, 0x42, 0x89, 0x49]);
|
||||
assert_eq!(
|
||||
tag,
|
||||
[
|
||||
0x65, 0xfd, 0x17, 0xb6, 0xd3, 0x0c, 0xd8, 0x76, 0xa0, 0x5a, 0x8e, 0xfc, 0xec, 0xad,
|
||||
0x99, 0x3a
|
||||
]
|
||||
);
|
||||
|
||||
let plaintext = aead_decrypt(&key, &iv, &ciphertext, aad, &tag).unwrap();
|
||||
assert_eq!(plaintext, message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
use util::{u64_to_u8, u8_to_u64};
|
||||
use crate::{
|
||||
util::{u64_to_u8, u8_to_u64},
|
||||
A, B, KEY_LEN, RATE, S_SIZE,
|
||||
};
|
||||
|
||||
pub fn permutation(s: &mut [u8], start: usize, rounds: usize) {
|
||||
let mut x = [0; 5];
|
||||
@ -47,17 +50,17 @@ pub fn permutation(s: &mut [u8], start: usize, rounds: usize) {
|
||||
}
|
||||
|
||||
pub fn initialization(s: &mut [u8], key: &[u8], nonce: &[u8]) {
|
||||
s[0] = ::KEY_LEN as u8 * 8;
|
||||
s[1] = ::RATE as u8 * 8;
|
||||
s[2] = ::A as u8;
|
||||
s[3] = ::B as u8;
|
||||
s[0] = KEY_LEN as u8 * 8;
|
||||
s[1] = RATE as u8 * 8;
|
||||
s[2] = A as u8;
|
||||
s[3] = B as u8;
|
||||
|
||||
let mut pos = ::S_SIZE - 2 * ::KEY_LEN;
|
||||
let mut pos = S_SIZE - 2 * KEY_LEN;
|
||||
s[pos..pos + key.len()].copy_from_slice(key);
|
||||
pos += ::KEY_LEN;
|
||||
pos += KEY_LEN;
|
||||
s[pos..pos + nonce.len()].copy_from_slice(nonce);
|
||||
|
||||
permutation(s, 12 - ::A, ::A);
|
||||
permutation(s, 12 - A, A);
|
||||
|
||||
for (i, &b) in key.iter().enumerate() {
|
||||
s[pos + i] ^= b;
|
||||
@ -66,19 +69,19 @@ pub fn initialization(s: &mut [u8], key: &[u8], nonce: &[u8]) {
|
||||
|
||||
pub fn finalization(s: &mut [u8], key: &[u8]) {
|
||||
for (i, &b) in key.iter().enumerate() {
|
||||
s[::RATE + i] ^= b;
|
||||
s[RATE + i] ^= b;
|
||||
}
|
||||
permutation(s, 12 - ::A, ::A);
|
||||
permutation(s, 12 - A, A);
|
||||
for (i, &b) in key.iter().enumerate() {
|
||||
s[::S_SIZE - ::KEY_LEN + i] ^= b;
|
||||
s[S_SIZE - KEY_LEN + i] ^= b;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_aad(ss: &mut [u8], aa: &[u8], s: usize) {
|
||||
for i in 0..s {
|
||||
for j in 0..::RATE {
|
||||
ss[j] ^= aa[i * ::RATE + j];
|
||||
for j in 0..RATE {
|
||||
ss[j] ^= aa[i * RATE + j];
|
||||
}
|
||||
permutation(ss, 12 - ::B, ::B);
|
||||
permutation(ss, 12 - B, B);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user