Skip to content

Commit

Permalink
refactor: keystream
Browse files Browse the repository at this point in the history
  • Loading branch information
Nugine committed Jan 23, 2025
1 parent 6387df8 commit 3fb9ab5
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 51 deletions.
53 changes: 28 additions & 25 deletions src/eea3/stream_cipher.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::Eea3Keystream;

use crate::internal::stream_cipher::xor_to_vec;
use crate::internal::stream_cipher::xor_inplace;

/// 128-EEA3 stream cipher
/// ([EEA3-EIA3-specification](https://www.gsma.com/solutions-and-impact/technologies/security/wp-content/uploads/2019/05/EEA3_EIA3_specification_v1_8.pdf))
Expand All @@ -9,32 +9,25 @@ pub type Eea3StreamCipher = cipher::StreamCipherCoreWrapper<Eea3Keystream>;
/// 128-EEA3: 3GPP confidentiality algorithm
/// ([EEA3-EIA3-specification](https://www.gsma.com/solutions-and-impact/technologies/security/wp-content/uploads/2019/05/EEA3_EIA3_specification_v1_8.pdf))
///
/// Input:
/// - count: 32bit counter
/// - bearer: 5bit carrier layer identification
/// - direction: 1bit transmission direction identification
/// - ck: 128bit confidentiality key
/// - length: 32bit bit length of plaintext information stream
/// - ibs: input bitstream
///
/// Output:
/// - [`Vec<u8>`]: encrypted bit stream
///
/// # Panics
/// + Panics if `length` is greater than the length of `ibs` times 8.
/// + Panics if `length` is greater than `usize::MAX`.
#[must_use]
pub fn eea3_encrypt(
/// ## Input
/// | name | size | description |
/// | --------- | -------- | ------------------------------------- |
/// | count | 32 bits | counter |
/// | bearer | 5 bits | carrier layer identification |
/// | direction | 1 bit | transmission direction identification |
/// | ck | 128 bits | confidentiality key |
/// | data | - | the bitstream |
/// | bitlen | - | bit length of the bitstream |
pub fn eea3_xor_inplace(
count: u32,
bearer: u8,
direction: u8,
ck: &[u8; 16],
length: u32,
ibs: &[u8],
) -> Vec<u8> {
let bitlen = usize::try_from(length).expect("bit length overflow");
data: &mut [u8],
bitlen: usize,
) {
let mut eea3 = Eea3Keystream::new(count, bearer, direction, ck);
xor_to_vec(&mut eea3, ibs, bitlen)
xor_inplace(&mut eea3, data, bitlen);
}

#[cfg(test)]
Expand Down Expand Up @@ -217,15 +210,25 @@ mod tests {
#[test]
fn examples() {
for x in ALL_EXAMPLES {
let obs = eea3_encrypt(x.count, x.bearer, x.direction, &x.ck, x.length, x.ibs);
assert_eq!(obs, x.obs);
let mut data = x.ibs.to_vec();
eea3_xor_inplace(
x.count,
x.bearer,
x.direction,
&x.ck,
&mut data,
x.length as usize,
);
assert_eq!(data, x.obs);
}
}

#[should_panic(expected = "assertion failed: bitlen <= data.len() * 8")]
#[test]
fn invalid_input() {
let x = &EXAMPLE1;
let _ = eea3_encrypt(x.count, x.bearer, x.direction, &x.ck, x.length * 2, x.ibs);
let mut data = x.ibs.to_vec();
let bitlen = x.length as usize * 2;
eea3_xor_inplace(x.count, x.bearer, x.direction, &x.ck, &mut data, bitlen);
}
}
6 changes: 0 additions & 6 deletions src/internal/stream_cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,3 @@ pub fn xor_inplace(zuc: &mut impl Keystream<Word = u32>, data: &mut [u8], bitlen
data[i] = 0;
}
}

pub fn xor_to_vec(zuc: &mut impl Keystream<Word = u32>, ibs: &[u8], bitlen: usize) -> Vec<u8> {
let mut res = ibs.to_vec();
xor_inplace(zuc, &mut res, bitlen);
res
}
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub mod zuc128 {

pub use self::keystream::Zuc128Keystream;
pub use self::mac::Zuc128Mac;
pub use self::stream_cipher::{zuc128_xor_encrypt, Zuc128StreamCipher};
pub use self::stream_cipher::{zuc128_xor_inplace, Zuc128StreamCipher};
}

pub mod zuc256 {
Expand All @@ -60,7 +60,7 @@ pub mod eea3 {
mod stream_cipher;

pub use self::keystream::Eea3Keystream;
pub use self::stream_cipher::{eea3_encrypt, Eea3StreamCipher};
pub use self::stream_cipher::{eea3_xor_inplace, Eea3StreamCipher};
}

pub mod eia3 {
Expand Down
29 changes: 11 additions & 18 deletions src/zuc128/stream_cipher.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
use super::Zuc128Keystream;

use crate::internal::stream_cipher::xor_to_vec;
use crate::internal::stream_cipher::xor_inplace;

/// ZUC128 stream cipher
/// ([GB/T 33133.1-2016](https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=8C41A3AEECCA52B5C0011C8010CF0715))
pub type Zuc128StreamCipher = cipher::StreamCipherCoreWrapper<Zuc128Keystream>;

/// ZUC128 xor encryption algorithm
/// ZUC128 confidentiality algorithm
/// ([GB/T 33133.2-2021](https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=5D3CBA3ADEC7989344BD1E63006EF2B3))
///
/// Input:
/// - `ck`: 128bit confidentiality key
/// - `iv`: 128bit initial vector
/// - `length`: 32bit bit length of plaintext information stream
/// - `ibs`: input bitstream
///
/// Output:
/// - [`Vec<u8>`]: encrypted bit stream
///
/// # Panics
/// + Panics if `length` is greater than the length of `ibs` times 8.
/// + Panics if `length` is greater than `usize::MAX`.
#[must_use]
pub fn zuc128_xor_encrypt(ck: &[u8; 16], iv: &[u8; 16], length: u32, ibs: &[u8]) -> Vec<u8> {
let bitlen = usize::try_from(length).expect("bit length overflow");
/// ## Input
/// | name | size | description |
/// | ------ | -------- | --------------------------- |
/// | ck | 128 bits | confidentiality key |
/// | iv | 128 bits | initial vector |
/// | data | - | the bitstream |
/// | bitlen | - | bit length of the bitstream |
pub fn zuc128_xor_inplace(ck: &[u8; 16], iv: &[u8; 16], data: &mut [u8], bitlen: usize) {
let mut zuc = Zuc128Keystream::new(ck, iv);
xor_to_vec(&mut zuc, ibs, bitlen)
xor_inplace(&mut zuc, data, bitlen);
}

0 comments on commit 3fb9ab5

Please sign in to comment.