Home | History | Annotate | Download | only in spec
      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