private static BigInteger generatePrivateKey(BigInteger q, SecureRandom random) { // B.1.2 Key Pair Generation by Testing Candidates int minWeight = q.bitLength() >>> 2; for (;;) { // TODO Prefer this method? (change test cases that used fixed random) // B.1.1 Key Pair Generation Using Extra Random Bits // BigInteger x = new BigInteger(q.bitLength() + 64, random).mod(q.subtract(ONE)).add(ONE); BigInteger x = BigIntegers.createRandomInRange(ONE, q.subtract(ONE), random); if (WNafUtil.getNafWeight(x) >= minWeight) { return x; } } }
return generateNaf(k); wnaf = trim(wnaf, length);
static ECPoint implSumOfMultiplies(ECPoint[] ps, ECPointMap pointMap, BigInteger[] ks) { int halfCount = ps.length, fullCount = halfCount << 1; boolean[] negs = new boolean[fullCount]; WNafPreCompInfo[] infos = new WNafPreCompInfo[fullCount]; byte[][] wnafs = new byte[fullCount][]; for (int i = 0; i < halfCount; ++i) { int j0 = i << 1, j1 = j0 + 1; BigInteger kj0 = ks[j0]; negs[j0] = kj0.signum() < 0; kj0 = kj0.abs(); BigInteger kj1 = ks[j1]; negs[j1] = kj1.signum() < 0; kj1 = kj1.abs(); int width = Math.max(2, Math.min(16, WNafUtil.getWindowSize(Math.max(kj0.bitLength(), kj1.bitLength())))); ECPoint P = ps[i], Q = WNafUtil.mapPointWithPrecomp(P, width, true, pointMap); infos[j0] = WNafUtil.getWNafPreCompInfo(P); infos[j1] = WNafUtil.getWNafPreCompInfo(Q); wnafs[j0] = WNafUtil.generateWindowNaf(width, kj0); wnafs[j1] = WNafUtil.generateWindowNaf(width, kj1); } return implSumOfMultiplies(negs, infos, wnafs); }
static ECPoint implSumOfMultiplies(ECPoint[] ps, BigInteger[] ks) { int count = ps.length; boolean[] negs = new boolean[count]; WNafPreCompInfo[] infos = new WNafPreCompInfo[count]; byte[][] wnafs = new byte[count][]; for (int i = 0; i < count; ++i) { BigInteger ki = ks[i]; negs[i] = ki.signum() < 0; ki = ki.abs(); int width = Math.max(2, Math.min(16, WNafUtil.getWindowSize(ki.bitLength()))); infos[i] = WNafUtil.precompute(ps[i], width, true); wnafs[i] = WNafUtil.generateWindowNaf(width, ki); } return implSumOfMultiplies(negs, infos, wnafs); }
WNafPreCompInfo wnafPreCompInfo = WNafUtil.precompute(p, width, true); ECPoint[] preComp = wnafPreCompInfo.getPreComp(); ECPoint[] preCompNeg = wnafPreCompInfo.getPreCompNeg(); int[] wnaf = WNafUtil.generateCompactWindowNaf(width, k);
return generateCompactNaf(k); wnaf = trim(wnaf, length);
WNafPreCompInfo wnafPreCompP = precompute(p, width, includeNegated); WNafPreCompInfo wnafPreCompQ = getWNafPreCompInfo(c.getPreCompInfo(q, PRECOMP_NAME));
protected ECPoint multiplyPositive(ECPoint p, BigInteger k) { int[] naf = WNafUtil.generateCompactNaf(k); ECPoint R0 = p.getCurve().getInfinity(), R1 = p; int zeroes = 0; for (int i = 0; i < naf.length; ++i) { int ni = naf[i]; int digit = ni >> 16; zeroes += ni & 0xFFFF; R1 = R1.timesPow2(zeroes); R0 = R0.add(digit < 0 ? R1.negate() : R1); zeroes = 1; } return R0; } }
public static WNafPreCompInfo precompute(ECPoint p, int width, boolean includeNegated) WNafPreCompInfo wnafPreCompInfo = getWNafPreCompInfo(c.getPreCompInfo(p, PRECOMP_NAME)); preComp = resizeTable(preComp, reqPreCompLen); if (pos < reqPreCompLen) preCompNeg = resizeTable(preCompNeg, reqPreCompLen);
/** * Determine window width to use for a scalar multiplication of the given size. * * @param bits the bit-length of the scalar to multiply by * @return the window size to use */ public static int getWindowSize(int bits) { return getWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS); }
public static WNafPreCompInfo getWNafPreCompInfo(ECPoint p) { return getWNafPreCompInfo(p.getCurve().getPreCompInfo(p, PRECOMP_NAME)); }
static ECPoint implShamirsTrickJsf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) { ECCurve curve = P.getCurve(); ECPoint infinity = curve.getInfinity(); // TODO conjugate co-Z addition (ZADDC) can return both of these ECPoint PaddQ = P.add(Q); ECPoint PsubQ = P.subtract(Q); ECPoint[] points = new ECPoint[]{ Q, PsubQ, P, PaddQ }; curve.normalizeAll(points); ECPoint[] table = new ECPoint[] { points[3].negate(), points[2].negate(), points[1].negate(), points[0].negate(), infinity, points[0], points[1], points[2], points[3] }; byte[] jsf = WNafUtil.generateJSF(k, l); ECPoint R = infinity; int i = jsf.length; while (--i >= 0) { int jsfi = jsf[i]; // NOTE: The shifting ensures the sign is extended correctly int kDigit = ((jsfi << 24) >> 28), lDigit = ((jsfi << 28) >> 28); int index = 4 + (kDigit * 3) + lDigit; R = R.twicePlus(table[index]); } return R; }
final WNafPreCompInfo wnafPreCompP = precompute(p, width, includeNegated);
static ECPoint implSumOfMultiplies(ECPoint[] ps, BigInteger[] ks) { int count = ps.length; boolean[] negs = new boolean[count]; WNafPreCompInfo[] infos = new WNafPreCompInfo[count]; byte[][] wnafs = new byte[count][]; for (int i = 0; i < count; ++i) { BigInteger ki = ks[i]; negs[i] = ki.signum() < 0; ki = ki.abs(); int width = Math.max(2, Math.min(16, WNafUtil.getWindowSize(ki.bitLength()))); infos[i] = WNafUtil.precompute(ps[i], width, true); wnafs[i] = WNafUtil.generateWindowNaf(width, ki); } return implSumOfMultiplies(negs, infos, wnafs); }
WNafPreCompInfo wnafPreCompInfo = WNafUtil.precompute(p, width, true); ECPoint[] preComp = wnafPreCompInfo.getPreComp(); ECPoint[] preCompNeg = wnafPreCompInfo.getPreCompNeg(); int[] wnaf = WNafUtil.generateCompactWindowNaf(width, k);
return generateCompactNaf(k); wnaf = trim(wnaf, length);
protected ECPoint multiplyPositive(ECPoint p, BigInteger k) { int[] naf = WNafUtil.generateCompactNaf(k); ECPoint R0 = p.getCurve().getInfinity(), R1 = p; int zeroes = 0; for (int i = 0; i < naf.length; ++i) { int ni = naf[i]; int digit = ni >> 16; zeroes += ni & 0xFFFF; R1 = R1.timesPow2(zeroes); R0 = R0.add(digit < 0 ? R1.negate() : R1); zeroes = 1; } return R0; } }
/** * Determine window width to use for a scalar multiplication of the given size. * * @param bits the bit-length of the scalar to multiply by * @return the window size to use */ protected int getWindowSize(int bits) { return WNafUtil.getWindowSize(bits); } }
public static WNafPreCompInfo getWNafPreCompInfo(ECPoint p) { return getWNafPreCompInfo(p.getCurve().getPreCompInfo(p, PRECOMP_NAME)); }
static ECPoint implShamirsTrickJsf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) { ECCurve curve = P.getCurve(); ECPoint infinity = curve.getInfinity(); // TODO conjugate co-Z addition (ZADDC) can return both of these ECPoint PaddQ = P.add(Q); ECPoint PsubQ = P.subtract(Q); ECPoint[] points = new ECPoint[]{ Q, PsubQ, P, PaddQ }; curve.normalizeAll(points); ECPoint[] table = new ECPoint[] { points[3].negate(), points[2].negate(), points[1].negate(), points[0].negate(), infinity, points[0], points[1], points[2], points[3] }; byte[] jsf = WNafUtil.generateJSF(k, l); ECPoint R = infinity; int i = jsf.length; while (--i >= 0) { int jsfi = jsf[i]; // NOTE: The shifting ensures the sign is extended correctly int kDigit = ((jsfi << 24) >> 28), lDigit = ((jsfi << 28) >> 28); int index = 4 + (kDigit * 3) + lDigit; R = R.twicePlus(table[index]); } return R; }