1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.kerberos.shared.crypto.encryption;
21  
22  
23  import java.util.Arrays;
24  
25  import junit.framework.TestCase;
26  
27  
28  /**
29   * Tests the use of "n-folding" using test vectors from RFC 3961,
30   * "Encryption and Checksum Specifications for Kerberos 5."
31   * 
32   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
33   * @version $Rev$, $Date$
34   */
35  public class NFoldTest extends TestCase
36  {
37      /**
38       * Tests an n-fold test vector from RFC 3961.
39       */
40      public void testNFold1()
41      {
42          int n = 64;
43          String passPhrase = "012345";
44  
45          int k = passPhrase.getBytes().length * 8;
46          int lcm = NFold.getLcm( n, k );
47          assertEquals( "LCM", 192, lcm );
48  
49          byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
50  
51          byte[] testVector =
52              { ( byte ) 0xbe, ( byte ) 0x07, ( byte ) 0x26, ( byte ) 0x31, ( byte ) 0x27, ( byte ) 0x6b, ( byte ) 0x19,
53                  ( byte ) 0x55 };
54          assertTrue( Arrays.equals( nFoldValue, testVector ) );
55      }
56  
57  
58      /**
59       * Tests an n-fold test vector from RFC 3961.
60       */
61      public void testNFold2()
62      {
63          int n = 56;
64          String passPhrase = "password";
65  
66          int k = passPhrase.getBytes().length * 8;
67          int lcm = NFold.getLcm( n, k );
68          assertEquals( "LCM", 448, lcm );
69  
70          byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
71  
72          byte[] testVector =
73              { ( byte ) 0x78, ( byte ) 0xa0, ( byte ) 0x7b, ( byte ) 0x6c, ( byte ) 0xaf, ( byte ) 0x85, ( byte ) 0xfa };
74          assertTrue( Arrays.equals( nFoldValue, testVector ) );
75      }
76  
77  
78      /**
79       * Tests an n-fold test vector from RFC 3961.
80       */
81      public void testNFold3()
82      {
83          int n = 64;
84          String passPhrase = "Rough Consensus, and Running Code";
85  
86          int k = passPhrase.getBytes().length * 8;
87          int lcm = NFold.getLcm( n, k );
88          assertEquals( "LCM", 2112, lcm );
89  
90          byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
91  
92          byte[] testVector =
93              { ( byte ) 0xbb, ( byte ) 0x6e, ( byte ) 0xd3, ( byte ) 0x08, ( byte ) 0x70, ( byte ) 0xb7, ( byte ) 0xf0,
94                  ( byte ) 0xe0 };
95          assertTrue( Arrays.equals( nFoldValue, testVector ) );
96      }
97  
98  
99      /**
100      * Tests an n-fold test vector from RFC 3961.
101      */
102     public void testNFold4()
103     {
104         int n = 168;
105         String passPhrase = "password";
106 
107         int k = passPhrase.getBytes().length * 8;
108         int lcm = NFold.getLcm( n, k );
109         assertEquals( "LCM", 1344, lcm );
110 
111         byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
112 
113         byte[] testVector =
114             { ( byte ) 0x59, ( byte ) 0xe4, ( byte ) 0xa8, ( byte ) 0xca, ( byte ) 0x7c, ( byte ) 0x03, ( byte ) 0x85,
115                 ( byte ) 0xc3, ( byte ) 0xc3, ( byte ) 0x7b, ( byte ) 0x3f, ( byte ) 0x6d, ( byte ) 0x20,
116                 ( byte ) 0x00, ( byte ) 0x24, ( byte ) 0x7c, ( byte ) 0xb6, ( byte ) 0xe6, ( byte ) 0xbd,
117                 ( byte ) 0x5b, ( byte ) 0x3e };
118         assertTrue( Arrays.equals( nFoldValue, testVector ) );
119     }
120 
121 
122     /**
123      * Tests an n-fold test vector from RFC 3961.
124      */
125     public void testNFold5()
126     {
127         int n = 192;
128         String passPhrase = "MASSACHVSETTS INSTITVTE OF TECHNOLOGY";
129 
130         int k = passPhrase.getBytes().length * 8;
131         int lcm = NFold.getLcm( n, k );
132         assertEquals( "LCM", 7104, lcm );
133 
134         byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
135 
136         byte[] testVector =
137             { ( byte ) 0xdb, ( byte ) 0x3b, ( byte ) 0x0d, ( byte ) 0x8f, ( byte ) 0x0b, ( byte ) 0x06, ( byte ) 0x1e,
138                 ( byte ) 0x60, ( byte ) 0x32, ( byte ) 0x82, ( byte ) 0xb3, ( byte ) 0x08, ( byte ) 0xa5,
139                 ( byte ) 0x08, ( byte ) 0x41, ( byte ) 0x22, ( byte ) 0x9a, ( byte ) 0xd7, ( byte ) 0x98,
140                 ( byte ) 0xfa, ( byte ) 0xb9, ( byte ) 0x54, ( byte ) 0x0c, ( byte ) 0x1b };
141         assertTrue( Arrays.equals( nFoldValue, testVector ) );
142 
143     }
144 
145 
146     /**
147      * Tests an n-fold test vector from RFC 3961.
148      */
149     public void testNFold6()
150     {
151         int n = 168;
152         String passPhrase = "Q";
153 
154         int k = passPhrase.getBytes().length * 8;
155         int lcm = NFold.getLcm( n, k );
156         assertEquals( "LCM", 168, lcm );
157 
158         byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
159 
160         byte[] testVector =
161             { ( byte ) 0x51, ( byte ) 0x8a, ( byte ) 0x54, ( byte ) 0xa2, ( byte ) 0x15, ( byte ) 0xa8, ( byte ) 0x45,
162                 ( byte ) 0x2a, ( byte ) 0x51, ( byte ) 0x8a, ( byte ) 0x54, ( byte ) 0xa2, ( byte ) 0x15,
163                 ( byte ) 0xa8, ( byte ) 0x45, ( byte ) 0x2a, ( byte ) 0x51, ( byte ) 0x8a, ( byte ) 0x54,
164                 ( byte ) 0xa2, ( byte ) 0x15 };
165         assertTrue( Arrays.equals( nFoldValue, testVector ) );
166     }
167 
168 
169     /**
170      * Tests an n-fold test vector from RFC 3961.
171      */
172     public void testNFold7()
173     {
174         int n = 168;
175         String passPhrase = "ba";
176 
177         int k = passPhrase.getBytes().length * 8;
178         int lcm = NFold.getLcm( n, k );
179         assertEquals( "LCM", 336, lcm );
180 
181         byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
182 
183         byte[] testVector =
184             { ( byte ) 0xfb, ( byte ) 0x25, ( byte ) 0xd5, ( byte ) 0x31, ( byte ) 0xae, ( byte ) 0x89, ( byte ) 0x74,
185                 ( byte ) 0x49, ( byte ) 0x9f, ( byte ) 0x52, ( byte ) 0xfd, ( byte ) 0x92, ( byte ) 0xea,
186                 ( byte ) 0x98, ( byte ) 0x57, ( byte ) 0xc4, ( byte ) 0xba, ( byte ) 0x24, ( byte ) 0xcf,
187                 ( byte ) 0x29, ( byte ) 0x7e };
188         assertTrue( Arrays.equals( nFoldValue, testVector ) );
189     }
190 
191 
192     /**
193      * Tests an n-fold test vector from RFC 3961.
194      */
195     public void testNFoldKerberos64()
196     {
197         int n = 64;
198         String passPhrase = "kerberos";
199 
200         int k = passPhrase.getBytes().length * 8;
201         int lcm = NFold.getLcm( n, k );
202         assertEquals( "LCM", 64, lcm );
203 
204         byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
205 
206         byte[] testVector =
207             { ( byte ) 0x6b, ( byte ) 0x65, ( byte ) 0x72, ( byte ) 0x62, ( byte ) 0x65, ( byte ) 0x72, ( byte ) 0x6f,
208                 ( byte ) 0x73 };
209         assertTrue( Arrays.equals( nFoldValue, testVector ) );
210     }
211 
212 
213     /**
214      * Tests an n-fold test vector from RFC 3961.
215      */
216     public void testNFoldKerberos128()
217     {
218         int n = 128;
219         String passPhrase = "kerberos";
220 
221         int k = passPhrase.getBytes().length * 8;
222         int lcm = NFold.getLcm( n, k );
223         assertEquals( "LCM", 128, lcm );
224 
225         byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
226 
227         byte[] testVector =
228             { ( byte ) 0x6b, ( byte ) 0x65, ( byte ) 0x72, ( byte ) 0x62, ( byte ) 0x65, ( byte ) 0x72, ( byte ) 0x6f,
229                 ( byte ) 0x73, ( byte ) 0x7b, ( byte ) 0x9b, ( byte ) 0x5b, ( byte ) 0x2b, ( byte ) 0x93,
230                 ( byte ) 0x13, ( byte ) 0x2b, ( byte ) 0x93 };
231         assertTrue( Arrays.equals( nFoldValue, testVector ) );
232     }
233 
234 
235     /**
236      * Tests an n-fold test vector from RFC 3961.
237      */
238     public void testNFoldKerberos168()
239     {
240         int n = 168;
241         String passPhrase = "kerberos";
242 
243         int k = passPhrase.getBytes().length * 8;
244         int lcm = NFold.getLcm( n, k );
245         assertEquals( "LCM", 1344, lcm );
246 
247         byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
248 
249         byte[] testVector =
250             { ( byte ) 0x83, ( byte ) 0x72, ( byte ) 0xc2, ( byte ) 0x36, ( byte ) 0x34, ( byte ) 0x4e, ( byte ) 0x5f,
251                 ( byte ) 0x15, ( byte ) 0x50, ( byte ) 0xcd, ( byte ) 0x07, ( byte ) 0x47, ( byte ) 0xe1,
252                 ( byte ) 0x5d, ( byte ) 0x62, ( byte ) 0xca, ( byte ) 0x7a, ( byte ) 0x5a, ( byte ) 0x3b,
253                 ( byte ) 0xce, ( byte ) 0xa4 };
254         assertTrue( Arrays.equals( nFoldValue, testVector ) );
255     }
256 
257 
258     /**
259      * Tests an n-fold test vector from RFC 3961.
260      */
261     public void testNFoldKerberos256()
262     {
263         int n = 256;
264         String passPhrase = "kerberos";
265 
266         int k = passPhrase.getBytes().length * 8;
267         int lcm = NFold.getLcm( n, k );
268         assertEquals( "LCM", 256, lcm );
269 
270         byte[] nFoldValue = NFold.nFold( n, passPhrase.getBytes() );
271 
272         byte[] testVector =
273             { ( byte ) 0x6b, ( byte ) 0x65, ( byte ) 0x72, ( byte ) 0x62, ( byte ) 0x65, ( byte ) 0x72, ( byte ) 0x6f,
274                 ( byte ) 0x73, ( byte ) 0x7b, ( byte ) 0x9b, ( byte ) 0x5b, ( byte ) 0x2b, ( byte ) 0x93,
275                 ( byte ) 0x13, ( byte ) 0x2b, ( byte ) 0x93, ( byte ) 0x5c, ( byte ) 0x9b, ( byte ) 0xdc,
276                 ( byte ) 0xda, ( byte ) 0xd9, ( byte ) 0x5c, ( byte ) 0x98, ( byte ) 0x99, ( byte ) 0xc4,
277                 ( byte ) 0xca, ( byte ) 0xe4, ( byte ) 0xde, ( byte ) 0xe6, ( byte ) 0xd6, ( byte ) 0xca, ( byte ) 0xe4 };
278         assertTrue( Arrays.equals( nFoldValue, testVector ) );
279     }
280 
281 
282     /**
283      * Test one's complement addition (addition with end-around carry).  Note
284      * that for purposes of n-folding, we do not actually complement the
285      * result of the addition.
286      */
287     public void testSum()
288     {
289         byte[] n1 =
290             { ( byte ) 0x86, ( byte ) 0x5E };
291         byte[] n2 =
292             { ( byte ) 0xAC, ( byte ) 0x60 };
293         byte[] n3 =
294             { ( byte ) 0x71, ( byte ) 0x2A };
295         byte[] n4 =
296             { ( byte ) 0x81, ( byte ) 0xB5 };
297 
298         byte[] sum = NFold.sum( n1, n2, n1.length * 8 );
299         sum = NFold.sum( sum, n3, sum.length * 8 );
300         sum = NFold.sum( sum, n4, sum.length * 8 );
301 
302         byte[] result = new byte[]
303             { ( byte ) 0x25, ( byte ) 0x9F };
304         assertTrue( Arrays.equals( sum, result ) );
305     }
306 }