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