Skip to content

feat: add RC4 implementation - #285

Merged
tarcieri merged 7 commits into
RustCrypto:masterfrom
magic-akari:feat/rc4
Mar 27, 2022
Merged

tarcieri merged 7 commits into
RustCrypto:masterfrom
magic-akari:feat/rc4

Conversation

@magic-akari

Copy link
Copy Markdown
Contributor

No description provided.

@magic-akari

Copy link
Copy Markdown
Contributor Author

It's hard to implement NewCipher for Rc4 since Rc4 can use variable key lengths.
What do you think about it? @tarcieri

@tarcieri

Copy link
Copy Markdown
Member

@magic-akari you can make the NewCipher impl generic around a key size, and use a marker trait to determine the set of valid key sizes

See how AesGcm is similarly generic around a NonceSize as a roughly analogous example:

https://docs.rs/aes-gcm/latest/aes_gcm/struct.AesGcm.html

@magic-akari

Copy link
Copy Markdown
Contributor Author

#[test]
fn test() {
let mut rc4 = Rc4::new(b"Key".into(), &Default::default());
let mut data = b"Plaintext".to_vec();
rc4.try_apply_keystream(&mut data).unwrap();
assert_eq!(data, [0xBB, 0xF3, 0x16, 0xE8, 0xD9, 0x40, 0xAF, 0x0A, 0xD3]);
}
#[test]
fn test2() {
use cipher::consts::U3;
let mut rc4 = Rc4::<U3>::new_from_slices(b"Key", Default::default()).unwrap();
let mut data = b"Plaintext".to_vec();
rc4.try_apply_keystream(&mut data).unwrap();
assert_eq!(data, [0xBB, 0xF3, 0x16, 0xE8, 0xD9, 0x40, 0xAF, 0x0A, 0xD3]);
}

HI, @tarcieri ,
I tried to implement NewCipher, but it would be a pain for users to use.

User have to write Rc4::new(b"Key".into(), &Default::default()); or Rc4::<U3>::new_from_slices(b"Key", Default::default())

<U3> cannot be inferred and must be written manually.

While as a user, I prefer the following codes.
What do you think about it?

fn test() {
let mut rc4 = Rc4::new_from_slices(b"Key").unwrap();
let mut data = b"Plaintext".to_vec();
rc4.try_apply_keystream(&mut data).unwrap();
assert_eq!(data, [0xBB, 0xF3, 0x16, 0xE8, 0xD9, 0x40, 0xAF, 0x0A, 0xD3]);
}

@tarcieri

tarcieri commented Feb 1, 2022 •

Copy link
Copy Markdown
Member

@magic-akari the root problem there is really generic-array, and yes, its ergonomics are bad. Long term we'd like to get rid of it, and in the medium term perhaps we can replace it with RustCrypto/utils#707

However, I think it would still make sense to impl NewCipher.

Users should define a type alias with the expected key size, or the crate can define some aliases for common key sizes:

pub type Rc4_128 = Rc4<U16>;

To me this is preferable to trying to infer the key size from the parameter, since unless it's constrained someone might accidentally pass the wrong/unexpected key size for a given application without noticing.

@magic-akari
magic-akari marked this pull request as ready for review February 9, 2022 13:52
@newpavlov

Copy link
Copy Markdown
Member

Can you please update this crate to cipher v0.4? I will try to review it next week.

@magic-akari

Copy link
Copy Markdown
Contributor Author

HI, @newpavlov
I tried to update it. I have to say it's hard to implement StreamCipherCore as it require a BlockSize.
Do you have any idea about it?
What BlockSize should Rc4 use?

@newpavlov

Copy link
Copy Markdown
Member

Well, strictly speaking RC4 has block size of one byte. Implementation of StreamBackend::gen_ks_block would look rougly like this:

fn gen_ks_block(&mut self, block: &mut Block<Self>) {
    // `block` has type of `GenericArray<u8, U1>`
    block[0] = self.state.prga();
}

Alternatively you could implement the StreamCipher trait directly.

@magic-akari

Copy link
Copy Markdown
Contributor Author

@newpavlov can you review it?

@tarcieri

Copy link
Copy Markdown
Member

I can do a first pass this weekend

@tarcieri

Copy link
Copy Markdown
Member

Looks good, thank you!

I'm going to do some minor followup cleanups after merging.

@tarcieri
tarcieri merged commit 532872b into RustCrypto:master Mar 27, 2022
@tarcieri

Copy link
Copy Markdown
Member

See #299 for fixups

tarcieri added a commit that referenced this pull request Mar 27, 2022
Adds the recently merged `rc4` crate to the table (#285)

Also adds a "Security" column similar to the one in this table:
https://github.com/RustCrypto/hashes/blob/master/README.md#supported-algorithms

- ChaCha20 and Salsa20 are categorized as secure
- HC-256 and Rabbit have theoretical breakages
- RC4 is broken and vulnerable to plaintext recovery

Both HC-256 and Rabbit have known distinguishing attacks:

- https://link.springer.com/chapter/10.1007/978-3-642-04846-3_4
- https://eprint.iacr.org/2013/780.pdf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants