📄 eccurve.java
字号:
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space
// Source File Name: ECCurve.java
package org.bouncycastle.math.ec;
import java.math.BigInteger;
import java.util.Random;
// Referenced classes of package org.bouncycastle.math.ec:
// ECFieldElement, ECPoint, ECConstants, Tnaf
public abstract class ECCurve
{
public static class F2m extends ECCurve
{
private int m;
private int k1;
private int k2;
private int k3;
private BigInteger n;
private BigInteger h;
private ECPoint.F2m infinity;
private byte mu;
private BigInteger si[];
public int getFieldSize()
{
return m;
}
public ECFieldElement fromBigInteger(BigInteger x)
{
return new ECFieldElement.F2m(m, k1, k2, k3, x);
}
public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
{
return new ECPoint.F2m(this, fromBigInteger(x), fromBigInteger(y), withCompression);
}
public ECPoint decodePoint(byte encoded[])
{
ECPoint p = null;
switch (encoded[0])
{
case 0: // '\0'
p = getInfinity();
break;
case 2: // '\002'
case 3: // '\003'
byte enc[] = new byte[encoded.length - 1];
System.arraycopy(encoded, 1, enc, 0, enc.length);
if (encoded[0] == 2)
p = decompressPoint(enc, 0);
else
p = decompressPoint(enc, 1);
break;
case 4: // '\004'
case 6: // '\006'
case 7: // '\007'
byte xEnc[] = new byte[(encoded.length - 1) / 2];
byte yEnc[] = new byte[(encoded.length - 1) / 2];
System.arraycopy(encoded, 1, xEnc, 0, xEnc.length);
System.arraycopy(encoded, xEnc.length + 1, yEnc, 0, yEnc.length);
p = new ECPoint.F2m(this, new ECFieldElement.F2m(m, k1, k2, k3, new BigInteger(1, xEnc)), new ECFieldElement.F2m(m, k1, k2, k3, new BigInteger(1, yEnc)), false);
break;
case 1: // '\001'
case 5: // '\005'
default:
throw new RuntimeException((new StringBuilder()).append("Invalid point encoding 0x").append(Integer.toString(encoded[0], 16)).toString());
}
return p;
}
public ECPoint getInfinity()
{
return infinity;
}
public boolean isKoblitz()
{
return n != null && h != null && (a.toBigInteger().equals(ECConstants.ZERO) || a.toBigInteger().equals(ECConstants.ONE)) && b.toBigInteger().equals(ECConstants.ONE);
}
synchronized byte getMu()
{
if (mu == 0)
mu = Tnaf.getMu(this);
return mu;
}
synchronized BigInteger[] getSi()
{
if (si == null)
si = Tnaf.getSi(this);
return si;
}
private ECPoint decompressPoint(byte xEnc[], int ypBit)
{
ECFieldElement xp = new ECFieldElement.F2m(m, k1, k2, k3, new BigInteger(1, xEnc));
ECFieldElement yp = null;
if (xp.toBigInteger().equals(ECConstants.ZERO))
{
yp = (ECFieldElement.F2m)b;
for (int i = 0; i < m - 1; i++)
yp = yp.square();
} else
{
ECFieldElement beta = xp.add(a).add(b.multiply(xp.square().invert()));
ECFieldElement z = solveQuadradicEquation(beta);
if (z == null)
throw new RuntimeException("Invalid point compression");
int zBit = 0;
if (z.toBigInteger().testBit(0))
zBit = 1;
if (zBit != ypBit)
z = z.add(new ECFieldElement.F2m(m, k1, k2, k3, ECConstants.ONE));
yp = xp.multiply(z);
}
return new ECPoint.F2m(this, xp, yp);
}
private ECFieldElement solveQuadradicEquation(ECFieldElement beta)
{
ECFieldElement zeroElement = new ECFieldElement.F2m(m, k1, k2, k3, ECConstants.ZERO);
if (beta.toBigInteger().equals(ECConstants.ZERO))
return zeroElement;
ECFieldElement z = null;
ECFieldElement gamma = zeroElement;
Random rand = new Random();
do
{
ECFieldElement t = new ECFieldElement.F2m(m, k1, k2, k3, new BigInteger(m, rand));
z = zeroElement;
ECFieldElement w = beta;
for (int i = 1; i <= m - 1; i++)
{
ECFieldElement w2 = w.square();
z = z.square().add(w2.multiply(t));
w = w2.add(beta);
}
if (!w.toBigInteger().equals(ECConstants.ZERO))
return null;
gamma = z.square().add(z);
} while (gamma.toBigInteger().equals(ECConstants.ZERO));
return z;
}
public boolean equals(Object anObject)
{
if (anObject == this)
return true;
if (!(anObject instanceof F2m))
{
return false;
} else
{
F2m other = (F2m)anObject;
return m == other.m && k1 == other.k1 && k2 == other.k2 && k3 == other.k3 && a.equals(other.a) && b.equals(other.b);
}
}
public int hashCode()
{
return a.hashCode() ^ b.hashCode() ^ m ^ k1 ^ k2 ^ k3;
}
public int getM()
{
return m;
}
public boolean isTrinomial()
{
return k2 == 0 && k3 == 0;
}
public int getK1()
{
return k1;
}
public int getK2()
{
return k2;
}
public int getK3()
{
return k3;
}
public BigInteger getN()
{
return n;
}
public BigInteger getH()
{
return h;
}
public F2m(int m, int k, BigInteger a, BigInteger b)
{
this(m, k, 0, 0, a, b, null, null);
}
public F2m(int m, int k, BigInteger a, BigInteger b, BigInteger n, BigInteger h)
{
this(m, k, 0, 0, a, b, n, h);
}
public F2m(int m, int k1, int k2, int k3, BigInteger a, BigInteger b)
{
this(m, k1, k2, k3, a, b, null, null);
}
public F2m(int m, int k1, int k2, int k3, BigInteger a, BigInteger b, BigInteger n,
BigInteger h)
{
mu = 0;
si = null;
this.m = m;
this.k1 = k1;
this.k2 = k2;
this.k3 = k3;
this.n = n;
this.h = h;
if (k1 == 0)
throw new IllegalArgumentException("k1 must be > 0");
if (k2 == 0)
{
if (k3 != 0)
throw new IllegalArgumentException("k3 must be 0 if k2 == 0");
} else
{
if (k2 <= k1)
throw new IllegalArgumentException("k2 must be > k1");
if (k3 <= k2)
throw new IllegalArgumentException("k3 must be > k2");
}
this.a = fromBigInteger(a);
this.b = fromBigInteger(b);
infinity = new ECPoint.F2m(this, null, null);
}
}
public static class Fp extends ECCurve
{
BigInteger q;
ECPoint.Fp infinity;
public BigInteger getQ()
{
return q;
}
public int getFieldSize()
{
return q.bitLength();
}
public ECFieldElement fromBigInteger(BigInteger x)
{
return new ECFieldElement.Fp(q, x);
}
public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
{
return new ECPoint.Fp(this, fromBigInteger(x), fromBigInteger(y), withCompression);
}
public ECPoint decodePoint(byte encoded[])
{
ECPoint p = null;
switch (encoded[0])
{
case 0: // '\0'
p = getInfinity();
break;
case 2: // '\002'
case 3: // '\003'
int ytilde = encoded[0] & 1;
byte i[] = new byte[encoded.length - 1];
System.arraycopy(encoded, 1, i, 0, i.length);
ECFieldElement x = new ECFieldElement.Fp(q, new BigInteger(1, i));
ECFieldElement alpha = x.multiply(x.square().add(a)).add(b);
ECFieldElement beta = alpha.sqrt();
if (beta == null)
throw new RuntimeException("Invalid point compression");
int bit0 = beta.toBigInteger().testBit(0) ? 1 : 0;
if (bit0 == ytilde)
p = new ECPoint.Fp(this, x, beta, true);
else
p = new ECPoint.Fp(this, x, new ECFieldElement.Fp(q, q.subtract(beta.toBigInteger())), true);
break;
case 4: // '\004'
case 6: // '\006'
case 7: // '\007'
byte xEnc[] = new byte[(encoded.length - 1) / 2];
byte yEnc[] = new byte[(encoded.length - 1) / 2];
System.arraycopy(encoded, 1, xEnc, 0, xEnc.length);
System.arraycopy(encoded, xEnc.length + 1, yEnc, 0, yEnc.length);
p = new ECPoint.Fp(this, new ECFieldElement.Fp(q, new BigInteger(1, xEnc)), new ECFieldElement.Fp(q, new BigInteger(1, yEnc)));
break;
case 1: // '\001'
case 5: // '\005'
default:
throw new RuntimeException((new StringBuilder()).append("Invalid point encoding 0x").append(Integer.toString(encoded[0], 16)).toString());
}
return p;
}
public ECPoint getInfinity()
{
return infinity;
}
public boolean equals(Object anObject)
{
if (anObject == this)
return true;
if (!(anObject instanceof Fp))
{
return false;
} else
{
Fp other = (Fp)anObject;
return q.equals(other.q) && a.equals(other.a) && b.equals(other.b);
}
}
public int hashCode()
{
return a.hashCode() ^ b.hashCode() ^ q.hashCode();
}
public Fp(BigInteger q, BigInteger a, BigInteger b)
{
this.q = q;
this.a = fromBigInteger(a);
this.b = fromBigInteger(b);
infinity = new ECPoint.Fp(this, null, null);
}
}
ECFieldElement a;
ECFieldElement b;
public ECCurve()
{
}
public abstract int getFieldSize();
public abstract ECFieldElement fromBigInteger(BigInteger biginteger);
public abstract ECPoint createPoint(BigInteger biginteger, BigInteger biginteger1, boolean flag);
public abstract ECPoint decodePoint(byte abyte0[]);
public abstract ECPoint getInfinity();
public ECFieldElement getA()
{
return a;
}
public ECFieldElement getB()
{
return b;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -