forked from ServiceStack/ServiceStack.Text
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUtils.cs
More file actions
203 lines (161 loc) · 6.33 KB
/
Utils.cs
File metadata and controls
203 lines (161 loc) · 6.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#if SL5 || WP
// From: http://scrypt.codeplex.com/
// License: http://scrypt.codeplex.com/license
using System;
using System.Collections;
namespace ServiceStack
{
static internal class Mathematics
{
/// <summary>
/// Bitwise XOR for 2 byte arrays. Arrays must be the same length.
/// </summary>
/// <param name="t1">Left side for comparison</param>
/// <param name="t2">Right side for comparison</param>
/// <returns>Resulting byte array</returns>
static internal byte[] BitwiseXOR(byte[] t1, byte[] t2)
{
//Inputs need to be the same length for this implementation
if (!(t1.Length == t2.Length))
{
throw new ArgumentException("Input arrays must have the same length");
}
byte[] result = new byte[t1.Length];
byte bytXOR = 0;
for (int i = 0; i <= t1.Length - 1; i++)
{
bytXOR = BitwiseXOR(t1[i], t2[i]);
result[i] = bytXOR;
}
return result;
}
/// <summary>
/// Bitwise XOR for 2 Bytes.
/// </summary>
/// <param name="t1">Left side for comparison</param>
/// <param name="t2">Right side for comparison</param>
/// <returns>Resulting byte</returns>
static internal byte BitwiseXOR(byte t1, byte t2)
{
BitArray baLft = null;
BitArray baRght = null;
BitArray baXor = null;
//Have to use Byte Arrays as the constructor for the BitArray, otherwise the
//integer value of the current byte is used to set the length of the bitArray instead of the value.
byte[] bytL = new byte[1];
byte[] bytR = new byte[1];
bytL[0] = t1;
bytR[0] = t2;
baLft = new BitArray(bytL);
baRght = new BitArray(bytR);
baXor = baLft.Xor(baRght);
byte[] ba2BytArr = new byte[8];
baXor.CopyTo(ba2BytArr, 0);
return ba2BytArr[0];
}
/// <summary>
/// Convert the input Integer to an Octet String.
/// </summary>
/// <param name="x">input integer</param>
/// <param name="size">size in octets (bytes)</param>
/// <returns>Resulting byte array of specified length</returns>
static internal byte[] I2OSP(int x, int size)
{
byte[] bytVal = BitConverter.GetBytes(x);
byte[] result = new byte[size];
Buffer.BlockCopy(bytVal, 0, result, (result.Length - bytVal.Length), bytVal.Length);
Array.Reverse(result);
return result;
}
/// <summary>
/// Mask generation function.
/// </summary>
/// <param name="seed">Seed</param>
/// <param name="maskLen">Length of generated mask</param>
/// <param name="hashLength">Length of the hash produced by the supplied hash provider</param>
/// <param name="hashProvider">Hash provider to use in mask generation</param>
/// <returns>Generated mask of specified length</returns>
static internal byte[] OAEPMGF(byte[] seed, int maskLen, int hashLength, IHashProvider hashProvider)
{
byte[] result = new byte[maskLen];
//Determine how many interations we have to do. We'll be appending
//m_hLen (hash length) bytes for every iteration, so the size of the generated byte array
//will be m_hLen * iNum (number of iterations).
int iNum = (int)Math.Floor(maskLen / hashLength) + 1;
//Mask that will be truncated to create the final
//resulting mask returned by this function.
byte[] bytLongMask = new byte[(iNum * hashLength)];
byte[] bytAppend = new byte[4];
byte[] bytTmp = null;
int iPadLen = 0;
byte[] bytSeedHash = new byte[hashLength];
//Padded pseudorandom seed to be hashed.
byte[] bytPadSeed = new byte[(seed.Length + 4)];
seed.CopyTo(bytPadSeed, 0);
for (int i = 0; i <= iNum - 1; i++)
{
//Convert the iterator to an Octet String byte array
bytTmp = Mathematics.I2OSP(i, 4);
//Calculate the needed padding zeros, and add
//them to the resulting Array. Result must be 4 bytes long.
iPadLen = bytAppend.Length - bytTmp.Length;
bytTmp.CopyTo(bytAppend, 0);
//Hash the pseudorandom padded seed and append it to the
//long version of the mask.
bytAppend.CopyTo(bytPadSeed, seed.Length);
bytSeedHash = hashProvider.ComputeHash(bytPadSeed);
bytSeedHash.CopyTo(bytLongMask, i * hashLength);
}
//Copy the first maskLen bytes of bytLongMask to the result
//and return the result.
Array.Copy(bytLongMask, result, maskLen);
return result;
}
}
static internal class DigestEncoding
{
static internal byte[] SHA1()
{
return new byte[] {
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
};
}
static internal byte[] SHA256()
{
return new byte[] {
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
};
}
static internal byte[] SHA384()
{
return new byte[] {
0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30
};
}
static internal byte[] SHA512()
{
return new byte[] {
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
};
}
static internal byte[] MD2()
{
return new byte[] {
0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10
};
}
static internal byte[] MD5()
{
return new byte[] {
0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
};
}
}
}
#endif