cargo fmt
This commit is contained in:
+61
-194
@@ -31,9 +31,7 @@ impl KeccakAead {
|
|||||||
CAPACITY_SIZE
|
CAPACITY_SIZE
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut input = Vec::with_capacity(
|
let mut input = Vec::with_capacity(iv.len() + key.len() + nonce.len());
|
||||||
iv.len() + key.len() + nonce.len(),
|
|
||||||
);
|
|
||||||
|
|
||||||
input.extend_from_slice(iv);
|
input.extend_from_slice(iv);
|
||||||
input.extend_from_slice(key);
|
input.extend_from_slice(key);
|
||||||
@@ -53,22 +51,17 @@ impl KeccakAead {
|
|||||||
|
|
||||||
/// Process associated data.
|
/// Process associated data.
|
||||||
/// Data is processed in 16-byte chunks.
|
/// Data is processed in 16-byte chunks.
|
||||||
pub fn associated_data_processing(
|
pub fn associated_data_processing(&mut self, associated_data: &[u8]) {
|
||||||
&mut self,
|
|
||||||
associated_data: &[u8],
|
|
||||||
) {
|
|
||||||
for chunk in associated_data.chunks(CHUNK_SIZE) {
|
for chunk in associated_data.chunks(CHUNK_SIZE) {
|
||||||
let mut input = [0u8; STATE_SIZE];
|
let mut input = [0u8; STATE_SIZE];
|
||||||
|
|
||||||
// r = chunk XOR state[0..16]
|
// r = chunk XOR state[0..16]
|
||||||
for i in 0..chunk.len() {
|
for i in 0..chunk.len() {
|
||||||
input[i] =
|
input[i] = chunk[i] ^ self.state[i];
|
||||||
chunk[i] ^ self.state[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// c = state[16..40]
|
// c = state[16..40]
|
||||||
input[RATE_SIZE..STATE_SIZE]
|
input[RATE_SIZE..STATE_SIZE].copy_from_slice(&self.state[RATE_SIZE..STATE_SIZE]);
|
||||||
.copy_from_slice(&self.state[RATE_SIZE..STATE_SIZE]);
|
|
||||||
|
|
||||||
self.state = shake256_state(&input);
|
self.state = shake256_state(&input);
|
||||||
}
|
}
|
||||||
@@ -78,12 +71,8 @@ impl KeccakAead {
|
|||||||
|
|
||||||
/// Encrypt plaintext.
|
/// Encrypt plaintext.
|
||||||
/// Returns the ciphertext split logically into 16-byte chunks, then concatenated
|
/// Returns the ciphertext split logically into 16-byte chunks, then concatenated
|
||||||
pub fn plaintext_processing(
|
pub fn plaintext_processing(&mut self, plaintext: &[u8]) -> Vec<u8> {
|
||||||
&mut self,
|
let mut ciphertext = Vec::with_capacity(plaintext.len());
|
||||||
plaintext: &[u8],
|
|
||||||
) -> Vec<u8> {
|
|
||||||
let mut ciphertext =
|
|
||||||
Vec::with_capacity(plaintext.len());
|
|
||||||
|
|
||||||
for chunk in plaintext.chunks(CHUNK_SIZE) {
|
for chunk in plaintext.chunks(CHUNK_SIZE) {
|
||||||
let mut input = [0u8; STATE_SIZE];
|
let mut input = [0u8; STATE_SIZE];
|
||||||
@@ -98,11 +87,9 @@ impl KeccakAead {
|
|||||||
// The rate portion must be the generated ciphertext.
|
// The rate portion must be the generated ciphertext.
|
||||||
let start = ciphertext.len() - chunk.len();
|
let start = ciphertext.len() - chunk.len();
|
||||||
|
|
||||||
input[..chunk.len()]
|
input[..chunk.len()].copy_from_slice(&ciphertext[start..]);
|
||||||
.copy_from_slice(&ciphertext[start..]);
|
|
||||||
|
|
||||||
input[RATE_SIZE..STATE_SIZE]
|
input[RATE_SIZE..STATE_SIZE].copy_from_slice(&self.state[RATE_SIZE..STATE_SIZE]);
|
||||||
.copy_from_slice(&self.state[RATE_SIZE..STATE_SIZE]);
|
|
||||||
|
|
||||||
self.state = shake256_state(&input);
|
self.state = shake256_state(&input);
|
||||||
}
|
}
|
||||||
@@ -111,12 +98,8 @@ impl KeccakAead {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypt ciphertext.
|
/// Decrypt ciphertext.
|
||||||
pub fn ciphertext_processing(
|
pub fn ciphertext_processing(&mut self, ciphertext: &[u8]) -> Vec<u8> {
|
||||||
&mut self,
|
let mut plaintext = Vec::with_capacity(ciphertext.len());
|
||||||
ciphertext: &[u8],
|
|
||||||
) -> Vec<u8> {
|
|
||||||
let mut plaintext =
|
|
||||||
Vec::with_capacity(ciphertext.len());
|
|
||||||
|
|
||||||
for chunk in ciphertext.chunks(CHUNK_SIZE) {
|
for chunk in ciphertext.chunks(CHUNK_SIZE) {
|
||||||
let mut input = [0u8; STATE_SIZE];
|
let mut input = [0u8; STATE_SIZE];
|
||||||
@@ -127,11 +110,9 @@ impl KeccakAead {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// input = ciphertext || c
|
// input = ciphertext || c
|
||||||
input[..chunk.len()]
|
input[..chunk.len()].copy_from_slice(chunk);
|
||||||
.copy_from_slice(chunk);
|
|
||||||
|
|
||||||
input[RATE_SIZE..STATE_SIZE]
|
input[RATE_SIZE..STATE_SIZE].copy_from_slice(&self.state[RATE_SIZE..STATE_SIZE]);
|
||||||
.copy_from_slice(&self.state[RATE_SIZE..STATE_SIZE]);
|
|
||||||
|
|
||||||
self.state = shake256_state(&input);
|
self.state = shake256_state(&input);
|
||||||
}
|
}
|
||||||
@@ -151,11 +132,9 @@ impl KeccakAead {
|
|||||||
// Construct padded key:
|
// Construct padded key:
|
||||||
let mut padded_key = [0u8; CAPACITY_SIZE];
|
let mut padded_key = [0u8; CAPACITY_SIZE];
|
||||||
|
|
||||||
let padding_len =
|
let padding_len = CAPACITY_SIZE - key.len();
|
||||||
CAPACITY_SIZE - key.len();
|
|
||||||
|
|
||||||
padded_key[padding_len..]
|
padded_key[padding_len..].copy_from_slice(key);
|
||||||
.copy_from_slice(key);
|
|
||||||
|
|
||||||
// XOR padded key into c.
|
// XOR padded key into c.
|
||||||
for i in 0..CAPACITY_SIZE {
|
for i in 0..CAPACITY_SIZE {
|
||||||
@@ -163,22 +142,14 @@ impl KeccakAead {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SHAKE256(state, 40)
|
// SHAKE256(state, 40)
|
||||||
let output = shake256(
|
let output = shake256(&self.state, STATE_SIZE);
|
||||||
&self.state,
|
|
||||||
STATE_SIZE,
|
|
||||||
);
|
|
||||||
|
|
||||||
let tag_start =
|
let tag_start = STATE_SIZE - key.len();
|
||||||
STATE_SIZE - key.len();
|
|
||||||
|
|
||||||
let mut tag =
|
let mut tag = Vec::with_capacity(key.len());
|
||||||
Vec::with_capacity(key.len());
|
|
||||||
|
|
||||||
for i in 0..key.len() {
|
for i in 0..key.len() {
|
||||||
tag.push(
|
tag.push(key[i] ^ output[tag_start + i]);
|
||||||
key[i]
|
|
||||||
^ output[tag_start + i],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tag
|
tag
|
||||||
@@ -197,23 +168,15 @@ impl KeccakAead {
|
|||||||
associated_data: &[u8],
|
associated_data: &[u8],
|
||||||
nonce: &[u8],
|
nonce: &[u8],
|
||||||
) -> EncryptionResult {
|
) -> EncryptionResult {
|
||||||
let mut sponge =
|
let mut sponge = Self::new(iv, key, nonce);
|
||||||
Self::new(iv, key, nonce);
|
|
||||||
|
|
||||||
sponge.associated_data_processing(
|
sponge.associated_data_processing(associated_data);
|
||||||
associated_data,
|
|
||||||
);
|
|
||||||
|
|
||||||
let cipher =
|
let cipher = sponge.plaintext_processing(plaintext);
|
||||||
sponge.plaintext_processing(plaintext);
|
|
||||||
|
|
||||||
let tag =
|
let tag = sponge.finalize(key);
|
||||||
sponge.finalize(key);
|
|
||||||
|
|
||||||
EncryptionResult {
|
EncryptionResult { cipher, tag }
|
||||||
cipher,
|
|
||||||
tag,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypt.
|
/// Decrypt.
|
||||||
@@ -224,36 +187,24 @@ impl KeccakAead {
|
|||||||
associated_data: &[u8],
|
associated_data: &[u8],
|
||||||
nonce: &[u8],
|
nonce: &[u8],
|
||||||
) -> DecryptionResult {
|
) -> DecryptionResult {
|
||||||
let mut sponge =
|
let mut sponge = Self::new(iv, key, nonce);
|
||||||
Self::new(iv, key, nonce);
|
|
||||||
|
|
||||||
sponge.associated_data_processing(
|
sponge.associated_data_processing(associated_data);
|
||||||
associated_data,
|
|
||||||
);
|
|
||||||
|
|
||||||
let plaintext =
|
let plaintext = sponge.ciphertext_processing(ciphertext);
|
||||||
sponge.ciphertext_processing(ciphertext);
|
|
||||||
|
|
||||||
let tag =
|
let tag = sponge.finalize(key);
|
||||||
sponge.finalize(key);
|
|
||||||
|
|
||||||
DecryptionResult {
|
DecryptionResult { plaintext, tag }
|
||||||
plaintext,
|
|
||||||
tag,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SHAKE256 wrapper returning exactly a 40-byte AEAD state.
|
/// SHAKE256 wrapper returning exactly a 40-byte AEAD state.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn shake256_state(
|
fn shake256_state(state: &[u8; STATE_SIZE]) -> [u8; STATE_SIZE] {
|
||||||
state: &[u8; STATE_SIZE],
|
let output = shake256(state, STATE_SIZE);
|
||||||
) -> [u8; STATE_SIZE] {
|
|
||||||
let output =
|
|
||||||
shake256(state, STATE_SIZE);
|
|
||||||
|
|
||||||
let mut result =
|
let mut result = [0u8; STATE_SIZE];
|
||||||
[0u8; STATE_SIZE];
|
|
||||||
|
|
||||||
result.copy_from_slice(&output);
|
result.copy_from_slice(&output);
|
||||||
|
|
||||||
@@ -270,37 +221,17 @@ mod tests {
|
|||||||
let iv = [0x11u8; 16];
|
let iv = [0x11u8; 16];
|
||||||
let nonce = [0x22u8; 16];
|
let nonce = [0x22u8; 16];
|
||||||
|
|
||||||
let associated_data =
|
let associated_data = b"associated data";
|
||||||
b"associated data";
|
|
||||||
|
|
||||||
let plaintext =
|
let plaintext = b"Hello, Keccak AEAD!";
|
||||||
b"Hello, Keccak AEAD!";
|
|
||||||
|
|
||||||
let encrypted = KeccakAead::encrypt(
|
let encrypted = KeccakAead::encrypt(&key, plaintext, &iv, associated_data, &nonce);
|
||||||
&key,
|
|
||||||
plaintext,
|
|
||||||
&iv,
|
|
||||||
associated_data,
|
|
||||||
&nonce,
|
|
||||||
);
|
|
||||||
|
|
||||||
let decrypted = KeccakAead::decrypt(
|
let decrypted = KeccakAead::decrypt(&key, &encrypted.cipher, &iv, associated_data, &nonce);
|
||||||
&key,
|
|
||||||
&encrypted.cipher,
|
|
||||||
&iv,
|
|
||||||
associated_data,
|
|
||||||
&nonce,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(decrypted.plaintext, plaintext);
|
||||||
decrypted.plaintext,
|
|
||||||
plaintext
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(decrypted.tag, encrypted.tag);
|
||||||
decrypted.tag,
|
|
||||||
encrypted.tag
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -309,13 +240,7 @@ mod tests {
|
|||||||
let iv = [0x11u8; 16];
|
let iv = [0x11u8; 16];
|
||||||
let nonce = [0x22u8; 16];
|
let nonce = [0x22u8; 16];
|
||||||
|
|
||||||
let result = KeccakAead::encrypt(
|
let result = KeccakAead::encrypt(&key, &[], &iv, b"test", &nonce);
|
||||||
&key,
|
|
||||||
&[],
|
|
||||||
&iv,
|
|
||||||
b"test",
|
|
||||||
&nonce,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(result.cipher.len(), 0);
|
assert_eq!(result.cipher.len(), 0);
|
||||||
assert_eq!(result.tag.len(), key.len());
|
assert_eq!(result.tag.len(), key.len());
|
||||||
@@ -327,35 +252,15 @@ mod tests {
|
|||||||
let iv = [0x11u8; 16];
|
let iv = [0x11u8; 16];
|
||||||
let nonce = [0x22u8; 16];
|
let nonce = [0x22u8; 16];
|
||||||
|
|
||||||
let plaintext =
|
let plaintext = b"test plaintext";
|
||||||
b"test plaintext";
|
|
||||||
|
|
||||||
let result = KeccakAead::encrypt(
|
let result = KeccakAead::encrypt(&key, plaintext, &iv, &[], &nonce);
|
||||||
&key,
|
|
||||||
plaintext,
|
|
||||||
&iv,
|
|
||||||
&[],
|
|
||||||
&nonce,
|
|
||||||
);
|
|
||||||
|
|
||||||
let decrypted =
|
let decrypted = KeccakAead::decrypt(&key, &result.cipher, &iv, &[], &nonce);
|
||||||
KeccakAead::decrypt(
|
|
||||||
&key,
|
|
||||||
&result.cipher,
|
|
||||||
&iv,
|
|
||||||
&[],
|
|
||||||
&nonce,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(decrypted.plaintext, plaintext);
|
||||||
decrypted.plaintext,
|
|
||||||
plaintext
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(decrypted.tag, result.tag);
|
||||||
decrypted.tag,
|
|
||||||
result.tag
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -365,44 +270,25 @@ mod tests {
|
|||||||
let nonce = [0x22u8; 16];
|
let nonce = [0x22u8; 16];
|
||||||
|
|
||||||
// > 16 bytes for multiple chunks.
|
// > 16 bytes for multiple chunks.
|
||||||
let plaintext =
|
let plaintext = b"0123456789abcdef0123456789abcdef0123";
|
||||||
b"0123456789abcdef0123456789abcdef0123";
|
|
||||||
|
|
||||||
let associated_data =
|
let associated_data = b"abcdefghijklmnopqrstuvwxyz";
|
||||||
b"abcdefghijklmnopqrstuvwxyz";
|
|
||||||
|
|
||||||
let encrypted =
|
let encrypted = KeccakAead::encrypt(&key, plaintext, &iv, associated_data, &nonce);
|
||||||
KeccakAead::encrypt(
|
|
||||||
&key,
|
|
||||||
plaintext,
|
|
||||||
&iv,
|
|
||||||
associated_data,
|
|
||||||
&nonce,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(encrypted.cipher.len(), plaintext.len());
|
||||||
encrypted.cipher.len(),
|
|
||||||
plaintext.len()
|
let decrypted = KeccakAead::decrypt(
|
||||||
|
&key,
|
||||||
|
&encrypted.cipher,
|
||||||
|
iv.as_slice(),
|
||||||
|
associated_data,
|
||||||
|
nonce.as_slice(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let decrypted =
|
assert_eq!(decrypted.plaintext, plaintext);
|
||||||
KeccakAead::decrypt(
|
|
||||||
&key,
|
|
||||||
&encrypted.cipher,
|
|
||||||
iv.as_slice(),
|
|
||||||
associated_data,
|
|
||||||
nonce.as_slice(),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(decrypted.tag, encrypted.tag);
|
||||||
decrypted.plaintext,
|
|
||||||
plaintext
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
decrypted.tag,
|
|
||||||
encrypted.tag
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -411,35 +297,16 @@ mod tests {
|
|||||||
let iv = [0x11u8; 16];
|
let iv = [0x11u8; 16];
|
||||||
let nonce = [0x22u8; 16];
|
let nonce = [0x22u8; 16];
|
||||||
|
|
||||||
let plaintext =
|
let plaintext = b"test plaintext";
|
||||||
b"test plaintext";
|
|
||||||
|
|
||||||
let encrypted =
|
let encrypted = KeccakAead::encrypt(&key, plaintext, &iv, b"ad", &nonce);
|
||||||
KeccakAead::encrypt(
|
|
||||||
&key,
|
|
||||||
plaintext,
|
|
||||||
&iv,
|
|
||||||
b"ad",
|
|
||||||
&nonce,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut modified =
|
let mut modified = encrypted.cipher.clone();
|
||||||
encrypted.cipher.clone();
|
|
||||||
|
|
||||||
modified[0] ^= 1;
|
modified[0] ^= 1;
|
||||||
|
|
||||||
let decrypted =
|
let decrypted = KeccakAead::decrypt(&key, &modified, &iv, b"ad", &nonce);
|
||||||
KeccakAead::decrypt(
|
|
||||||
&key,
|
|
||||||
&modified,
|
|
||||||
&iv,
|
|
||||||
b"ad",
|
|
||||||
&nonce,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_ne!(
|
assert_ne!(decrypted.tag, encrypted.tag);
|
||||||
decrypted.tag,
|
|
||||||
encrypted.tag
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user