1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /** 19 * @author Vladimir N. Molotkov 20 * @version $Revision$ 21 */ 22 23 package tests.security.spec; 24 25 import junit.framework.TestCase; 26 27 import java.math.BigInteger; 28 import java.security.spec.ECFieldF2m; 29 import java.util.Arrays; 30 import java.util.Random; 31 32 /** 33 * Tests for <code>ECFieldF2m</code> class fields and methods. 34 * 35 */ 36 public class ECFieldF2mTest extends TestCase { 37 38 /** 39 * Support class for this test. 40 * Encapsulates <code>ECFieldF2m</code> testing 41 * domain parameters. 42 * 43 */ 44 private static final class ECFieldF2mDomainParams { 45 46 /** 47 * <code>NPE</code> reference object of class NullPointerException. 48 * NullPointerException must be thrown by <code>ECFieldF2m</code> 49 * ctors in some circumstances 50 */ 51 static final NullPointerException NPE = new NullPointerException(); 52 /** 53 * <code>IArgE</code> reference object of class IllegalArgumentException. 54 * IllegalArgumentException must be thrown by <code>ECFieldF2m</code> 55 * ctors in some circumstances 56 */ 57 static final IllegalArgumentException IArgE = new IllegalArgumentException(); 58 59 /** 60 * The <code>m</code> parameter for <code>ECFieldF2m</code> 61 * ctor for the current test. 62 */ 63 final int m; 64 /** 65 * The <code>rp</code> parameter for <code>ECFieldF2m</code> 66 * ctor for the current test. 67 */ 68 final BigInteger rp; 69 /** 70 * The <code>ks</code> parameter for <code>ECFieldF2m</code> 71 * ctor for the current test. 72 */ 73 final int[] ks; 74 75 76 /** 77 * Exception expected with this parameters set or <code>null</code> 78 * if no exception expected. 79 */ 80 final Exception x; 81 82 /** 83 * Constructs ECFieldF2mDomainParams 84 * 85 * @param m 86 * @param rp 87 * @param ks 88 * @param expectedException 89 */ 90 ECFieldF2mDomainParams(final int m, 91 final BigInteger rp, 92 final int[] ks, 93 final Exception expectedException) { 94 this.m = m; 95 this.rp = rp; 96 this.ks = ks; 97 this.x = expectedException; 98 } 99 } 100 101 // 102 // Tests 103 // 104 105 /** 106 * Set of parameters used for <code>ECFieldF2m(int)</code> 107 * constructor tests. 108 */ 109 private final ECFieldF2mDomainParams[] intCtorTestParameters = 110 new ECFieldF2mDomainParams[] { 111 // set 0: valid m 112 new ECFieldF2mDomainParams(1, null, null, null), 113 // set 1: valid m 114 new ECFieldF2mDomainParams(Integer.MAX_VALUE, null, null, null), 115 // set 2: invalid m 116 new ECFieldF2mDomainParams(0, null, null, ECFieldF2mDomainParams.IArgE), 117 // set 3: invalid m 118 new ECFieldF2mDomainParams(-1, null, null, ECFieldF2mDomainParams.IArgE) 119 }; 120 121 /** 122 * Tests for constructor <code>ECFieldF2m(int)</code><br> 123 * 124 * Assertion: constructs new <code>ECFieldF2m</code> object 125 * using valid parameter m. 126 * 127 * Assertion: IllegalArgumentException if m is not positive. 128 */ 129 public final void testECFieldF2mint() { 130 for(int i=0; i<intCtorTestParameters.length; i++) { 131 ECFieldF2mDomainParams tp = intCtorTestParameters[i]; 132 try { 133 // perform test 134 new ECFieldF2m(tp.m); 135 136 if (tp.x != null) { 137 // exception has been expected 138 fail(getName() + ", set " + i + 139 " FAILED: expected exception has not been thrown"); 140 } 141 } catch (Exception e){ 142 if (tp.x == null || !e.getClass().isInstance(tp.x)) { 143 // exception: failure 144 // if it has not been expected 145 // or wrong one has been thrown 146 fail(getName() + ", set " + i + 147 " FAILED: unexpected " + e); 148 } 149 } 150 } 151 } 152 153 /** 154 * Set of parameters used for <code>ECFieldF2m(int, int[] ks)</code> 155 * constructor tests. 156 */ 157 private final ECFieldF2mDomainParams[] constructorTestParameters = 158 new ECFieldF2mDomainParams[] { 159 // set 0: valid m and ks - trinomial basis params 160 new ECFieldF2mDomainParams( 161 1999, 162 new BigInteger("57406534763712726211641660058884099201115885104434760023882136841288313069618515692832974315825313495922298231949373138672355948043152766571296567808332659269564994572656140000344389574120022435714463495031743122390807731823194181973658513020233176985452498279081199404472314802811655824768082110985166340672084454492229252801189742403957029450467388250214501358353312915261004066118140645880633941658603299497698209063510889929202021079926591625770444716951045960277478891794836019580040978908928741972740865961716524153209532713803393514722581342474556943840519615081302148762454520131486413662191617"), 163 new int[] {367}, 164 null), 165 // set 1: valid m and ks - pentanomial basis params 166 new ECFieldF2mDomainParams( 167 2000, 168 new BigInteger("114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681364606313754094036473740741389411285817465477407288087941692709593079057904974473325399237449961796178150263073811552931156681807161003582337510008648338765664631815874608789366699668224806907571505750798647855797220056285479869767291137153732790597348308446887230584637235716444920907512810569735"), 169 new int[] {981,2,1}, 170 null), 171 // set 2: valid m, invalid (null) pr, invalid (null) ks 172 new ECFieldF2mDomainParams( 173 1963, 174 null, 175 null, 176 ECFieldF2mDomainParams.NPE), 177 // set 3: valid m, invalid pr, invalid ks - wrong length 178 new ECFieldF2mDomainParams( 179 1963, 180 new BigInteger("114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681364606313754094036473740741389411285817465477407288087941692709593079057904974473325399237449961796178150263073811552931156681807161003582337510008648338765664631815874608789366699668224806907571505750798647855797220056285479869767291137153732790597348308446887230584637235716444920907512810569734"), 181 new int[] {981,2}, 182 ECFieldF2mDomainParams.IArgE), 183 // set 4: valid m, invalid ks - wrong length 184 new ECFieldF2mDomainParams( 185 1963, 186 new BigInteger("5"), 187 new int[] {981,124,2,1}, 188 ECFieldF2mDomainParams.IArgE), 189 // set 5: valid m, invalid ks - wrong value 190 new ECFieldF2mDomainParams( 191 1999, 192 new BigInteger("5"), 193 new int[] {1999}, 194 ECFieldF2mDomainParams.IArgE), 195 // set 6: valid m, invalid ks - wrong value 196 new ECFieldF2mDomainParams( 197 1999, 198 new BigInteger("5"), 199 new int[] {0}, 200 ECFieldF2mDomainParams.IArgE), 201 // set 7: valid m, invalid ks - wrong values 202 new ECFieldF2mDomainParams( 203 2000, 204 new BigInteger("5"), 205 new int[] {2000,2,1}, 206 ECFieldF2mDomainParams.IArgE), 207 // set 8: valid m, invalid ks - wrong values 208 new ECFieldF2mDomainParams( 209 2000, 210 new BigInteger("5"), 211 new int[] {981,2,0}, 212 ECFieldF2mDomainParams.IArgE), 213 // set 9: invalid m 214 new ECFieldF2mDomainParams( 215 -5, 216 new BigInteger("114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681364606313754094036473740741389411285817465477407288087941692709593079057904974473325399237449961796178150263073811552931156681807161003582337510008648338765664631815874608789366699668224806907571505750798647855797220056285479869767291137153732790597348308446887230584637235716444920907512810569735"), 217 new int[] {981,2,1}, 218 ECFieldF2mDomainParams.IArgE), 219 // set 10: valid m, invalid ks - wrong order 220 new ECFieldF2mDomainParams( 221 2000, 222 new BigInteger("5"), 223 new int[] {981,1,2}, 224 ECFieldF2mDomainParams.IArgE), 225 // set 11: valid m, invalid ks - no content 226 new ECFieldF2mDomainParams( 227 2000, 228 new BigInteger("5"), 229 new int[3], 230 ECFieldF2mDomainParams.IArgE), 231 // set 12: valid m, invalid ks - length is 0 232 new ECFieldF2mDomainParams( 233 2000, 234 new BigInteger("0"), 235 new int[0], 236 ECFieldF2mDomainParams.IArgE), 237 }; 238 239 /** 240 * Tests for constructor <code>ECFieldF2m(int m, int[] ks)</code><br> 241 * 242 * Assertion: constructs new <code>ECFieldF2m</code> object 243 * using valid parameters m and rp. ks represents trinomial basis. 244 * 245 * Assertion: constructs new <code>ECFieldF2m</code> object 246 * using valid parameters m and ks. ks represents pentanomial basis. 247 * 248 * Assertion: IllegalArgumentException if m is not positive. 249 * 250 * Assertion: NullPointerException if ks is null. 251 * 252 * Assertion: IllegalArgumentException if ks is invalid. 253 */ 254 public final void testECFieldF2mintintArray() { 255 for(int i=0; i<constructorTestParameters.length; i++) { 256 ECFieldF2mDomainParams tp = constructorTestParameters[i]; 257 try { 258 // perform test 259 ECFieldF2m test = new ECFieldF2m(tp.m, tp.ks); 260 261 if (tp.x != null) { 262 // exception has been expected 263 fail(getName() + ", set " + i + 264 " FAILED: expected exception has not been thrown"); 265 } 266 } catch (Exception e){ 267 if (tp.x == null || !e.getClass().isInstance(tp.x)) { 268 // exception: failure 269 // if it has not been expected 270 // or wrong one has been thrown 271 fail(getName() + ", set " + i + 272 " FAILED: unexpected " + e); 273 } 274 } 275 } 276 } 277 278 /** 279 * Tests for constructor <code>ECFieldF2m(int m, BigInteger rp)</code><br> 280 * 281 * Assertion: constructs new <code>ECFieldF2m</code> object 282 * using valid parameters m and rp. 283 * 284 * Assertion: constructs new <code>ECFieldF2m</code> object 285 * using valid parameters m and rp. 286 * 287 * Assertion: IllegalArgumentException if m is not positive. 288 * 289 * Assertion: NullPointerException if rp is null. 290 * 291 * Assertion: IllegalArgumentException if rp is invalid. 292 */ 293 public final void testECFieldF2mintBigInteger() { 294 for(int i=0; i<constructorTestParameters.length; i++) { 295 ECFieldF2mDomainParams tp = constructorTestParameters[i]; 296 try { 297 // perform test 298 new ECFieldF2m(tp.m, tp.rp); 299 300 if (tp.x != null) { 301 // exception has been expected 302 fail(getName() + ", set " + i + 303 " FAILED: expected exception has not been thrown"); 304 } 305 } catch (Exception e){ 306 if (tp.x == null || !e.getClass().isInstance(tp.x)) { 307 // exception: failure 308 // if it has not been expected 309 // or wrong one has been thrown 310 fail(getName() + ", set " + i + 311 " FAILED: unexpected " + e); 312 } 313 } 314 } 315 } 316 317 /** 318 * Test #1 for <code>hashCode()</code> method.<br> 319 * 320 * Assertion: must return the same value if invoked 321 * repeatedly on the same object. 322 */ 323 public final void testHashCode01() { 324 ECFieldF2m f = new ECFieldF2m(2000); 325 int hc = f.hashCode(); 326 assertTrue(hc == f.hashCode() && 327 hc == f.hashCode() && 328 hc == f.hashCode() && 329 hc == f.hashCode() && 330 hc == f.hashCode() && 331 hc == f.hashCode() && 332 hc == f.hashCode() && 333 hc == f.hashCode()); 334 } 335 336 /** 337 * Test #2 for <code>hashCode()</code> method.<br> 338 * 339 * Assertion: must return the same value if invoked 340 * repeatedly on the same object. 341 */ 342 public final void testHashCode02() { 343 ECFieldF2m f = new ECFieldF2m(2000, new int[] {981, 2, 1}); 344 int hc = f.hashCode(); 345 assertTrue(hc == f.hashCode() && 346 hc == f.hashCode() && 347 hc == f.hashCode() && 348 hc == f.hashCode() && 349 hc == f.hashCode() && 350 hc == f.hashCode() && 351 hc == f.hashCode() && 352 hc == f.hashCode()); 353 } 354 355 /** 356 * Test #3 for <code>hashCode()</code> method.<br> 357 * 358 * Assertion: must return the same value if invoked 359 * on equal (according to the <code>equals(Object)</code> method) objects. 360 */ 361 public final void testHashCode03() { 362 assertTrue(new ECFieldF2m(111).hashCode() == 363 new ECFieldF2m(111).hashCode()); 364 } 365 366 /** 367 * Test #4 for <code>hashCode()</code> method.<br> 368 * 369 * Assertion: must return the same value if invoked 370 * on equal (according to the <code>equals(Object)</code> method) objects. 371 */ 372 public final void testHashCode04() { 373 assertTrue(new ECFieldF2m(2000, new int[] {981, 2, 1}).hashCode() == 374 new ECFieldF2m(2000, new int[] {981, 2, 1}).hashCode()); 375 } 376 377 /** 378 * Test #5 for <code>hashCode()</code> method.<br> 379 * 380 * Assertion: must return the same value if invoked 381 * on equal (according to the <code>equals(Object)</code> method) objects. 382 */ 383 public final void testHashCode05() { 384 assertTrue(new ECFieldF2m(2000, new int[] {981, 2, 1}).hashCode() == 385 new ECFieldF2m(2000, BigInteger.valueOf(0L). 386 setBit(0).setBit(1).setBit(2). 387 setBit(981).setBit(2000)).hashCode()); 388 } 389 390 /** 391 * Test #1 for <code>equals()</code> method.<br> 392 * 393 * Assertion: object equals to itself. 394 */ 395 public final void testEqualsObject01() { 396 ECFieldF2m obj = new ECFieldF2m(1999, new int[] {367}); 397 assertTrue(obj.equals(obj)); 398 } 399 400 /** 401 * Test #2 for <code>equals()</code> method.<br> 402 * 403 * Assertion: normal basis - objects equal if their m are equal. 404 */ 405 public final void testEqualsObject02() { 406 assertTrue(new ECFieldF2m(43).equals(new ECFieldF2m(43))); 407 } 408 409 /** 410 * Test #3 for <code>equals()</code> method.<br> 411 * 412 * Assertion: trinomial basis - objects equal if their m, and rp 413 * are mutually equal. 414 */ 415 public final void testEqualsObject03() { 416 assertTrue(new ECFieldF2m(1999, new int[] {367}).equals( 417 new ECFieldF2m(1999, BigInteger.valueOf(0L). 418 setBit(0).setBit(367).setBit(1999)))); 419 } 420 421 /** 422 * Test #4 for <code>equals()</code> method.<br> 423 * 424 * Assertion: pentanomial basis - objects equal if their m, and rp 425 * are mutually equal. 426 */ 427 public final void testEqualsObject04() { 428 ECFieldF2m f1 = new ECFieldF2m(2000, new int[] {981, 2, 1}); 429 ECFieldF2m f2 = new ECFieldF2m(2000, BigInteger.valueOf(0L). 430 setBit(0).setBit(1).setBit(2). 431 setBit(981).setBit(2000)); 432 assertTrue(f1.equals(f2) && f2.equals(f1)); 433 } 434 435 /** 436 * Test #5 for <code>equals()</code> method.<br> 437 * 438 * Assertion: objects equal if their m, and rp are mutually equal. 439 */ 440 public final void testEqualsObject05() { 441 ECFieldF2m f1 = new ECFieldF2m(2000); 442 ECFieldF2m f2 = new ECFieldF2m(2000, BigInteger.valueOf(0L). 443 setBit(0).setBit(1).setBit(2). 444 setBit(981).setBit(2000)); 445 assertFalse(f1.equals(f2) || f2.equals(f1)); 446 } 447 448 /** 449 * Test #6 for <code>equals(Object obj)</code> method.<br> 450 * 451 * Assertion: returns false if obj is <code>null</code> 452 */ 453 public final void testEqualsObject06() { 454 assertFalse(new ECFieldF2m(2000).equals(null)); 455 } 456 457 /** 458 * Test #7 for <code>equals(Object obj)</code> method.<br> 459 * 460 * Assertion: returns false if obj is not instance of <code>ECFieldF2m</code> 461 */ 462 public final void testEqualsObject07() { 463 assertFalse(new ECFieldF2m(2000).equals(new Object())); 464 } 465 466 /** 467 * Test for <code>getFieldSize()</code> method.<br> 468 * 469 * Assertion: returns m value for <code>ECFieldF2m</code> 470 */ 471 public final void testGetFieldSize() { 472 assertEquals(2000, new ECFieldF2m(2000).getFieldSize()); 473 } 474 475 /** 476 * Test for <code>getM()</code> method.<br> 477 * 478 * Assertion: returns m value for <code>ECFieldF2m</code> 479 */ 480 public final void testGetM() { 481 assertEquals(2000, new ECFieldF2m(2000).getM()); 482 } 483 484 /** 485 * Test #1 for <code>getMidTermsOfReductionPolynomial()</code> method.<br> 486 * 487 * Assertion: returns mid terms of reduction polynomial 488 */ 489 public final void testGetMidTermsOfReductionPolynomial01() { 490 int[] a = new int[] {981,2,1}; 491 int[] b = new ECFieldF2m(2000, 492 BigInteger.valueOf(0L).setBit(0).setBit(1). 493 setBit(2).setBit(981).setBit(2000)). 494 getMidTermsOfReductionPolynomial(); 495 assertTrue(Arrays.equals(a, b)); 496 } 497 498 /** 499 * Test #2 for <code>getMidTermsOfReductionPolynomial()</code> method.<br> 500 * 501 * Assertion: returns null for normal basis 502 */ 503 public final void testGetMidTermsOfReductionPolynomial02() { 504 assertNull(new ECFieldF2m(2000).getMidTermsOfReductionPolynomial()); 505 } 506 507 /** 508 * Test #3 for <code>getMidTermsOfReductionPolynomial()</code> method.<br> 509 * 510 * Assertion: returns mid terms of reduction polynomial 511 */ 512 public final void testGetMidTermsOfReductionPolynomial03() { 513 int[] a = new int[] {367}; 514 int[] b = new ECFieldF2m(1999, a).getMidTermsOfReductionPolynomial(); 515 assertTrue(Arrays.equals(a, b)); 516 } 517 518 /** 519 * Test #1 for <code>getReductionPolynomial()</code> method.<br> 520 * 521 * Assertion: returns reduction polynomial 522 */ 523 public final void testGetReductionPolynomial01() { 524 BigInteger rp = BigInteger.valueOf(0L).setBit(0).setBit(1).setBit(2). 525 setBit(981).setBit(2000); 526 assertTrue(new ECFieldF2m(2000, rp).getReductionPolynomial().equals(rp)); 527 } 528 529 /** 530 * Test #2 for <code>getReductionPolynomial()</code> method.<br> 531 * 532 * Assertion: returns null for normal basis 533 */ 534 public final void testGetReductionPolynomial02() { 535 assertNull(new ECFieldF2m(2000).getReductionPolynomial()); 536 } 537 538 /** 539 * Tests that object state is preserved against modifications 540 * through array reference passed to the constructor. 541 */ 542 public final void testIsStatePreserved01() { 543 // reference array 544 int[] a = new int[] {367}; 545 // reference array copy 546 int[] aCopy = a.clone(); 547 // create obj using copy 548 ECFieldF2m f = new ECFieldF2m(1999, aCopy); 549 // modify copy 550 aCopy[0] = 5; 551 // compare reference with returned array 552 assertTrue(Arrays.equals(a, f.getMidTermsOfReductionPolynomial())); 553 } 554 555 /** 556 * Tests that object state is preserved against 557 * modifications through array reference returned by 558 * <code>getMidTermsOfReductionPolynomial()</code> method. 559 */ 560 public final void testIsStatePreserved02() { 561 // reference array 562 int[] a = new int[] {981,2,1}; 563 // reference array copy 564 int[] aCopy = a.clone(); 565 // create obj using copy 566 ECFieldF2m f = new ECFieldF2m(2000, aCopy); 567 // get array reference and modify returned array 568 f.getMidTermsOfReductionPolynomial()[0] = 1532; 569 // compare reference with returned for the second time array 570 assertTrue(Arrays.equals(a, f.getMidTermsOfReductionPolynomial())); 571 } 572 573 } 574