1 /// Implementation of RC4 digester. 2 module tern.digest.rc4; 3 4 import tern.serialization; 5 import tern.digest; 6 import tern.digest.circe; 7 8 /** 9 * Implementation of RC4 digester. 10 * 11 * RC4 (Rivest Cipher 4) is a stream cipher algorithm widely used in various cryptographic 12 * applications. It operates by generating a pseudorandom stream of bits (keystream) based on 13 * a secret key, which is then XORed with the plaintext to produce the ciphertext. 14 * 15 * Example: 16 * ```d 17 * import tern.digest.rc4; 18 * 19 * ubyte[] data = [1, 2, 3, 4, 5]; 20 * string key = "my_secret_key"; 21 * RC4.encrypt(data, key); 22 * ``` 23 */ 24 public static @digester class RC4 25 { 26 public: 27 static: 28 pure: 29 /** 30 * Encrypts the given byte array `data`. 31 * 32 * Params: 33 * data = Reference to the input byte array to be encrypted. 34 * key = The encryption key. 35 */ 36 void encrypt(ref ubyte[] data, string key) 37 { 38 assert(key.length == 32, "Key must be 256 bits!"); 39 40 key = cast(string)Circe.hash(cast(ubyte[])key); 41 ubyte[256] S; 42 ubyte[256] T; 43 44 for (ubyte i = 0; i < 256; ++i) 45 { 46 S[i] = i; 47 T[i] = cast(ubyte)key[i % key.length]; 48 } 49 50 ubyte j = 0; 51 for (ubyte i = 0; i < 256; ++i) 52 { 53 j = (j + S[i] + T[i]) % 256; 54 S[i] = S[i] ^ S[j]; 55 S[j] = S[i] ^ S[j]; 56 S[i] = S[i] ^ S[j]; 57 } 58 59 ubyte i = 0; 60 j = 0; 61 foreach (ref b; data) 62 { 63 i = (i + 1) % 256; 64 j = (j + S[i]) % 256; 65 S[i] = S[i] ^ S[j]; 66 S[j] = S[i] ^ S[j]; 67 S[i] = S[i] ^ S[j]; 68 b ^= S[(S[i] + S[j]) % 256]; 69 } 70 } 71 72 /** 73 * Decrypts the given byte array `data`. 74 * 75 * Params: 76 * data = Reference to the input byte array to be decrypted. 77 * key = The decryption key. 78 */ 79 void decrypt(ref ubyte[] data, string key) => encrypt(data, key); 80 }