Home | History | Annotate | Download | only in sec
      1 package org.bouncycastle.math.ec.custom.sec;
      2 
      3 import org.bouncycastle.math.ec.ECCurve;
      4 import org.bouncycastle.math.ec.ECFieldElement;
      5 import org.bouncycastle.math.ec.ECPoint;
      6 import org.bouncycastle.math.raw.Nat;
      7 import org.bouncycastle.math.raw.Nat192;
      8 
      9 public class SecP192R1Point extends ECPoint.AbstractFp
     10 {
     11     /**
     12      * Create a point which encodes with point compression.
     13      *
     14      * @param curve
     15      *            the curve to use
     16      * @param x
     17      *            affine x co-ordinate
     18      * @param y
     19      *            affine y co-ordinate
     20      *
     21      * @deprecated Use ECCurve.createPoint to construct points
     22      */
     23     public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
     24     {
     25         this(curve, x, y, false);
     26     }
     27 
     28     /**
     29      * Create a point that encodes with or without point compresion.
     30      *
     31      * @param curve
     32      *            the curve to use
     33      * @param x
     34      *            affine x co-ordinate
     35      * @param y
     36      *            affine y co-ordinate
     37      * @param withCompression
     38      *            if true encode with point compression
     39      *
     40      * @deprecated per-point compression property will be removed, refer
     41      *             {@link #getEncoded(boolean)}
     42      */
     43     public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
     44     {
     45         super(curve, x, y);
     46 
     47         if ((x == null) != (y == null))
     48         {
     49             throw new IllegalArgumentException("Exactly one of the field elements is null");
     50         }
     51 
     52         this.withCompression = withCompression;
     53     }
     54 
     55     SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
     56     {
     57         super(curve, x, y, zs);
     58 
     59         this.withCompression = withCompression;
     60     }
     61 
     62     protected ECPoint detach()
     63     {
     64         return new SecP192R1Point(null, getAffineXCoord(), getAffineYCoord());
     65     }
     66 
     67     // B.3 pg 62
     68     public ECPoint add(ECPoint b)
     69     {
     70         if (this.isInfinity())
     71         {
     72             return b;
     73         }
     74         if (b.isInfinity())
     75         {
     76             return this;
     77         }
     78         if (this == b)
     79         {
     80             return twice();
     81         }
     82 
     83         ECCurve curve = this.getCurve();
     84 
     85         SecP192R1FieldElement X1 = (SecP192R1FieldElement)this.x, Y1 = (SecP192R1FieldElement)this.y;
     86         SecP192R1FieldElement X2 = (SecP192R1FieldElement)b.getXCoord(), Y2 = (SecP192R1FieldElement)b.getYCoord();
     87 
     88         SecP192R1FieldElement Z1 = (SecP192R1FieldElement)this.zs[0];
     89         SecP192R1FieldElement Z2 = (SecP192R1FieldElement)b.getZCoord(0);
     90 
     91         int c;
     92         int[] tt1 = Nat192.createExt();
     93         int[] t2 = Nat192.create();
     94         int[] t3 = Nat192.create();
     95         int[] t4 = Nat192.create();
     96 
     97         boolean Z1IsOne = Z1.isOne();
     98         int[] U2, S2;
     99         if (Z1IsOne)
    100         {
    101             U2 = X2.x;
    102             S2 = Y2.x;
    103         }
    104         else
    105         {
    106             S2 = t3;
    107             SecP192R1Field.square(Z1.x, S2);
    108 
    109             U2 = t2;
    110             SecP192R1Field.multiply(S2, X2.x, U2);
    111 
    112             SecP192R1Field.multiply(S2, Z1.x, S2);
    113             SecP192R1Field.multiply(S2, Y2.x, S2);
    114         }
    115 
    116         boolean Z2IsOne = Z2.isOne();
    117         int[] U1, S1;
    118         if (Z2IsOne)
    119         {
    120             U1 = X1.x;
    121             S1 = Y1.x;
    122         }
    123         else
    124         {
    125             S1 = t4;
    126             SecP192R1Field.square(Z2.x, S1);
    127 
    128             U1 = tt1;
    129             SecP192R1Field.multiply(S1, X1.x, U1);
    130 
    131             SecP192R1Field.multiply(S1, Z2.x, S1);
    132             SecP192R1Field.multiply(S1, Y1.x, S1);
    133         }
    134 
    135         int[] H = Nat192.create();
    136         SecP192R1Field.subtract(U1, U2, H);
    137 
    138         int[] R = t2;
    139         SecP192R1Field.subtract(S1, S2, R);
    140 
    141         // Check if b == this or b == -this
    142         if (Nat192.isZero(H))
    143         {
    144             if (Nat192.isZero(R))
    145             {
    146                 // this == b, i.e. this must be doubled
    147                 return this.twice();
    148             }
    149 
    150             // this == -b, i.e. the result is the point at infinity
    151             return curve.getInfinity();
    152         }
    153 
    154         int[] HSquared = t3;
    155         SecP192R1Field.square(H, HSquared);
    156 
    157         int[] G = Nat192.create();
    158         SecP192R1Field.multiply(HSquared, H, G);
    159 
    160         int[] V = t3;
    161         SecP192R1Field.multiply(HSquared, U1, V);
    162 
    163         SecP192R1Field.negate(G, G);
    164         Nat192.mul(S1, G, tt1);
    165 
    166         c = Nat192.addBothTo(V, V, G);
    167         SecP192R1Field.reduce32(c, G);
    168 
    169         SecP192R1FieldElement X3 = new SecP192R1FieldElement(t4);
    170         SecP192R1Field.square(R, X3.x);
    171         SecP192R1Field.subtract(X3.x, G, X3.x);
    172 
    173         SecP192R1FieldElement Y3 = new SecP192R1FieldElement(G);
    174         SecP192R1Field.subtract(V, X3.x, Y3.x);
    175         SecP192R1Field.multiplyAddToExt(Y3.x, R, tt1);
    176         SecP192R1Field.reduce(tt1, Y3.x);
    177 
    178         SecP192R1FieldElement Z3 = new SecP192R1FieldElement(H);
    179         if (!Z1IsOne)
    180         {
    181             SecP192R1Field.multiply(Z3.x, Z1.x, Z3.x);
    182         }
    183         if (!Z2IsOne)
    184         {
    185             SecP192R1Field.multiply(Z3.x, Z2.x, Z3.x);
    186         }
    187 
    188         ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
    189 
    190         return new SecP192R1Point(curve, X3, Y3, zs, this.withCompression);
    191     }
    192 
    193     // B.3 pg 62
    194     public ECPoint twice()
    195     {
    196         if (this.isInfinity())
    197         {
    198             return this;
    199         }
    200 
    201         ECCurve curve = this.getCurve();
    202 
    203         SecP192R1FieldElement Y1 = (SecP192R1FieldElement)this.y;
    204         if (Y1.isZero())
    205         {
    206             return curve.getInfinity();
    207         }
    208 
    209         SecP192R1FieldElement X1 = (SecP192R1FieldElement)this.x, Z1 = (SecP192R1FieldElement)this.zs[0];
    210 
    211         int c;
    212         int[] t1 = Nat192.create();
    213         int[] t2 = Nat192.create();
    214 
    215         int[] Y1Squared = Nat192.create();
    216         SecP192R1Field.square(Y1.x, Y1Squared);
    217 
    218         int[] T = Nat192.create();
    219         SecP192R1Field.square(Y1Squared, T);
    220 
    221         boolean Z1IsOne = Z1.isOne();
    222 
    223         int[] Z1Squared = Z1.x;
    224         if (!Z1IsOne)
    225         {
    226             Z1Squared = t2;
    227             SecP192R1Field.square(Z1.x, Z1Squared);
    228         }
    229 
    230         SecP192R1Field.subtract(X1.x, Z1Squared, t1);
    231 
    232         int[] M = t2;
    233         SecP192R1Field.add(X1.x, Z1Squared, M);
    234         SecP192R1Field.multiply(M, t1, M);
    235         c = Nat192.addBothTo(M, M, M);
    236         SecP192R1Field.reduce32(c, M);
    237 
    238         int[] S = Y1Squared;
    239         SecP192R1Field.multiply(Y1Squared, X1.x, S);
    240         c = Nat.shiftUpBits(6, S, 2, 0);
    241         SecP192R1Field.reduce32(c, S);
    242 
    243         c = Nat.shiftUpBits(6, T, 3, 0, t1);
    244         SecP192R1Field.reduce32(c, t1);
    245 
    246         SecP192R1FieldElement X3 = new SecP192R1FieldElement(T);
    247         SecP192R1Field.square(M, X3.x);
    248         SecP192R1Field.subtract(X3.x, S, X3.x);
    249         SecP192R1Field.subtract(X3.x, S, X3.x);
    250 
    251         SecP192R1FieldElement Y3 = new SecP192R1FieldElement(S);
    252         SecP192R1Field.subtract(S, X3.x, Y3.x);
    253         SecP192R1Field.multiply(Y3.x, M, Y3.x);
    254         SecP192R1Field.subtract(Y3.x, t1, Y3.x);
    255 
    256         SecP192R1FieldElement Z3 = new SecP192R1FieldElement(M);
    257         SecP192R1Field.twice(Y1.x, Z3.x);
    258         if (!Z1IsOne)
    259         {
    260             SecP192R1Field.multiply(Z3.x, Z1.x, Z3.x);
    261         }
    262 
    263         return new SecP192R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
    264     }
    265 
    266     public ECPoint twicePlus(ECPoint b)
    267     {
    268         if (this == b)
    269         {
    270             return threeTimes();
    271         }
    272         if (this.isInfinity())
    273         {
    274             return b;
    275         }
    276         if (b.isInfinity())
    277         {
    278             return twice();
    279         }
    280 
    281         ECFieldElement Y1 = this.y;
    282         if (Y1.isZero())
    283         {
    284             return b;
    285         }
    286 
    287         return twice().add(b);
    288     }
    289 
    290     public ECPoint threeTimes()
    291     {
    292         if (this.isInfinity() || this.y.isZero())
    293         {
    294             return this;
    295         }
    296 
    297         // NOTE: Be careful about recursions between twicePlus and threeTimes
    298         return twice().add(this);
    299     }
    300 
    301     public ECPoint negate()
    302     {
    303         if (this.isInfinity())
    304         {
    305             return this;
    306         }
    307 
    308         return new SecP192R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
    309     }
    310 }
    311