1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
4+ using System . Security . Cryptography ;
5+ using System . Text ;
6+
7+ public class IronWallCipher
8+ {
9+ // --- HELPER BIT OPERATIONS ---
10+
11+ // Rotates bits to the left (For Diffusion effect)
12+ private static byte RotateLeft ( byte value , int count )
13+ {
14+ return ( byte ) ( ( value << count ) | ( value >> ( 8 - count ) ) ) ;
15+ }
16+
17+ // Rotates bits to the right (For Decryption)
18+ private static byte RotateRight ( byte value , int count )
19+ {
20+ return ( byte ) ( ( value >> count ) | ( value << ( 8 - count ) ) ) ;
21+ }
22+
23+ // Derives a strong key from Password and Salt
24+ private static byte [ ] DeriveKey ( string password , byte [ ] salt )
25+ {
26+ using ( var sha256 = SHA256 . Create ( ) )
27+ {
28+ var passwordBytes = Encoding . UTF8 . GetBytes ( password ) ;
29+ var combined = new byte [ passwordBytes . Length + salt . Length ] ;
30+ Buffer . BlockCopy ( passwordBytes , 0 , combined , 0 , passwordBytes . Length ) ;
31+ Buffer . BlockCopy ( salt , 0 , combined , passwordBytes . Length , salt . Length ) ;
32+ return sha256 . ComputeHash ( combined ) ;
33+ }
34+ }
35+
36+ // --- ENCRYPTION ---
37+ public static byte [ ] Encrypt ( byte [ ] data , string password )
38+ {
39+ // 1. Generate a unique random 'Salt' for each file
40+ byte [ ] salt = new byte [ 16 ] ;
41+ using ( var rng = RandomNumberGenerator . Create ( ) )
42+ {
43+ rng . GetBytes ( salt ) ;
44+ }
45+
46+ // 2. Derive the key
47+ byte [ ] key = DeriveKey ( password , salt ) ;
48+ List < byte > result = new List < byte > ( ) ;
49+
50+ // Prepend the Salt to the file (Needed for decryption)
51+ result . AddRange ( salt ) ;
52+
53+ byte currentKeyByte = key [ 0 ] ;
54+
55+ for ( int i = 0 ; i < data . Length ; i ++ )
56+ {
57+ byte b = data [ i ] ;
58+
59+ // LAYER 1: XOR (Confusion)
60+ b = ( byte ) ( b ^ currentKeyByte ) ;
61+
62+ // LAYER 2: Bit Rotation (Avalanche Effect)
63+ b = RotateLeft ( b , 3 ) ;
64+
65+ // LAYER 3: Modular Addition (To break linearity)
66+ b = ( byte ) ( b + key [ i % key . Length ] ) ;
67+
68+ // LAYER 4: Chaining (Cipher Block Chaining - CBC style)
69+ // The previous encrypted byte affects the current one.
70+ // Even a 1-bit change at the start changes the entire file.
71+ if ( i > 0 )
72+ {
73+ // Get the last added element from Result list (Account for Salt length)
74+ byte previousEncryptedByte = result [ result . Count - 1 ] ;
75+ b = ( byte ) ( b ^ previousEncryptedByte ) ;
76+ }
77+
78+ result . Add ( b ) ;
79+
80+ // Update the key at every step (Rolling Key)
81+ currentKeyByte = ( byte ) ( ( currentKeyByte + 11 ) % 256 ) ;
82+ }
83+
84+ return result . ToArray ( ) ;
85+ }
86+
87+ // --- DECRYPTION ---
88+ public static byte [ ] Decrypt ( byte [ ] encryptedData , string password )
89+ {
90+ if ( encryptedData . Length < 16 ) throw new Exception ( "Invalid or corrupted file format." ) ;
91+
92+ // 1. Extract the Salt from the beginning
93+ byte [ ] salt = encryptedData . Take ( 16 ) . ToArray ( ) ;
94+ byte [ ] actualData = encryptedData . Skip ( 16 ) . ToArray ( ) ;
95+
96+ // 2. Re-derive the key
97+ byte [ ] key = DeriveKey ( password , salt ) ;
98+
99+ byte [ ] decrypted = new byte [ actualData . Length ] ;
100+ byte currentKeyByte = key [ 0 ] ;
101+
102+ for ( int i = 0 ; i < actualData . Length ; i ++ )
103+ {
104+ byte b = actualData [ i ] ;
105+
106+ // We need the previous encrypted data to reverse the chaining
107+ byte xorMask = 0 ;
108+ if ( i > 0 )
109+ {
110+ xorMask = actualData [ i - 1 ] ;
111+ }
112+
113+ // PERFORM OPERATIONS IN REVERSE ORDER (Reverse Engineering)
114+
115+ // 4. Reverse Chaining
116+ if ( i > 0 )
117+ {
118+ b = ( byte ) ( b ^ xorMask ) ;
119+ }
120+
121+ // 3. Modular Subtraction
122+ b = ( byte ) ( b - key [ i % key . Length ] ) ;
123+
124+ // 2. Right Bit Rotation
125+ b = RotateRight ( b , 3 ) ;
126+
127+ // 1. Reverse XOR
128+ b = ( byte ) ( b ^ currentKeyByte ) ;
129+
130+ decrypted [ i ] = b ;
131+
132+ // Update key (Same logic as encryption)
133+ currentKeyByte = ( byte ) ( ( currentKeyByte + 11 ) % 256 ) ;
134+ }
135+
136+ return decrypted ;
137+ }
138+ }
0 commit comments