From 877609ecbb1271bcc2d984a503a965ba0c5efd49 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 26 Aug 2023 23:46:30 +0800 Subject: [PATCH] feat: dec not works --- src/decryptor.rs | 151 ++++++++++++++++++++++++++++++++ src/encryptor.rs | 144 +++++++++++++++++++++++++++++++ src/lib.rs | 218 ++--------------------------------------------- src/main.rs | 23 +++-- src/util.rs | 72 ++++++++++++++++ 5 files changed, 387 insertions(+), 221 deletions(-) create mode 100644 src/decryptor.rs create mode 100644 src/encryptor.rs create mode 100644 src/util.rs diff --git a/src/decryptor.rs b/src/decryptor.rs new file mode 100644 index 0000000..d5ef603 --- /dev/null +++ b/src/decryptor.rs @@ -0,0 +1,151 @@ +use aes::Aes128; +use aes::cipher::{Block, BlockEncrypt, KeyInit}; +use aes::cipher::generic_array::GenericArray; + +use crate::util::{gmul_128, inc_32, msb_s, normalize_nonce, u8to128}; + +pub struct Aes128GcmStreamDecryptor { + crypto: Aes128, + message_buffer: Vec, + integrality_buffer: Vec, + ghash_key: u128, + ghash_val: u128, + init_nonce: u128, + encryption_nonce: u128, + adata_len: usize, + message_len: usize, +} + +impl Aes128GcmStreamDecryptor { + pub fn new(key: [u8; 16]) -> Self { + let key = GenericArray::from(key); + let aes = Aes128::new(&key); + + Self { + crypto: aes, + message_buffer: vec![], + integrality_buffer: vec![], + ghash_key: 0, + ghash_val: 0, + init_nonce: 0, + encryption_nonce: 0, + adata_len: 0, + message_len: 0, + } + } + + pub fn init_nonce(&mut self, nonce: &[u8]) { + let (ghash_key, normalized_nonce) = self.normalize_nonce(nonce); + self.ghash_key = ghash_key; + self.init_nonce = normalized_nonce; + self.encryption_nonce = normalized_nonce; + } + + pub fn init_adata(&mut self, adata: &[u8]) { + self.integrality_buffer.extend_from_slice(adata); + self.adata_len += adata.len(); + + let adata_bit_len = self.adata_len * 8; + let v = 128 * ((adata_bit_len + 128 - 1) / 128) - adata_bit_len; + self.integrality_buffer.extend_from_slice(&vec![0x00; v / 8]); + } + + pub fn next(&mut self, bytes: &[u8]) -> Vec { + self.message_buffer.extend_from_slice(bytes); + let message_buffer_slice = self.message_buffer.as_slice(); + let message_buffer_len = message_buffer_slice.len(); + if message_buffer_len < 32 { + return vec![]; + } + let blocks_count = (message_buffer_len / 16) - 1; + let mut plaintext_message = Vec::with_capacity(blocks_count * 16); + for i in 0..blocks_count { + self.encryption_nonce = inc_32(self.encryption_nonce); + let mut ctr = self.encryption_nonce.to_be_bytes(); + let block = Block::::from_mut_slice(&mut ctr); + self.crypto.encrypt_block(block); + let chunk = &message_buffer_slice[i * 16..(i + 1) * 16]; + let y = u8to128(chunk) ^ u8to128(&block.as_slice()); + plaintext_message.extend_from_slice(&y.to_be_bytes()); + } + self.integrality_buffer.extend_from_slice(&message_buffer_slice[0..blocks_count * 16]); + self.message_buffer = message_buffer_slice[blocks_count * 16..].to_vec(); + self.message_len += plaintext_message.len(); + + self.update_integrality_buffer(); + + plaintext_message + } + + pub fn finalize(&mut self) -> Result, String> { + let mut plaintext_message = vec![]; + let message_buffer_len = self.message_buffer.len(); + if message_buffer_len > 16 { + // last block and this block len is less than 128 bits + self.encryption_nonce = inc_32(self.encryption_nonce); + let mut ctr = self.encryption_nonce.to_be_bytes(); + let block = Block::::from_mut_slice(&mut ctr); + self.crypto.encrypt_block(block); + + let chunk = &self.message_buffer[0..message_buffer_len - 16]; + let msb = msb_s(chunk.len() * 8, block.as_slice()); + let y = u8to128(chunk) ^ u8to128(&msb); + plaintext_message.extend_from_slice(&y.to_be_bytes()[16 - chunk.len()..16]); + self.integrality_buffer.extend_from_slice(&self.message_buffer[0..message_buffer_len - 16]); + self.message_len += plaintext_message.len(); + } + let adata_bit_len = self.adata_len * 8; + let message_bit_len = self.message_len * 8; + let u = 128 * ((message_bit_len + 128 - 1) / 128) - message_bit_len; + self.integrality_buffer.extend_from_slice(&vec![0x00; u / 8]); + self.integrality_buffer.extend_from_slice(&(adata_bit_len as u64).to_be_bytes()); + self.integrality_buffer.extend_from_slice(&(message_bit_len as u64).to_be_bytes()); + + self.update_integrality_buffer(); + assert!(self.integrality_buffer.is_empty()); + + let tag = self.calculate_tag(); + let message_tag = &self.message_buffer[message_buffer_len - 16..]; + + if message_tag != tag.as_slice() { + Err(format!("Tag mismatch, expected: {}, actual: {}", + hex::encode(&tag), hex::encode(message_tag))) + } else { + Ok(plaintext_message) + } + } + + fn calculate_tag(&mut self) -> Vec { + let mut bs = self.init_nonce.to_be_bytes().clone(); + let block = Block::::from_mut_slice(&mut bs); + self.crypto.encrypt_block(block); + let tag_trunk = self.ghash_val.to_be_bytes(); + let y = u8to128(&tag_trunk) ^ u8to128(&block.as_slice()); + y.to_be_bytes().to_vec() + } + + fn update_integrality_buffer(&mut self) { + let integrality_buffer_slice = self.integrality_buffer.as_slice(); + let integrality_buffer_slice_len = integrality_buffer_slice.len(); + if integrality_buffer_slice_len >= 16 { + let blocks_count = integrality_buffer_slice_len / 16; + for i in 0..blocks_count { + let buf = &integrality_buffer_slice[i * 16..(i + 1) * 16]; + self.ghash_val = gmul_128(self.ghash_val ^ u8to128(buf), self.ghash_key) + } + self.integrality_buffer = integrality_buffer_slice[blocks_count * 16..].to_vec(); + } + } + + fn ghash_key(&mut self) -> u128 { + let mut block = [0u8; 16]; + let block = Block::::from_mut_slice(&mut block); + self.crypto.encrypt_block(block); + u8to128(&block.as_slice()) + } + + fn normalize_nonce(&mut self, nonce_bytes: &[u8]) -> (u128, u128) { + let ghash_key = self.ghash_key(); + normalize_nonce(ghash_key, nonce_bytes) + } +} \ No newline at end of file diff --git a/src/encryptor.rs b/src/encryptor.rs new file mode 100644 index 0000000..5d1a1cd --- /dev/null +++ b/src/encryptor.rs @@ -0,0 +1,144 @@ +use aes::Aes128; +use aes::cipher::{Block, BlockEncrypt, KeyInit}; +use aes::cipher::generic_array::GenericArray; + +use crate::util::{gmul_128, inc_32, msb_s, normalize_nonce, u8to128}; + +pub struct Aes128GcmStreamEncryptor { + crypto: Aes128, + message_buffer: Vec, + integrality_buffer: Vec, + ghash_key: u128, + ghash_val: u128, + init_nonce: u128, + encryption_nonce: u128, + adata_len: usize, + message_len: usize, +} + +impl Aes128GcmStreamEncryptor { + pub fn new(key: [u8; 16]) -> Self { + let key = GenericArray::from(key); + let aes = Aes128::new(&key); + + Self { + crypto: aes, + message_buffer: vec![], + integrality_buffer: vec![], + ghash_key: 0, + ghash_val: 0, + init_nonce: 0, + encryption_nonce: 0, + adata_len: 0, + message_len: 0, + } + } + + pub fn init_nonce(&mut self, nonce: &[u8]) { + let (ghash_key, normalized_nonce) = self.normalize_nonce(nonce); + self.ghash_key = ghash_key; + self.init_nonce = normalized_nonce; + self.encryption_nonce = normalized_nonce; + } + + pub fn init_adata(&mut self, adata: &[u8]) { + self.integrality_buffer.extend_from_slice(adata); + self.adata_len += adata.len(); + + let adata_bit_len = self.adata_len * 8; + let v = 128 * ((adata_bit_len + 128 - 1) / 128) - adata_bit_len; + self.integrality_buffer.extend_from_slice(&vec![0x00; v / 8]); + } + + pub fn next(&mut self, bytes: &[u8]) -> Vec { + self.message_buffer.extend_from_slice(bytes); + let message_buffer_slice = self.message_buffer.as_slice(); + let message_buffer_len = message_buffer_slice.len(); + if message_buffer_len < 16 { + return vec![]; + } + let blocks_count = message_buffer_len / 16; + let mut encrypted_message = Vec::with_capacity(blocks_count * 16); + for i in 0..blocks_count { + self.encryption_nonce = inc_32(self.encryption_nonce); + let mut ctr = self.encryption_nonce.to_be_bytes(); + let block = Block::::from_mut_slice(&mut ctr); + self.crypto.encrypt_block(block); + let chunk = &message_buffer_slice[i * 16..(i + 1) * 16]; + let y = u8to128(chunk) ^ u8to128(&block.as_slice()); + encrypted_message.extend_from_slice(&y.to_be_bytes()); + } + self.message_buffer = message_buffer_slice[blocks_count * 16..].to_vec(); + self.integrality_buffer.extend_from_slice(&encrypted_message); + self.message_len += encrypted_message.len(); + + self.update_integrality_buffer(); + + encrypted_message + } + + pub fn finalize(&mut self) -> (Vec, Vec) { + let mut encrypted_message = vec![]; + if !self.message_buffer.is_empty() { + // last block and this block len is less than 128 bits + self.encryption_nonce = inc_32(self.encryption_nonce); + let mut ctr = self.encryption_nonce.to_be_bytes(); + let block = Block::::from_mut_slice(&mut ctr); + self.crypto.encrypt_block(block); + + let chunk = self.message_buffer.as_slice(); + let msb = msb_s(chunk.len() * 8, block.as_slice()); + let y = u8to128(chunk) ^ u8to128(&msb); + encrypted_message.extend_from_slice(&y.to_be_bytes()[16 - chunk.len()..16]); + self.integrality_buffer.extend_from_slice(&encrypted_message); + self.message_len += encrypted_message.len(); + } + let adata_bit_len = self.adata_len * 8; + let message_bit_len = self.message_len * 8; + let u = 128 * ((message_bit_len + 128 - 1) / 128) - message_bit_len; + self.integrality_buffer.extend_from_slice(&vec![0x00; u / 8]); + self.integrality_buffer.extend_from_slice(&(adata_bit_len as u64).to_be_bytes()); + self.integrality_buffer.extend_from_slice(&(message_bit_len as u64).to_be_bytes()); + + self.update_integrality_buffer(); + assert!(self.integrality_buffer.is_empty()); + + let tag = self.calculate_tag(); + + (encrypted_message, tag) + } + + fn calculate_tag(&mut self) -> Vec { + let mut bs = self.init_nonce.to_be_bytes().clone(); + let block = Block::::from_mut_slice(&mut bs); + self.crypto.encrypt_block(block); + let tag_trunk = self.ghash_val.to_be_bytes(); + let y = u8to128(&tag_trunk) ^ u8to128(&block.as_slice()); + y.to_be_bytes().to_vec() + } + + fn update_integrality_buffer(&mut self) { + let integrality_buffer_slice = self.integrality_buffer.as_slice(); + let integrality_buffer_slice_len = integrality_buffer_slice.len(); + if integrality_buffer_slice_len >= 16 { + let blocks_count = integrality_buffer_slice_len / 16; + for i in 0..blocks_count { + let buf = &integrality_buffer_slice[i * 16..(i + 1) * 16]; + self.ghash_val = gmul_128(self.ghash_val ^ u8to128(buf), self.ghash_key) + } + self.integrality_buffer = integrality_buffer_slice[blocks_count * 16..].to_vec(); + } + } + + fn ghash_key(&mut self) -> u128 { + let mut block = [0u8; 16]; + let block = Block::::from_mut_slice(&mut block); + self.crypto.encrypt_block(block); + u8to128(&block.as_slice()) + } + + fn normalize_nonce(&mut self, nonce_bytes: &[u8]) -> (u128, u128) { + let ghash_key = self.ghash_key(); + normalize_nonce(ghash_key, nonce_bytes) + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 1216cc7..433b2bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,215 +1,7 @@ -use aes::Aes128; -use aes::cipher::{Block, BlockEncrypt, KeyInit}; -use aes::cipher::generic_array::GenericArray; +pub use encryptor::Aes128GcmStreamEncryptor; +pub use decryptor::Aes128GcmStreamDecryptor; -pub struct Aes128GcmStreamEncryptor { - crypto: Aes128, - message_buffer: Vec, - integrality_buffer: Vec, - ghash_key: u128, - ghash_val: u128, - init_nonce: u128, - encryption_nonce: u128, - adata_len: usize, - message_len: usize, -} +mod util; +mod encryptor; +mod decryptor; -impl Aes128GcmStreamEncryptor { - pub fn new(key: [u8; 16]) -> Self { - let key = GenericArray::from(key); - let aes = Aes128::new(&key); - - Self { - crypto: aes, - message_buffer: vec![], - integrality_buffer: vec![], - ghash_key: 0, - ghash_val: 0, - init_nonce: 0, - encryption_nonce: 0, - adata_len: 0, - message_len: 0, - } - } - - pub fn init_nonce(&mut self, nonce: &[u8]) { - let (ghash_key, normalized_nonce) = self.normalize_nonce(nonce); - self.ghash_key = ghash_key; - self.init_nonce = normalized_nonce; - self.encryption_nonce = normalized_nonce; - } - - pub fn init_adata(&mut self, adata: &[u8]) { - self.integrality_buffer.extend_from_slice(adata); - self.adata_len += adata.len(); - - let adata_bit_len = self.adata_len * 8; - let v = 128 * ((adata_bit_len + 128 - 1) / 128) - adata_bit_len; - self.integrality_buffer.extend_from_slice(&vec![0x00; v / 8]); - } - - pub fn next(&mut self, bytes: &[u8]) -> Vec { - self.message_buffer.extend_from_slice(bytes); - let message_buffer_slice = self.message_buffer.as_slice(); - let message_buffer_len = message_buffer_slice.len(); - if message_buffer_len < 16 { - return vec![]; - } - let blocks_count = message_buffer_len / 16; - let mut encrypted_message = vec![]; - for i in 0..blocks_count { - self.encryption_nonce = inc_32(self.encryption_nonce); - let mut ctr = self.encryption_nonce.to_be_bytes(); - let block = Block::::from_mut_slice(&mut ctr); - self.crypto.encrypt_block(block); - let chunk = &message_buffer_slice[i * 16..(i + 1) * 16]; - let y = u8to128(chunk) ^ u8to128(&block.as_slice()); - encrypted_message.extend_from_slice(&y.to_be_bytes()); - } - self.message_buffer = message_buffer_slice[blocks_count * 16..].to_vec(); - self.integrality_buffer.extend_from_slice(&encrypted_message); - self.message_len += encrypted_message.len(); - - self.update_integrality_buffer(); - - encrypted_message - } - - pub fn finalize(&mut self) -> (Vec, Vec) { - let mut encrypted_message = vec![]; - if !self.message_buffer.is_empty() { - // last block and this block len is less than 128 bits - self.encryption_nonce = inc_32(self.encryption_nonce); - let mut ctr = self.encryption_nonce.to_be_bytes(); - let block = Block::::from_mut_slice(&mut ctr); - self.crypto.encrypt_block(block); - - let chunk = self.message_buffer.as_slice(); - let msb = msb_s(chunk.len() * 8, block.as_slice()); - let y = u8to128(chunk) ^ u8to128(&msb); - encrypted_message.extend_from_slice(&y.to_be_bytes()[16 - chunk.len()..16]); - self.integrality_buffer.extend_from_slice(&encrypted_message); - self.message_len += encrypted_message.len(); - } - let adata_bit_len = self.adata_len * 8; - let message_bit_len = self.message_len * 8; - let u = 128 * ((message_bit_len + 128 - 1) / 128) - message_bit_len; - self.integrality_buffer.extend_from_slice(&vec![0x00; u / 8]); - self.integrality_buffer.extend_from_slice(&(adata_bit_len as u64).to_be_bytes()); - self.integrality_buffer.extend_from_slice(&(message_bit_len as u64).to_be_bytes()); - - self.update_integrality_buffer(); - assert!(self.integrality_buffer.is_empty()); - - let tag = self.calculate_tag(); - - (encrypted_message, tag) - } - - fn calculate_tag(&mut self) -> Vec { - let mut bs = self.init_nonce.to_be_bytes().clone(); - let block = Block::::from_mut_slice(&mut bs); - self.crypto.encrypt_block(block); - let tag_trunk = self.ghash_val.to_be_bytes(); - let y = u8to128(&tag_trunk) ^ u8to128(&block.as_slice()); - y.to_be_bytes().to_vec() - } - - fn update_integrality_buffer(&mut self) { - let integrality_buffer_slice = self.integrality_buffer.as_slice(); - let integrality_buffer_slice_len = integrality_buffer_slice.len(); - if integrality_buffer_slice_len >= 16 { - let blocks_count = integrality_buffer_slice_len / 16; - for i in 0..blocks_count { - let buf = &integrality_buffer_slice[i * 16..(i + 1) * 16]; - self.ghash_val = gmul_128(self.ghash_val ^ u8to128(buf), self.ghash_key) - } - self.integrality_buffer = integrality_buffer_slice[blocks_count * 16..].to_vec(); - } - } - - fn ghash_key(&mut self) -> u128 { - let mut block = [0u8; 16]; - let block = Block::::from_mut_slice(&mut block); - self.crypto.encrypt_block(block); - u8to128(&block.as_slice()) - } - - fn normalize_nonce(&mut self, nonce_bytes: &[u8]) -> (u128, u128) { - let ghash_key = self.ghash_key(); - normalize_nonce(ghash_key, nonce_bytes) - } -} - -fn normalize_nonce(ghash_key: u128, nonce_bytes: &[u8]) -> (u128, u128) { - let nonce = u8to128(nonce_bytes); - let normalized_nonce = match nonce_bytes.len() == 12 { - true => { - nonce << 32 | 0x00000001 - } - false => { - let mut iv_padding = vec![]; - // s = 128[len(iv) / 128] - len(iv) - let s = 128 * (((nonce_bytes.len() * 8) + 128 - 1) / 128) - (nonce_bytes.len() * 8); - iv_padding.push(nonce << s); - iv_padding.push((nonce_bytes.len() * 8) as u128); - ghash(ghash_key, &iv_padding) - } - }; - (ghash_key, normalized_nonce) -} - -// R = 11100001 || 0(120) -const R: u128 = 0b11100001 << 120; - -fn gmul_128(x: u128, y: u128) -> u128 { - let mut z = 0u128; - let mut v = y; - for i in (0..128).rev() { - let xi = (x >> i) & 1; - if xi != 0 { - z ^= v; - } - v = match v & 1 == 0 { - true => { v >> 1 } - false => { (v >> 1) ^ R } - }; - } - z -} - -fn ghash(key: u128, messages: &[u128]) -> u128 { - let mut y = 0u128; - for i in 0..messages.len() { - let yi = gmul_128(y ^ messages[i], key); - y = yi; - } - y -} - -fn u8to128(bytes: &[u8]) -> u128 { - bytes.iter().rev().enumerate().fold(0, |acc, (i, &byte)| { - acc | (byte as u128) << (i * 8) - }) -} - -fn msb_s(s: usize, bytes: &[u8]) -> Vec { - let mut result = vec![]; - let n = s / 8; - let remain = s % 8; - for i in 0..n { - result.push(bytes[i]); - } - if remain > 0 { - result.push(bytes[n] >> (8 - remain)); - } - result -} - -// incs(X)=MSBlen(X)-s(X) || [int(LSBs(X))+1 mod 2^s]s -fn inc_32(bits: u128) -> u128 { - let msb = bits >> 32; - let mut lsb = (bits & 0xffffffff) as u32; - lsb = lsb.wrapping_add(1); - msb << 32 | lsb as u128 -} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d664c22..051fa14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use aes::cipher::KeyInit; use aes_gcm::{AeadInPlace, Aes128Gcm, Key}; use aes_gcm::aead::{Aead, Nonce}; -use aes_gcm_stream::Aes128GcmStreamEncryptor; +use aes_gcm_stream::{Aes128GcmStreamDecryptor, Aes128GcmStreamEncryptor}; use crate::copied::GCM; @@ -42,16 +42,23 @@ fn main() { cipher.encrypt_in_place(&nonce, &[], &mut ciphertext).unwrap(); println!("{}", hex::encode(ciphertext.as_slice())); - let mut aes128_gcm_stream = Aes128GcmStreamEncryptor::new([0; 16]); - aes128_gcm_stream.init_nonce(&[0u8; 12]); - aes128_gcm_stream.init_adata(&[]); - let o1 = aes128_gcm_stream.next(&plaintext[0..21]); - let o2 = aes128_gcm_stream.next(&plaintext[21..64]); - let o3 = aes128_gcm_stream.next(&[0; 5]); - let (o4, t) = aes128_gcm_stream.finalize(); + let mut aes128_gcm_stream_encryptor = Aes128GcmStreamEncryptor::new([0; 16]); + aes128_gcm_stream_encryptor.init_nonce(&[0u8; 12]); + aes128_gcm_stream_encryptor.init_adata(&[]); + let o1 = aes128_gcm_stream_encryptor.next(&plaintext[0..21]); + let o2 = aes128_gcm_stream_encryptor.next(&plaintext[21..64]); + let o3 = aes128_gcm_stream_encryptor.next(&[0; 5]); + let (o4, t) = aes128_gcm_stream_encryptor.finalize(); println!("{}: E1", hex::encode(&o1)); println!("{}: E2", hex::encode(&o2)); println!("{}: E3", hex::encode(&o3)); println!("{}: E4", hex::encode(&o4)); println!("{} : TAG", hex::encode(&t)); + + let mut aes128_gcm_stream_decryptor = Aes128GcmStreamDecryptor::new([0; 16]); + aes128_gcm_stream_decryptor.init_nonce(&[0u8; 12]); + let o1 = aes128_gcm_stream_decryptor.next(&hex::decode("0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8c992f32a52151e1c2adceb7c6138e042").unwrap()); + let o2_result = aes128_gcm_stream_decryptor.finalize(); + println!("{}", hex::encode(&o1)); + println!("{:?}", o2_result); } \ No newline at end of file diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..ea23b3d --- /dev/null +++ b/src/util.rs @@ -0,0 +1,72 @@ +// R = 11100001 || 0(120) +const R: u128 = 0b11100001 << 120; + +pub(crate) fn gmul_128(x: u128, y: u128) -> u128 { + let mut z = 0u128; + let mut v = y; + for i in (0..128).rev() { + let xi = (x >> i) & 1; + if xi != 0 { + z ^= v; + } + v = match v & 1 == 0 { + true => { v >> 1 } + false => { (v >> 1) ^ R } + }; + } + z +} + +pub(crate) fn ghash(key: u128, messages: &[u128]) -> u128 { + let mut y = 0u128; + for i in 0..messages.len() { + let yi = gmul_128(y ^ messages[i], key); + y = yi; + } + y +} + +pub(crate) fn normalize_nonce(ghash_key: u128, nonce_bytes: &[u8]) -> (u128, u128) { + let nonce = u8to128(nonce_bytes); + let normalized_nonce = match nonce_bytes.len() == 12 { + true => { + nonce << 32 | 0x00000001 + } + false => { + let mut iv_padding = vec![]; + // s = 128[len(iv) / 128] - len(iv) + let s = 128 * (((nonce_bytes.len() * 8) + 128 - 1) / 128) - (nonce_bytes.len() * 8); + iv_padding.push(nonce << s); + iv_padding.push((nonce_bytes.len() * 8) as u128); + ghash(ghash_key, &iv_padding) + } + }; + (ghash_key, normalized_nonce) +} + +pub(crate) fn u8to128(bytes: &[u8]) -> u128 { + bytes.iter().rev().enumerate().fold(0, |acc, (i, &byte)| { + acc | (byte as u128) << (i * 8) + }) +} + +pub(crate) fn msb_s(s: usize, bytes: &[u8]) -> Vec { + let mut result = vec![]; + let n = s / 8; + let remain = s % 8; + for i in 0..n { + result.push(bytes[i]); + } + if remain > 0 { + result.push(bytes[n] >> (8 - remain)); + } + result +} + +// incs(X)=MSBlen(X)-s(X) || [int(LSBs(X))+1 mod 2^s]s +pub(crate) fn inc_32(bits: u128) -> u128 { + let msb = bits >> 32; + let mut lsb = (bits & 0xffffffff) as u32; + lsb = lsb.wrapping_add(1); + msb << 32 | lsb as u128 +} \ No newline at end of file