Skip to content

Commit

Permalink
feat: TABLE cipher add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zonyitoo committed Jun 14, 2024
1 parent 74a3808 commit 6da6267
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 56 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shadowsocks-crypto"
version = "0.5.4"
version = "0.5.5"
authors = ["luozijun <[email protected]>", "ty <[email protected]>"]
edition = "2021"
license = "MIT"
Expand Down Expand Up @@ -70,3 +70,7 @@ subtle = { version = "2.5", optional = true }

[dev-dependencies]
hex = "0.4"

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
102 changes: 51 additions & 51 deletions src/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ pub enum CipherCategory {
None,
/// Stream ciphers is used for OLD ShadowSocks protocol, which uses stream ciphers to encrypt data payloads
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
Stream,
/// AEAD ciphers is used in modern ShadowSocks protocol, which sends data in separate packets
#[cfg(feature = "v1-aead")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))]
Aead,
/// AEAD ciphers 2022 with enhanced security
#[cfg(feature = "v2")]
#[cfg_attr(docrs, doc(cfg(feature = "v2")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v2")))]
Aead2022,
}

Expand All @@ -81,180 +81,180 @@ pub enum CipherKind {
NONE,

#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
SS_TABLE,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
SS_RC4_MD5,

#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_128_CTR,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_192_CTR,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_256_CTR,

#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_128_CFB1,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_128_CFB8,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_128_CFB128,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_192_CFB1,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_192_CFB8,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_192_CFB128,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_256_CFB1,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_256_CFB8,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_256_CFB128,

#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_128_OFB,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_192_OFB,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
AES_256_OFB,

#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_128_CTR,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_192_CTR,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_256_CTR,

#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_128_CFB1,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_128_CFB8,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_128_CFB128,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_192_CFB1,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_192_CFB8,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_192_CFB128,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_256_CFB1,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_256_CFB8,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_256_CFB128,

#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_128_OFB,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_192_OFB,
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CAMELLIA_256_OFB,

#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
RC4,
// NOTE: IETF 版本
#[cfg(feature = "v1-stream")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
CHACHA20,

// AEAD Cipher
#[cfg(feature = "v1-aead")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))]
/// AEAD_AES_128_GCM
AES_128_GCM,
#[cfg(feature = "v1-aead")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))]
/// AEAD_AES_256_GCM
AES_256_GCM,

#[cfg(feature = "v1-aead-extra")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
/// AEAD_AES_128_CCM
AES_128_CCM,
#[cfg(feature = "v1-aead-extra")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
/// AEAD_AES_256_CCM
AES_256_CCM,

#[cfg(feature = "v1-aead-extra")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
/// AEAD_AES_128_GCM_SIV
AES_128_GCM_SIV,
#[cfg(feature = "v1-aead-extra")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
/// AEAD_AES_256_GCM_SIV
AES_256_GCM_SIV,

// NOTE: IETF 版本
#[cfg(feature = "v1-aead")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))]
/// AEAD_CHACHA20_POLY1305
CHACHA20_POLY1305,

#[cfg(feature = "v1-aead-extra")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
/// AEAD_XCHACHA20_POLY1305
XCHACHA20_POLY1305,

#[cfg(feature = "v1-aead-extra")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
/// SM4_GCM
SM4_GCM,
#[cfg(feature = "v1-aead-extra")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
/// SM4_GCM
SM4_CCM,

#[cfg(feature = "v2")]
#[cfg_attr(docrs, doc(cfg(feature = "v2")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v2")))]
/// 2022-blake3-aes-128-gcm
AEAD2022_BLAKE3_AES_128_GCM,

#[cfg(feature = "v2")]
#[cfg_attr(docrs, doc(cfg(feature = "v2")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v2")))]
/// 2022-blake3-aes-128-gcm
AEAD2022_BLAKE3_AES_256_GCM,

#[cfg(feature = "v2")]
#[cfg_attr(docrs, doc(cfg(feature = "v2")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v2")))]
/// 2022-blake3-chacha20-poly1305
AEAD2022_BLAKE3_CHACHA20_POLY1305,
#[cfg(feature = "v2-extra")]
#[cfg_attr(docrs, doc(cfg(feature = "v2-extra")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v2-extra")))]
/// 2022-blake3-chacha8-poly1305
AEAD2022_BLAKE3_CHACHA8_POLY1305,
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
#![cfg_attr(docsrs, feature(doc_cfg))]

#[cfg(feature = "v1")]
#[cfg_attr(docrs, doc(cfg(feature = "v1")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v1")))]
pub mod v1;

#[cfg(feature = "v2")]
#[cfg_attr(docrs, doc(cfg(feature = "v2")))]
#[cfg_attr(docsrs, doc(cfg(feature = "v2")))]
pub mod v2;

pub mod kind;
Expand Down
54 changes: 52 additions & 2 deletions src/v1/streamcipher/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ impl Table {
let a = u64::from_le_bytes([h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]]);

let mut table = [0u64; Self::TABLE_SIZE];
for (i, item) in table.iter_mut().enumerate().take(Self::TABLE_SIZE) {
*item = i as u64;

for i in 0..table.len() {

Check warning on line 27 in src/v1/streamcipher/table.rs

View workflow job for this annotation

GitHub Actions / clippy-ubuntu-latest

the loop variable `i` is used to index `table`

warning: the loop variable `i` is used to index `table` --> src/v1/streamcipher/table.rs:27:18 | 27 | for i in 0..table.len() { | ^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop help: consider using an iterator and enumerate() | 27 | for (i, <item>) in table.iter_mut().enumerate() { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Check warning on line 27 in src/v1/streamcipher/table.rs

View workflow job for this annotation

GitHub Actions / clippy-macos-latest

the loop variable `i` is used to index `table`

warning: the loop variable `i` is used to index `table` --> src/v1/streamcipher/table.rs:27:18 | 27 | for i in 0..table.len() { | ^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop help: consider using an iterator and enumerate() | 27 | for (i, <item>) in table.iter_mut().enumerate() { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
table[i] = i as u64;
}

for i in 1..1024 {
Expand Down Expand Up @@ -74,3 +75,52 @@ fn test_table() {

assert_eq!(&cleartext[..], plaintext);
}

#[test]
fn test_table_box() {
let key: &[u8] = b"password";
let ebox: [u8; 256] = [
157, 219, 245, 15, 85, 7, 195, 211, 55, 126, 37, 117, 249, 229, 98, 205, 254, 61, 137, 77, 253, 135, 138, 185,
45, 100, 75, 97, 46, 22, 28, 84, 143, 160, 175, 136, 194, 2, 201, 173, 132, 155, 23, 174, 95, 54, 0, 239, 6,
153, 180, 34, 149, 26, 19, 101, 203, 247, 214, 111, 127, 119, 81, 177, 53, 142, 13, 216, 115, 241, 202, 73, 48,
86, 1, 11, 43, 125, 41, 121, 209, 193, 199, 51, 47, 32, 36, 90, 255, 156, 38, 108, 3, 99, 238, 179, 50, 237,
158, 186, 110, 217, 76, 223, 118, 196, 107, 83, 39, 63, 9, 129, 72, 5, 56, 234, 91, 250, 224, 228, 251, 146,
170, 151, 21, 10, 171, 114, 154, 172, 58, 78, 140, 197, 67, 35, 130, 92, 12, 31, 189, 166, 122, 29, 123, 113,
215, 94, 165, 89, 221, 240, 93, 178, 150, 218, 220, 232, 144, 188, 65, 88, 52, 59, 139, 242, 71, 62, 182, 57,
225, 147, 30, 17, 68, 243, 80, 44, 141, 4, 200, 42, 16, 102, 134, 246, 70, 244, 145, 124, 213, 8, 187, 66, 183,
191, 40, 103, 162, 74, 87, 148, 230, 25, 120, 60, 233, 18, 176, 227, 184, 112, 20, 131, 109, 152, 14, 163, 49,
24, 222, 181, 164, 133, 207, 104, 210, 236, 27, 106, 96, 64, 33, 116, 79, 206, 69, 212, 82, 169, 105, 235, 190,
128, 226, 208, 168, 192, 167, 159, 161, 231, 204, 198, 248, 252,
];
let dbox: [u8; 256] = [
46, 74, 37, 92, 179, 113, 48, 5, 191, 110, 125, 75, 138, 66, 216, 3, 182, 173, 207, 54, 212, 124, 29, 42, 219,
203, 53, 228, 30, 143, 172, 139, 85, 232, 51, 135, 86, 10, 90, 108, 196, 78, 181, 76, 177, 24, 28, 84, 72, 218,
96, 83, 162, 64, 45, 8, 114, 169, 130, 163, 205, 17, 167, 109, 231, 160, 193, 134, 174, 236, 186, 166, 112, 71,
199, 26, 102, 19, 131, 234, 176, 62, 238, 107, 31, 4, 73, 200, 161, 149, 87, 116, 137, 152, 147, 44, 230, 27,
14, 93, 25, 55, 183, 197, 225, 240, 229, 106, 91, 214, 100, 59, 211, 145, 127, 68, 233, 11, 104, 61, 204, 79,
142, 144, 189, 77, 9, 60, 243, 111, 136, 213, 40, 223, 184, 21, 35, 18, 22, 164, 132, 178, 65, 32, 158, 188,
121, 171, 201, 52, 154, 123, 215, 49, 128, 41, 89, 0, 98, 249, 33, 250, 198, 217, 222, 148, 141, 248, 246, 239,
122, 126, 129, 39, 43, 34, 208, 63, 153, 95, 50, 221, 168, 194, 210, 23, 99, 192, 159, 140, 242, 195, 247, 81,
36, 6, 105, 133, 253, 82, 180, 38, 70, 56, 252, 15, 235, 224, 245, 80, 226, 7, 237, 190, 58, 146, 67, 101, 155,
1, 156, 150, 220, 103, 118, 170, 244, 209, 119, 13, 202, 251, 157, 206, 115, 241, 227, 97, 94, 47, 151, 69,
165, 175, 187, 2, 185, 57, 254, 12, 117, 120, 255, 20, 16, 88,
];

let cipher = Table::new(key, b"");
assert_eq!(cipher.ebox, ebox);
assert_eq!(cipher.dbox, dbox);
}

#[test]
fn test_table_encrypt() {
let key: &[u8] = b"password";
let plain_text: &[u8] = b"hello world";
let cipher_text: &[u8] = &[118, 217, 39, 39, 129, 143, 228, 129, 56, 39, 110];

let mut cipher = Table::new(key, b"");

let mut text_buffer = plain_text.to_vec();
cipher.encrypt_slice(&mut text_buffer);

assert_eq!(cipher_text, text_buffer);
}

0 comments on commit 6da6267

Please sign in to comment.