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 SecP192K1Field 9 { 10 // 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 11 static final int[] P = new int[]{ 0xFFFFEE37, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; 12 static final int[] PExt = new int[]{ 0x013C4FD1, 0x00002392, 0x00000001, 0x00000000, 0x00000000, 13 0x00000000, 0xFFFFDC6E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; 14 private static final int[] PExtInv = new int[]{ 0xFEC3B02F, 0xFFFFDC6D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 15 0xFFFFFFFF, 0x00002391, 0x00000002 }; 16 private static final int P5 = 0xFFFFFFFF; 17 private static final int PExt11 = 0xFFFFFFFF; 18 private static final int PInv33 = 0x11C9; 19 add(int[] x, int[] y, int[] z)20 public static void add(int[] x, int[] y, int[] z) 21 { 22 int c = Nat192.add(x, y, z); 23 if (c != 0 || (z[5] == P5 && Nat192.gte(z, P))) 24 { 25 Nat.add33To(6, PInv33, z); 26 } 27 } 28 addExt(int[] xx, int[] yy, int[] zz)29 public static void addExt(int[] xx, int[] yy, int[] zz) 30 { 31 int c = Nat.add(12, xx, yy, zz); 32 if (c != 0 || (zz[11] == PExt11 && Nat.gte(12, zz, PExt))) 33 { 34 if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0) 35 { 36 Nat.incAt(12, zz, PExtInv.length); 37 } 38 } 39 } 40 addOne(int[] x, int[] z)41 public static void addOne(int[] x, int[] z) 42 { 43 int c = Nat.inc(6, x, z); 44 if (c != 0 || (z[5] == P5 && Nat192.gte(z, P))) 45 { 46 Nat.add33To(6, PInv33, z); 47 } 48 } 49 fromBigInteger(BigInteger x)50 public static int[] fromBigInteger(BigInteger x) 51 { 52 int[] z = Nat192.fromBigInteger(x); 53 if (z[5] == P5 && Nat192.gte(z, P)) 54 { 55 Nat192.subFrom(P, z); 56 } 57 return z; 58 } 59 half(int[] x, int[] z)60 public static void half(int[] x, int[] z) 61 { 62 if ((x[0] & 1) == 0) 63 { 64 Nat.shiftDownBit(6, x, 0, z); 65 } 66 else 67 { 68 int c = Nat192.add(x, P, z); 69 Nat.shiftDownBit(6, z, c); 70 } 71 } 72 multiply(int[] x, int[] y, int[] z)73 public static void multiply(int[] x, int[] y, int[] z) 74 { 75 int[] tt = Nat192.createExt(); 76 Nat192.mul(x, y, tt); 77 reduce(tt, z); 78 } 79 multiplyAddToExt(int[] x, int[] y, int[] zz)80 public static void multiplyAddToExt(int[] x, int[] y, int[] zz) 81 { 82 int c = Nat192.mulAddTo(x, y, zz); 83 if (c != 0 || (zz[11] == PExt11 && Nat.gte(12, zz, PExt))) 84 { 85 if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0) 86 { 87 Nat.incAt(12, zz, PExtInv.length); 88 } 89 } 90 } 91 negate(int[] x, int[] z)92 public static void negate(int[] x, int[] z) 93 { 94 if (Nat192.isZero(x)) 95 { 96 Nat192.zero(z); 97 } 98 else 99 { 100 Nat192.sub(P, x, z); 101 } 102 } 103 reduce(int[] xx, int[] z)104 public static void reduce(int[] xx, int[] z) 105 { 106 long cc = Nat192.mul33Add(PInv33, xx, 6, xx, 0, z, 0); 107 int c = Nat192.mul33DWordAdd(PInv33, cc, z, 0); 108 109 // assert c == 0L || c == 1L; 110 111 if (c != 0 || (z[5] == P5 && Nat192.gte(z, P))) 112 { 113 Nat.add33To(6, PInv33, z); 114 } 115 } 116 reduce32(int x, int[] z)117 public static void reduce32(int x, int[] z) 118 { 119 if ((x != 0 && Nat192.mul33WordAdd(PInv33, x, z, 0) != 0) 120 || (z[5] == P5 && Nat192.gte(z, P))) 121 { 122 Nat.add33To(6, PInv33, z); 123 } 124 } 125 square(int[] x, int[] z)126 public static void square(int[] x, int[] z) 127 { 128 int[] tt = Nat192.createExt(); 129 Nat192.square(x, tt); 130 reduce(tt, z); 131 } 132 squareN(int[] x, int n, int[] z)133 public static void squareN(int[] x, int n, int[] z) 134 { 135 // assert n > 0; 136 137 int[] tt = Nat192.createExt(); 138 Nat192.square(x, tt); 139 reduce(tt, z); 140 141 while (--n > 0) 142 { 143 Nat192.square(z, tt); 144 reduce(tt, z); 145 } 146 } 147 subtract(int[] x, int[] y, int[] z)148 public static void subtract(int[] x, int[] y, int[] z) 149 { 150 int c = Nat192.sub(x, y, z); 151 if (c != 0) 152 { 153 Nat.sub33From(6, PInv33, z); 154 } 155 } 156 subtractExt(int[] xx, int[] yy, int[] zz)157 public static void subtractExt(int[] xx, int[] yy, int[] zz) 158 { 159 int c = Nat.sub(12, xx, yy, zz); 160 if (c != 0) 161 { 162 if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0) 163 { 164 Nat.decAt(12, zz, PExtInv.length); 165 } 166 } 167 } 168 twice(int[] x, int[] z)169 public static void twice(int[] x, int[] z) 170 { 171 int c = Nat.shiftUpBit(6, x, 0, z); 172 if (c != 0 || (z[5] == P5 && Nat192.gte(z, P))) 173 { 174 Nat.add33To(6, PInv33, z); 175 } 176 } 177 } 178