@@ -126,65 +126,98 @@ public static void PerformAESOperation(uint size,
126126
127127 #endregion
128128
129+ // TODO: Remove when IO updated
129130 #region Byte Arrays
130131
131132 /// <summary>
132133 /// Add an integer value to a number represented by a byte array
133134 /// </summary>
134- /// <param name="input ">Byte array to add to</param>
135+ /// <param name="self ">Byte array to add to</param>
135136 /// <param name="add">Amount to add</param>
136137 /// <returns>Byte array representing the new value</returns>
137- public static byte [ ] Add ( byte [ ] input , uint add )
138+ /// <remarks>Assumes array values are in big-endian format</remarks>
139+ public static byte [ ] Add ( this byte [ ] self , uint add )
138140 {
141+ // If nothing is being added, just return
142+ if ( add == 0 )
143+ return self ;
144+
145+ // Get the big-endian representation of the value
139146 byte [ ] addBytes = BitConverter . GetBytes ( add ) ;
140147 Array . Reverse ( addBytes ) ;
148+
149+ // Pad the array out to 16 bytes
141150 byte [ ] paddedBytes = new byte [ 16 ] ;
142151 Array . Copy ( addBytes , 0 , paddedBytes , 12 , 4 ) ;
143- return Add ( input , paddedBytes ) ;
152+
153+ // If the input is empty, just return the added value
154+ if ( self . Length == 0 )
155+ return paddedBytes ;
156+
157+ return self . Add ( paddedBytes ) ;
144158 }
145159
146160 /// <summary>
147161 /// Add two numbers represented by byte arrays
148162 /// </summary>
149- /// <param name="left ">Byte array to add to</param>
150- /// <param name="right ">Amount to add</param>
163+ /// <param name="self ">Byte array to add to</param>
164+ /// <param name="add ">Amount to add</param>
151165 /// <returns>Byte array representing the new value</returns>
152- public static byte [ ] Add ( byte [ ] left , byte [ ] right )
166+ /// <remarks>Assumes array values are in big-endian format</remarks>
167+ public static byte [ ] Add ( this byte [ ] self , byte [ ] add )
153168 {
154- int addBytes = Math . Min ( left . Length , right . Length ) ;
155- int outLength = Math . Max ( left . Length , right . Length ) ;
156-
169+ // If either input is empty
170+ if ( self . Length == 0 && add . Length == 0 )
171+ return [ ] ;
172+ else if ( self . Length > 0 && add . Length == 0 )
173+ return self ;
174+ else if ( self . Length == 0 && add . Length > 0 )
175+ return add ;
176+
177+ // Setup the output array
178+ int outLength = Math . Max ( self . Length , add . Length ) ;
157179 byte [ ] output = new byte [ outLength ] ;
158180
181+ // Loop adding with carry
159182 uint carry = 0 ;
160- for ( int i = addBytes - 1 ; i >= 0 ; i -- )
183+ for ( int i = 0 ; i < outLength ; i ++ )
161184 {
162- uint addValue = ( uint ) ( left [ i ] + right [ i ] ) + carry ;
163- output [ i ] = ( byte ) addValue ;
164- carry = addValue >> 8 ;
165- }
185+ int selfIndex = self . Length - i - 1 ;
186+ uint selfValue = selfIndex >= 0 ? self [ selfIndex ] : 0u ;
166187
167- if ( outLength != addBytes && left . Length == outLength )
168- Array . Copy ( left , addBytes , output , addBytes , outLength - addBytes ) ;
169- else if ( outLength != addBytes && right . Length == outLength )
170- Array . Copy ( right , addBytes , output , addBytes , outLength - addBytes ) ;
188+ int addIndex = add . Length - i - 1 ;
189+ uint addValue = addIndex >= 0 ? add [ addIndex ] : 0u ;
190+
191+ uint next = selfValue + addValue + carry ;
192+ carry = next >> 8 ;
193+
194+ int outputIndex = output . Length - i - 1 ;
195+ output [ outputIndex ] = ( byte ) ( next & 0xFF ) ;
196+ }
171197
172198 return output ;
173199 }
174200
175201 /// <summary>
176202 /// Perform a rotate left on a byte array
177203 /// </summary>
178- /// <param name="val ">Byte array value to rotate</param>
179- /// <param name="r_bits ">Number of bits to rotate</param>
204+ /// <param name="self ">Byte array value to rotate</param>
205+ /// <param name="numBits ">Number of bits to rotate</param>
180206 /// <returns>Rotated byte array value</returns>
181- public static byte [ ] RotateLeft ( byte [ ] val , int r_bits )
207+ /// <remarks>Assumes array values are in big-endian format</remarks>
208+ public static byte [ ] RotateLeft ( this byte [ ] self , int numBits )
182209 {
183- byte [ ] output = new byte [ val . Length ] ;
184- Array . Copy ( val , output , output . Length ) ;
210+ // If either input is empty
211+ if ( self . Length == 0 )
212+ return [ ] ;
213+ else if ( numBits == 0 )
214+ return self ;
215+
216+ byte [ ] output = new byte [ self . Length ] ;
217+ Array . Copy ( self , output , output . Length ) ;
185218
186219 // Shift by bytes
187- while ( r_bits >= 8 )
220+ while ( numBits >= 8 )
188221 {
189222 byte temp = output [ 0 ] ;
190223 for ( int i = 0 ; i < output . Length - 1 ; i ++ )
@@ -193,13 +226,13 @@ public static byte[] RotateLeft(byte[] val, int r_bits)
193226 }
194227
195228 output [ output . Length - 1 ] = temp ;
196- r_bits -= 8 ;
229+ numBits -= 8 ;
197230 }
198231
199232 // Shift by bits
200- if ( r_bits > 0 )
233+ if ( numBits > 0 )
201234 {
202- byte bitMask = ( byte ) ( 8 - r_bits ) , carry , wrap = 0 ;
235+ byte bitMask = ( byte ) ( 8 - numBits ) , carry , wrap = 0 ;
203236 for ( int i = 0 ; i < output . Length ; i ++ )
204237 {
205238 carry = ( byte ) ( ( 255 << bitMask & output [ i ] ) >> bitMask ) ;
@@ -213,7 +246,7 @@ public static byte[] RotateLeft(byte[] val, int r_bits)
213246 output [ i - 1 ] |= carry ;
214247
215248 // Shift the current bits
216- output [ i ] <<= r_bits ;
249+ output [ i ] <<= numBits ;
217250 }
218251
219252 // Make sure the wrap happens
@@ -226,24 +259,38 @@ public static byte[] RotateLeft(byte[] val, int r_bits)
226259 /// <summary>
227260 /// XOR two numbers represented by byte arrays
228261 /// </summary>
229- /// <param name="left ">Byte array to XOR to</param>
230- /// <param name="right ">Amount to XOR</param>
262+ /// <param name="self ">Byte array to XOR to</param>
263+ /// <param name="xor ">Amount to XOR</param>
231264 /// <returns>Byte array representing the new value</returns>
232- public static byte [ ] Xor ( byte [ ] left , byte [ ] right )
265+ /// <remarks>Assumes array values are in big-endian format</remarks>
266+ public static byte [ ] Xor ( this byte [ ] self , byte [ ] xor )
233267 {
234- int xorBytes = Math . Min ( left . Length , right . Length ) ;
235- int outLength = Math . Max ( left . Length , right . Length ) ;
236-
268+ // If either input is empty
269+ if ( self . Length == 0 && xor . Length == 0 )
270+ return [ ] ;
271+ else if ( self . Length > 0 && xor . Length == 0 )
272+ return self ;
273+ else if ( self . Length == 0 && xor . Length > 0 )
274+ return xor ;
275+
276+ // Setup the output array
277+ int outLength = Math . Max ( self . Length , xor . Length ) ;
237278 byte [ ] output = new byte [ outLength ] ;
238- for ( int i = 0 ; i < xorBytes ; i ++ )
279+
280+ // Loop XOR
281+ for ( int i = 0 ; i < outLength ; i ++ )
239282 {
240- output [ i ] = ( byte ) ( left [ i ] ^ right [ i ] ) ;
241- }
283+ int selfIndex = self . Length - i - 1 ;
284+ uint selfValue = selfIndex >= 0 ? self [ selfIndex ] : 0u ;
285+
286+ int xorIndex = xor . Length - i - 1 ;
287+ uint xorValue = xorIndex >= 0 ? xor [ xorIndex ] : 0u ;
242288
243- if ( outLength != xorBytes && left . Length == outLength )
244- Array . Copy ( left , xorBytes , output , xorBytes , outLength - xorBytes ) ;
245- else if ( outLength != xorBytes && right . Length == outLength )
246- Array . Copy ( right , xorBytes , output , xorBytes , outLength - xorBytes ) ;
289+ uint next = selfValue ^ xorValue ;
290+
291+ int outputIndex = output . Length - i - 1 ;
292+ output [ outputIndex ] = ( byte ) ( next & 0xFF ) ;
293+ }
247294
248295 return output ;
249296 }
0 commit comments