[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mcs / class / corlib / System.Security.Cryptography / RC2CryptoServiceProvider.cs
blobc9d3448f716f3103c8fa94eb17ba5b32d6a7bb1b
1 //
2 // System.Security.Cryptography.RC2CryptoServiceProvider.cs
3 //
4 // Authors:
5 // Andrew Birkett (andy@nobugs.org)
6 // Sebastien Pouliot (sebastien@ximian.com)
7 //
8 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Globalization;
32 using System.Runtime.InteropServices;
34 using Mono.Security.Cryptography;
36 namespace System.Security.Cryptography {
38 // References:
39 // a. IETF RFC2286: A Description of the RC2(r) Encryption Algorithm
40 // http://www.ietf.org/rfc/rfc2268.txt
42 internal class RC2Transform : SymmetricTransform {
44 private UInt16 R0, R1, R2, R3; // state
45 private UInt16[] K; // expanded key
46 private int j; // Key indexer
48 public RC2Transform (RC2 rc2Algo, bool encryption, byte[] key, byte[] iv)
49 : base (rc2Algo, encryption, iv)
51 int t1 = rc2Algo.EffectiveKeySize;
52 if (key == null) {
53 key = KeyBuilder.Key (rc2Algo.KeySize >> 3);
54 } else {
55 key = (byte[]) key.Clone ();
56 t1 = Math.Min (t1, key.Length << 3);
59 int t = key.Length;
60 if (!KeySizes.IsLegalKeySize (rc2Algo.LegalKeySizes, (t << 3))) {
61 string msg = Locale.GetText ("Key is too small ({0} bytes), it should be between {1} and {2} bytes long.",
62 t, 5, 16);
63 throw new CryptographicException (msg);
66 // Expand key into a byte array, then convert to word
67 // array since we always access the key in 16bit chunks.
68 byte[] L = new byte [128];
70 int t8 = ((t1 + 7) >> 3); // divide by 8
71 int tm = 255 % (2 << (8 + t1 - (t8 << 3) - 1));
73 for (int i=0; i < t; i++)
74 L [i] = key [i];
75 for (int i=t; i < 128; i++)
76 L [i] = (byte) (pitable [(L [i-1] + L [i-t]) & 0xff]);
78 L [128-t8] = pitable [L [128-t8] & tm];
80 for (int i=127-t8; i >= 0; i--)
81 L [i] = pitable [L [i+1] ^ L [i+t8]];
83 K = new UInt16 [64];
84 int pos = 0;
85 for (int i=0; i < 64; i++)
86 K [i] = (UInt16) (L [pos++] + (L [pos++] << 8));
89 protected override void ECB (byte[] input, byte[] output)
91 // unrolled loop, eliminated mul
92 R0 = (UInt16) (input [0] | (input [1] << 8));
93 R1 = (UInt16) (input [2] | (input [3] << 8));
94 R2 = (UInt16) (input [4] | (input [5] << 8));
95 R3 = (UInt16) (input [6] | (input [7] << 8));
97 if (encrypt) {
98 j = 0;
99 // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix();
100 while (j <= 16) {
101 R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
102 R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
104 R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
105 R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
107 R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
108 R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
110 R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
111 R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
114 // inline Mash(); j == 20
115 R0 += K [R3 & 63];
116 R1 += K [R0 & 63];
117 R2 += K [R1 & 63];
118 R3 += K [R2 & 63];
120 // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix(); Mix();
121 while (j <= 40) {
122 R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
123 R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
125 R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
126 R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
128 R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
129 R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
131 R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
132 R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
135 // inline Mash(); j == 44
136 R0 += K [R3 & 63];
137 R1 += K [R0 & 63];
138 R2 += K [R1 & 63];
139 R3 += K [R2 & 63];
141 // inline, but looped, Mix(); Mix(); Mix(); Mix(); Mix();
142 while (j < 64) {
143 R0 += (UInt16) (K[j++] + (R3 & R2) + ((~R3) & R1));
144 R0 = (UInt16) ((R0 << 1) | (R0 >> 15));
146 R1 += (UInt16) (K[j++] + (R0 & R3) + ((~R0) & R2));
147 R1 = (UInt16) ((R1 << 2) | (R1 >> 14));
149 R2 += (UInt16) (K[j++] + (R1 & R0) + ((~R1) & R3));
150 R2 = (UInt16) ((R2 << 3) | (R2 >> 13));
152 R3 += (UInt16) (K[j++] + (R2 & R1) + ((~R2) & R0));
153 R3 = (UInt16) ((R3 << 5) | (R3 >> 11));
156 else {
157 j = 63;
158 // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix();
159 while (j >= 44) {
160 R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
161 R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
163 R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
164 R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
166 R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
167 R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
169 R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
170 R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
173 // inline RMash();
174 R3 -= K [R2 & 63];
175 R2 -= K [R1 & 63];
176 R1 -= K [R0 & 63];
177 R0 -= K [R3 & 63];
179 // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix(); RMix();
180 while (j >= 20) {
181 R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
182 R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
184 R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
185 R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
187 R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
188 R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
190 R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
191 R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
194 // inline RMash();
195 R3 -= K [R2 & 63];
196 R2 -= K [R1 & 63];
197 R1 -= K [R0 & 63];
198 R0 -= K [R3 & 63];
200 // inline, but looped, RMix(); RMix(); RMix(); RMix(); RMix();
201 while (j >= 0) {
202 R3 = (UInt16) ((R3 >> 5) | (R3 << 11));
203 R3 -= (UInt16) (K[j--] + (R2 & R1) + ((~R2) & R0));
205 R2 = (UInt16) ((R2 >> 3) | (R2 << 13));
206 R2 -= (UInt16) (K[j--] + (R1 & R0) + ((~R1) & R3));
208 R1 = (UInt16) ((R1 >> 2) | (R1 << 14));
209 R1 -= (UInt16) (K[j--] + (R0 & R3) + ((~R0) & R2));
211 R0 = (UInt16) ((R0 >> 1) | (R0 << 15));
212 R0 -= (UInt16) (K[j--] + (R3 & R2) + ((~R3) & R1));
216 // unrolled loop
217 output[0] = (byte) R0;
218 output[1] = (byte) (R0 >> 8);
219 output[2] = (byte) R1;
220 output[3] = (byte) (R1 >> 8);
221 output[4] = (byte) R2;
222 output[5] = (byte) (R2 >> 8);
223 output[6] = (byte) R3;
224 output[7] = (byte) (R3 >> 8);
227 static readonly byte[] pitable = {
228 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed,
229 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
230 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
231 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
232 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13,
233 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
234 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b,
235 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
236 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
237 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
238 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1,
239 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
240 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57,
241 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
242 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
243 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
244 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7,
245 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
246 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74,
247 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
248 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
249 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
250 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a,
251 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
252 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae,
253 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
254 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
255 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
256 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0,
257 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
258 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77,
259 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad