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