Home | History | Annotate | Download | only in sec
      1 package org.bouncycastle.math.ec.custom.sec;
      2 
      3 import java.math.BigInteger;
      4 
      5 import org.bouncycastle.math.raw.Nat;
      6 import org.bouncycastle.math.raw.Nat192;
      7 
      8 public class SecP192R1Field
      9 {
     10     private static final long M = 0xFFFFFFFFL;
     11 
     12     // 2^192 - 2^64 - 1
     13     static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
     14     static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001,
     15         0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
     16     private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFE,
     17         0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000002 };
     18     private static final int P5 = 0xFFFFFFFF;
     19     private static final int PExt11 = 0xFFFFFFFF;
     20 
     21     public static void add(int[] x, int[] y, int[] z)
     22     {
     23         int c = Nat192.add(x, y, z);
     24         if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
     25         {
     26             addPInvTo(z);
     27         }
     28     }
     29 
     30     public static void addExt(int[] xx, int[] yy, int[] zz)
     31     {
     32         int c = Nat.add(12, xx, yy, zz);
     33         if (c != 0 || (zz[11] == PExt11 && Nat.gte(12, zz, PExt)))
     34         {
     35             if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
     36             {
     37                 Nat.incAt(12, zz, PExtInv.length);
     38             }
     39         }
     40     }
     41 
     42     public static void addOne(int[] x, int[] z)
     43     {
     44         int c = Nat.inc(6, x, z);
     45         if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
     46         {
     47             addPInvTo(z);
     48         }
     49     }
     50 
     51     public static int[] fromBigInteger(BigInteger x)
     52     {
     53         int[] z = Nat192.fromBigInteger(x);
     54         if (z[5] == P5 && Nat192.gte(z, P))
     55         {
     56             Nat192.subFrom(P, z);
     57         }
     58         return z;
     59     }
     60 
     61     public static void half(int[] x, int[] z)
     62     {
     63         if ((x[0] & 1) == 0)
     64         {
     65             Nat.shiftDownBit(6, x, 0, z);
     66         }
     67         else
     68         {
     69             int c = Nat192.add(x, P, z);
     70             Nat.shiftDownBit(6, z, c);
     71         }
     72     }
     73 
     74     public static void multiply(int[] x, int[] y, int[] z)
     75     {
     76         int[] tt = Nat192.createExt();
     77         Nat192.mul(x, y, tt);
     78         reduce(tt, z);
     79     }
     80 
     81     public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
     82     {
     83         int c = Nat192.mulAddTo(x, y, zz);
     84         if (c != 0 || (zz[11] == PExt11 && Nat.gte(12, zz, PExt)))
     85         {
     86             if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
     87             {
     88                 Nat.incAt(12, zz, PExtInv.length);
     89             }
     90         }
     91     }
     92 
     93     public static void negate(int[] x, int[] z)
     94     {
     95         if (Nat192.isZero(x))
     96         {
     97             Nat192.zero(z);
     98         }
     99         else
    100         {
    101             Nat192.sub(P, x, z);
    102         }
    103     }
    104 
    105     public static void reduce(int[] xx, int[] z)
    106     {
    107         long xx06 = xx[6] & M, xx07 = xx[7] & M, xx08 = xx[8] & M;
    108         long xx09 = xx[9] & M, xx10 = xx[10] & M, xx11 = xx[11] & M;
    109 
    110         long t0 = xx06 + xx10;
    111         long t1 = xx07 + xx11;
    112 
    113         long cc = 0;
    114         cc += (xx[0] & M) + t0;
    115         int z0 = (int)cc;
    116         cc >>= 32;
    117         cc += (xx[1] & M) + t1;
    118         z[1] = (int)cc;
    119         cc >>= 32;
    120 
    121         t0 += xx08;
    122         t1 += xx09;
    123 
    124         cc += (xx[2] & M) + t0;
    125         long z2 = cc & M;
    126         cc >>= 32;
    127         cc += (xx[3] & M) + t1;
    128         z[3] = (int)cc;
    129         cc >>= 32;
    130 
    131         t0 -= xx06;
    132         t1 -= xx07;
    133 
    134         cc += (xx[4] & M) + t0;
    135         z[4] = (int)cc;
    136         cc >>= 32;
    137         cc += (xx[5] & M) + t1;
    138         z[5] = (int)cc;
    139         cc >>= 32;
    140 
    141         z2 += cc;
    142 
    143         cc += (z0 & M);
    144         z[0] = (int)cc;
    145         cc >>= 32;
    146         if (cc != 0)
    147         {
    148             cc += (z[1] & M);
    149             z[1] = (int)cc;
    150             z2 += cc >> 32;
    151         }
    152         z[2] = (int)z2;
    153         cc = z2 >> 32;
    154 
    155 //      assert cc == 0 || cc == 1;
    156 
    157         if ((cc != 0 && Nat.incAt(6, z, 3) != 0)
    158             || (z[5] == P5 && Nat192.gte(z, P)))
    159         {
    160             addPInvTo(z);
    161         }
    162     }
    163 
    164     public static void reduce32(int x, int[] z)
    165     {
    166         long cc = 0;
    167 
    168         if (x != 0)
    169         {
    170             long xx06 = x & M;
    171 
    172             cc += (z[0] & M) + xx06;
    173             z[0] = (int)cc;
    174             cc >>= 32;
    175             if (cc != 0)
    176             {
    177                 cc += (z[1] & M);
    178                 z[1] = (int)cc;
    179                 cc >>= 32;
    180             }
    181             cc += (z[2] & M) + xx06;
    182             z[2] = (int)cc;
    183             cc >>= 32;
    184 
    185 //            assert cc == 0 || cc == 1;
    186         }
    187 
    188         if ((cc != 0 && Nat.incAt(6, z, 3) != 0)
    189             || (z[5] == P5 && Nat192.gte(z, P)))
    190         {
    191             addPInvTo(z);
    192         }
    193     }
    194 
    195     public static void square(int[] x, int[] z)
    196     {
    197         int[] tt = Nat192.createExt();
    198         Nat192.square(x, tt);
    199         reduce(tt, z);
    200     }
    201 
    202     public static void squareN(int[] x, int n, int[] z)
    203     {
    204 //        assert n > 0;
    205 
    206         int[] tt = Nat192.createExt();
    207         Nat192.square(x, tt);
    208         reduce(tt, z);
    209 
    210         while (--n > 0)
    211         {
    212             Nat192.square(z, tt);
    213             reduce(tt, z);
    214         }
    215     }
    216 
    217     public static void subtract(int[] x, int[] y, int[] z)
    218     {
    219         int c = Nat192.sub(x, y, z);
    220         if (c != 0)
    221         {
    222             subPInvFrom(z);
    223         }
    224     }
    225 
    226     public static void subtractExt(int[] xx, int[] yy, int[] zz)
    227     {
    228         int c = Nat.sub(12, xx, yy, zz);
    229         if (c != 0)
    230         {
    231             if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0)
    232             {
    233                 Nat.decAt(12, zz, PExtInv.length);
    234             }
    235         }
    236     }
    237 
    238     public static void twice(int[] x, int[] z)
    239     {
    240         int c = Nat.shiftUpBit(6, x, 0, z);
    241         if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
    242         {
    243             addPInvTo(z);
    244         }
    245     }
    246 
    247     private static void addPInvTo(int[] z)
    248     {
    249         long c = (z[0] & M) + 1;
    250         z[0] = (int)c;
    251         c >>= 32;
    252         if (c != 0)
    253         {
    254             c += (z[1] & M);
    255             z[1] = (int)c;
    256             c >>= 32;
    257         }
    258         c += (z[2] & M) + 1;
    259         z[2] = (int)c;
    260         c >>= 32;
    261         if (c != 0)
    262         {
    263             Nat.incAt(6, z, 3);
    264         }
    265     }
    266 
    267     private static void subPInvFrom(int[] z)
    268     {
    269         long c = (z[0] & M) - 1;
    270         z[0] = (int)c;
    271         c >>= 32;
    272         if (c != 0)
    273         {
    274             c += (z[1] & M);
    275             z[1] = (int)c;
    276             c >>= 32;
    277         }
    278         c += (z[2] & M) - 1;
    279         z[2] = (int)c;
    280         c >>= 32;
    281         if (c != 0)
    282         {
    283             Nat.decAt(6, z, 3);
    284         }
    285     }
    286 }
    287