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