1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.kerberos.shared.crypto.encryption;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public class NFold
38 {
39
40
41
42
43
44
45
46 public static byte[] nFold( int n, byte[] data )
47 {
48 int k = data.length * 8;
49 int lcm = getLcm( n, k );
50 int replicate = lcm / k;
51 byte[] sumBytes = new byte[lcm / 8];
52
53 for ( int i = 0; i < replicate; i++ )
54 {
55 int rotation = 13 * i;
56
57 byte[] temp = rotateRight( data, data.length * 8, rotation );
58
59 for ( int j = 0; j < temp.length; j++ )
60 {
61 sumBytes[j + i * temp.length] = temp[j];
62 }
63 }
64
65 byte[] sum = new byte[n / 8];
66 byte[] nfold = new byte[n / 8];
67
68 for ( int m = 0; m < lcm / n; m++ )
69 {
70 for ( int o = 0; o < n / 8; o++ )
71 {
72 sum[o] = sumBytes[o + ( m * n / 8 )];
73 }
74
75 nfold = sum( nfold, sum, nfold.length * 8 );
76
77 }
78
79 return nfold;
80 }
81
82
83
84
85
86
87
88
89
90 protected static int getLcm( int n1, int n2 )
91 {
92 int temp;
93 int product;
94
95 product = n1 * n2;
96
97 do
98 {
99 if ( n1 < n2 )
100 {
101 temp = n1;
102 n1 = n2;
103 n2 = temp;
104 }
105 n1 = n1 % n2;
106 }
107 while ( n1 != 0 );
108
109 return product / n2;
110 }
111
112
113
114
115
116
117
118
119
120
121 private static byte[] rotateRight( byte[] in, int len, int step )
122 {
123 int numOfBytes = ( len - 1 ) / 8 + 1;
124 byte[] out = new byte[numOfBytes];
125
126 for ( int i = 0; i < len; i++ )
127 {
128 int val = getBit( in, i );
129 setBit( out, ( i + step ) % len, val );
130 }
131 return out;
132 }
133
134
135
136
137
138
139
140
141
142
143
144
145 protected static byte[] sum( byte[] n1, byte[] n2, int len )
146 {
147 int numOfBytes = ( len - 1 ) / 8 + 1;
148 byte[] out = new byte[numOfBytes];
149 int carry = 0;
150
151 for ( int i = len - 1; i > -1; i-- )
152 {
153 int n1b = getBit( n1, i );
154 int n2b = getBit( n2, i );
155
156 int sum = n1b + n2b + carry;
157
158 if ( sum == 0 || sum == 1 )
159 {
160 setBit( out, i, sum );
161 carry = 0;
162 }
163 else if ( sum == 2 )
164 {
165 carry = 1;
166 }
167 else if ( sum == 3 )
168 {
169 setBit( out, i, 1 );
170 carry = 1;
171 }
172 }
173
174 if ( carry == 1 )
175 {
176 byte[] carryArray = new byte[n1.length];
177 carryArray[carryArray.length - 1] = 1;
178 out = sum( out, carryArray, n1.length * 8 );
179 }
180
181 return out;
182 }
183
184
185
186
187
188
189
190
191
192 private static int getBit( byte[] data, int pos )
193 {
194 int posByte = pos / 8;
195 int posBit = pos % 8;
196
197 byte valByte = data[posByte];
198 int valInt = valByte >> ( 8 - ( posBit + 1 ) ) & 0x0001;
199 return valInt;
200 }
201
202
203
204
205
206
207
208
209
210 private static void setBit( byte[] data, int pos, int val )
211 {
212 int posByte = pos / 8;
213 int posBit = pos % 8;
214 byte oldByte = data[posByte];
215 oldByte = ( byte ) ( ( ( 0xFF7F >> posBit ) & oldByte ) & 0x00FF );
216 byte newByte = ( byte ) ( ( val << ( 8 - ( posBit + 1 ) ) ) | oldByte );
217 data[posByte] = newByte;
218 }
219 }