/Mate20_9_0_0/src/main/java/org/bouncycastle/math/ec/WNafUtil.java

https://github.com/SivanLiu/HwFrameWorkSource · Java · 361 lines · 344 code · 17 blank · 0 comment · 116 complexity · 21995b248e106f381a4f85347448adcb MD5 · raw file

  1. package org.bouncycastle.math.ec;
  2. import java.math.BigInteger;
  3. import org.bouncycastle.asn1.cmp.PKIFailureInfo;
  4. public abstract class WNafUtil {
  5. private static final int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{13, 41, 121, 337, 897, 2305};
  6. private static final byte[] EMPTY_BYTES = new byte[0];
  7. private static final int[] EMPTY_INTS = new int[0];
  8. private static final ECPoint[] EMPTY_POINTS = new ECPoint[0];
  9. public static final String PRECOMP_NAME = "bc_wnaf";
  10. public static int[] generateCompactNaf(BigInteger bigInteger) {
  11. if ((bigInteger.bitLength() >>> 16) != 0) {
  12. throw new IllegalArgumentException("'k' must have bitlength < 2^16");
  13. } else if (bigInteger.signum() == 0) {
  14. return EMPTY_INTS;
  15. } else {
  16. BigInteger add = bigInteger.shiftLeft(1).add(bigInteger);
  17. int bitLength = add.bitLength();
  18. int[] iArr = new int[(bitLength >> 1)];
  19. add = add.xor(bigInteger);
  20. bitLength--;
  21. int i = 0;
  22. int i2 = i;
  23. int i3 = 1;
  24. while (i3 < bitLength) {
  25. if (add.testBit(i3)) {
  26. int i4 = i + 1;
  27. iArr[i] = i2 | ((bigInteger.testBit(i3) ? -1 : 1) << 16);
  28. i3++;
  29. i2 = 1;
  30. i = i4;
  31. } else {
  32. i2++;
  33. }
  34. i3++;
  35. }
  36. int i5 = i + 1;
  37. iArr[i] = PKIFailureInfo.notAuthorized | i2;
  38. if (iArr.length > i5) {
  39. iArr = trim(iArr, i5);
  40. }
  41. return iArr;
  42. }
  43. }
  44. public static int[] generateCompactWindowNaf(int i, BigInteger bigInteger) {
  45. if (i == 2) {
  46. return generateCompactNaf(bigInteger);
  47. }
  48. if (i < 2 || i > 16) {
  49. throw new IllegalArgumentException("'width' must be in the range [2, 16]");
  50. } else if ((bigInteger.bitLength() >>> 16) != 0) {
  51. throw new IllegalArgumentException("'k' must have bitlength < 2^16");
  52. } else if (bigInteger.signum() == 0) {
  53. return EMPTY_INTS;
  54. } else {
  55. int[] iArr = new int[((bigInteger.bitLength() / i) + 1)];
  56. int i2 = 1 << i;
  57. int i3 = i2 - 1;
  58. int i4 = i2 >>> 1;
  59. BigInteger bigInteger2 = bigInteger;
  60. int i5 = 0;
  61. int i6 = i5;
  62. int i7 = i6;
  63. while (i5 <= bigInteger2.bitLength()) {
  64. if (bigInteger2.testBit(i5) == i6) {
  65. i5++;
  66. } else {
  67. bigInteger2 = bigInteger2.shiftRight(i5);
  68. int intValue = bigInteger2.intValue() & i3;
  69. if (i6 == true) {
  70. intValue++;
  71. }
  72. i6 = (intValue & i4) != 0 ? 1 : 0;
  73. if (i6 != 0) {
  74. intValue -= i2;
  75. }
  76. if (i7 > 0) {
  77. i5--;
  78. }
  79. int i8 = i7 + 1;
  80. iArr[i7] = i5 | (intValue << 16);
  81. i5 = i;
  82. i7 = i8;
  83. }
  84. }
  85. if (iArr.length > i7) {
  86. iArr = trim(iArr, i7);
  87. }
  88. return iArr;
  89. }
  90. }
  91. public static byte[] generateJSF(BigInteger bigInteger, BigInteger bigInteger2) {
  92. byte[] bArr = new byte[(Math.max(bigInteger.bitLength(), bigInteger2.bitLength()) + 1)];
  93. BigInteger bigInteger3 = bigInteger;
  94. BigInteger bigInteger4 = bigInteger2;
  95. int i = 0;
  96. int i2 = i;
  97. int i3 = i2;
  98. int i4 = i3;
  99. while (true) {
  100. if ((i | i2) == 0 && bigInteger3.bitLength() <= i3 && bigInteger4.bitLength() <= i3) {
  101. break;
  102. }
  103. int intValue = ((bigInteger3.intValue() >>> i3) + i) & 7;
  104. int intValue2 = ((bigInteger4.intValue() >>> i3) + i2) & 7;
  105. int i5 = intValue & 1;
  106. if (i5 != 0) {
  107. i5 -= intValue & 2;
  108. if (intValue + i5 == 4 && (intValue2 & 3) == 2) {
  109. i5 = -i5;
  110. }
  111. }
  112. int i6 = intValue2 & 1;
  113. if (i6 != 0) {
  114. i6 -= intValue2 & 2;
  115. if (intValue2 + i6 == 4 && (intValue & 3) == 2) {
  116. i6 = -i6;
  117. }
  118. }
  119. if ((i << 1) == 1 + i5) {
  120. i ^= 1;
  121. }
  122. if ((i2 << 1) == 1 + i6) {
  123. i2 ^= 1;
  124. }
  125. i3++;
  126. if (i3 == 30) {
  127. bigInteger3 = bigInteger3.shiftRight(30);
  128. bigInteger4 = bigInteger4.shiftRight(30);
  129. i3 = 0;
  130. }
  131. intValue = i4 + 1;
  132. bArr[i4] = (byte) ((i5 << 4) | (i6 & 15));
  133. i4 = intValue;
  134. }
  135. return bArr.length > i4 ? trim(bArr, i4) : bArr;
  136. }
  137. public static byte[] generateNaf(BigInteger bigInteger) {
  138. if (bigInteger.signum() == 0) {
  139. return EMPTY_BYTES;
  140. }
  141. BigInteger add = bigInteger.shiftLeft(1).add(bigInteger);
  142. int bitLength = add.bitLength() - 1;
  143. byte[] bArr = new byte[bitLength];
  144. add = add.xor(bigInteger);
  145. int i = 1;
  146. while (i < bitLength) {
  147. if (add.testBit(i)) {
  148. bArr[i - 1] = (byte) (bigInteger.testBit(i) ? -1 : 1);
  149. i++;
  150. }
  151. i++;
  152. }
  153. bArr[bitLength - 1] = (byte) 1;
  154. return bArr;
  155. }
  156. public static byte[] generateWindowNaf(int i, BigInteger bigInteger) {
  157. if (i == 2) {
  158. return generateNaf(bigInteger);
  159. }
  160. if (i < 2 || i > 8) {
  161. throw new IllegalArgumentException("'width' must be in the range [2, 8]");
  162. } else if (bigInteger.signum() == 0) {
  163. return EMPTY_BYTES;
  164. } else {
  165. byte[] bArr = new byte[(bigInteger.bitLength() + 1)];
  166. int i2 = 1 << i;
  167. int i3 = i2 - 1;
  168. int i4 = i2 >>> 1;
  169. BigInteger bigInteger2 = bigInteger;
  170. int i5 = 0;
  171. int i6 = i5;
  172. int i7 = i6;
  173. while (i5 <= bigInteger2.bitLength()) {
  174. if (bigInteger2.testBit(i5) == i6) {
  175. i5++;
  176. } else {
  177. bigInteger2 = bigInteger2.shiftRight(i5);
  178. int intValue = bigInteger2.intValue() & i3;
  179. if (i6 == true) {
  180. intValue++;
  181. }
  182. i6 = (intValue & i4) != 0 ? 1 : 0;
  183. if (i6 != 0) {
  184. intValue -= i2;
  185. }
  186. if (i7 > 0) {
  187. i5--;
  188. }
  189. i7 += i5;
  190. i5 = i7 + 1;
  191. bArr[i7] = (byte) intValue;
  192. i7 = i5;
  193. i5 = i;
  194. }
  195. }
  196. if (bArr.length > i7) {
  197. bArr = trim(bArr, i7);
  198. }
  199. return bArr;
  200. }
  201. }
  202. public static int getNafWeight(BigInteger bigInteger) {
  203. return bigInteger.signum() == 0 ? 0 : bigInteger.shiftLeft(1).add(bigInteger).xor(bigInteger).bitCount();
  204. }
  205. public static WNafPreCompInfo getWNafPreCompInfo(ECPoint eCPoint) {
  206. return getWNafPreCompInfo(eCPoint.getCurve().getPreCompInfo(eCPoint, PRECOMP_NAME));
  207. }
  208. public static WNafPreCompInfo getWNafPreCompInfo(PreCompInfo preCompInfo) {
  209. return (preCompInfo == null || !(preCompInfo instanceof WNafPreCompInfo)) ? new WNafPreCompInfo() : (WNafPreCompInfo) preCompInfo;
  210. }
  211. public static int getWindowSize(int i) {
  212. return getWindowSize(i, DEFAULT_WINDOW_SIZE_CUTOFFS);
  213. }
  214. public static int getWindowSize(int i, int[] iArr) {
  215. int i2 = 0;
  216. while (i2 < iArr.length && i >= iArr[i2]) {
  217. i2++;
  218. }
  219. return i2 + 2;
  220. }
  221. public static ECPoint mapPointWithPrecomp(ECPoint eCPoint, int i, boolean z, ECPointMap eCPointMap) {
  222. ECCurve curve = eCPoint.getCurve();
  223. WNafPreCompInfo precompute = precompute(eCPoint, i, z);
  224. eCPoint = eCPointMap.map(eCPoint);
  225. WNafPreCompInfo wNafPreCompInfo = getWNafPreCompInfo(curve.getPreCompInfo(eCPoint, PRECOMP_NAME));
  226. ECPoint twice = precompute.getTwice();
  227. if (twice != null) {
  228. wNafPreCompInfo.setTwice(eCPointMap.map(twice));
  229. }
  230. ECPoint[] preComp = precompute.getPreComp();
  231. ECPoint[] eCPointArr = new ECPoint[preComp.length];
  232. int i2 = 0;
  233. for (int i3 = 0; i3 < preComp.length; i3++) {
  234. eCPointArr[i3] = eCPointMap.map(preComp[i3]);
  235. }
  236. wNafPreCompInfo.setPreComp(eCPointArr);
  237. if (z) {
  238. preComp = new ECPoint[eCPointArr.length];
  239. while (i2 < preComp.length) {
  240. preComp[i2] = eCPointArr[i2].negate();
  241. i2++;
  242. }
  243. wNafPreCompInfo.setPreCompNeg(preComp);
  244. }
  245. curve.setPreCompInfo(eCPoint, PRECOMP_NAME, wNafPreCompInfo);
  246. return eCPoint;
  247. }
  248. public static WNafPreCompInfo precompute(ECPoint eCPoint, int i, boolean z) {
  249. int i2;
  250. ECCurve curve = eCPoint.getCurve();
  251. WNafPreCompInfo wNafPreCompInfo = getWNafPreCompInfo(curve.getPreCompInfo(eCPoint, PRECOMP_NAME));
  252. int i3 = 0;
  253. i = 1 << Math.max(0, i - 2);
  254. ECPoint[] preComp = wNafPreCompInfo.getPreComp();
  255. if (preComp == null) {
  256. preComp = EMPTY_POINTS;
  257. i2 = 0;
  258. } else {
  259. i2 = preComp.length;
  260. }
  261. if (i2 < i) {
  262. preComp = resizeTable(preComp, i);
  263. if (i == 1) {
  264. preComp[0] = eCPoint.normalize();
  265. } else {
  266. int i4;
  267. if (i2 == 0) {
  268. preComp[0] = eCPoint;
  269. i4 = 1;
  270. } else {
  271. i4 = i2;
  272. }
  273. ECFieldElement eCFieldElement = null;
  274. if (i == 2) {
  275. preComp[1] = eCPoint.threeTimes();
  276. } else {
  277. ECPoint twice = wNafPreCompInfo.getTwice();
  278. ECPoint eCPoint2 = preComp[i4 - 1];
  279. if (twice == null) {
  280. twice = preComp[0].twice();
  281. wNafPreCompInfo.setTwice(twice);
  282. if (!twice.isInfinity() && ECAlgorithms.isFpCurve(curve) && curve.getFieldSize() >= 64) {
  283. switch (curve.getCoordinateSystem()) {
  284. case 2:
  285. case 3:
  286. case 4:
  287. eCFieldElement = twice.getZCoord(0);
  288. twice = curve.createPoint(twice.getXCoord().toBigInteger(), twice.getYCoord().toBigInteger());
  289. ECFieldElement square = eCFieldElement.square();
  290. eCPoint2 = eCPoint2.scaleX(square).scaleY(square.multiply(eCFieldElement));
  291. if (i2 == 0) {
  292. preComp[0] = eCPoint2;
  293. break;
  294. }
  295. break;
  296. }
  297. }
  298. }
  299. while (i4 < i) {
  300. int i5 = i4 + 1;
  301. eCPoint2 = eCPoint2.add(twice);
  302. preComp[i4] = eCPoint2;
  303. i4 = i5;
  304. }
  305. }
  306. curve.normalizeAll(preComp, i2, i - i2, eCFieldElement);
  307. }
  308. }
  309. wNafPreCompInfo.setPreComp(preComp);
  310. if (z) {
  311. ECPoint[] preCompNeg = wNafPreCompInfo.getPreCompNeg();
  312. if (preCompNeg == null) {
  313. preCompNeg = new ECPoint[i];
  314. } else {
  315. i3 = preCompNeg.length;
  316. if (i3 < i) {
  317. preCompNeg = resizeTable(preCompNeg, i);
  318. }
  319. }
  320. while (i3 < i) {
  321. preCompNeg[i3] = preComp[i3].negate();
  322. i3++;
  323. }
  324. wNafPreCompInfo.setPreCompNeg(preCompNeg);
  325. }
  326. curve.setPreCompInfo(eCPoint, PRECOMP_NAME, wNafPreCompInfo);
  327. return wNafPreCompInfo;
  328. }
  329. private static ECPoint[] resizeTable(ECPoint[] eCPointArr, int i) {
  330. ECPoint[] eCPointArr2 = new ECPoint[i];
  331. System.arraycopy(eCPointArr, 0, eCPointArr2, 0, eCPointArr.length);
  332. return eCPointArr2;
  333. }
  334. private static byte[] trim(byte[] bArr, int i) {
  335. byte[] bArr2 = new byte[i];
  336. System.arraycopy(bArr, 0, bArr2, 0, bArr2.length);
  337. return bArr2;
  338. }
  339. private static int[] trim(int[] iArr, int i) {
  340. int[] iArr2 = new int[i];
  341. System.arraycopy(iArr, 0, iArr2, 0, iArr2.length);
  342. return iArr2;
  343. }
  344. }