BigIntegersの代わりにECFieldElementオブジェクトを使用して指数の算術演算を行う方が適切だという印象を受けましたが、テストでは間違った結果になります。Bouncy CastleでのJava - Elliptic Curveフィールドの要素の算術
テストルーチン(JUnitの):
class ArithmeticTest
{
@Test
public void testMultDistributativity_BigInteger()
{
ECPoint g = getG();
for (int i=0; i<100; i++)
{
BigInteger a, b, c;
a = randomIntInField(false);
b = randomIntInField(false);
c = a.add(b);
ECPoint gA = g.multiply(a);
ECPoint gB = g.multiply(b);
ECPoint gC = g.multiply(c);
ECPoint sum = gA.add(gB);
assertEquals(gC, sum);
}
}
@Test
public void testMultDistributativity_ECFieldElement_SmallValues()
{
assertTrue(checkMultDistributativity_ECFieldElement(BigInteger.ONE, BigInteger.TEN));
}
@Test
public void testMultDistributativity_ECFieldElement_RandomValues()
{
BigInteger a, b;
int failureCount=0;
for (int i=0; i<1000; i++)
{
a = randomIntInField(false);
b = randomIntInField(false);
if (!checkMultDistributativity_ECFieldElement(a, b))
failureCount++;
}
assertTrue(failureCount==0, "Failed on " + Integer.toString(failureCount) + " out of 1000 runs.");
}
private boolean checkMultDistributativity_ECFieldElement(BigInteger a, BigInteger b)
{
ECFieldElement fA, fB, fC;
ECPoint gA, gB, gC, sum;
fA = getFieldElement(a);
fB = getFieldElement(b);
fC = fA.add(fB);
gA = getG().multiply(a);
gB = getG().multiply(b);
gC = getG().multiply(fC.toBigInteger());
sum = gA.add(gB);
return gC.equals(sum);
}
testMultDistributativity_BigInteger
とtestMultDistributativity_ECFieldElement_SmallValues
成功するが、そのテストケースの半分にtestMultDistributativity_ECFieldElement_RandomValues
失敗します。
なお、1/2は2つのランダムなフィールド要素がフィールド順序より大きな数になる確率です。私はこれが物事を混乱させる方法を理解していない。
はカーブのロード:
private java.security.spec.EllipticCurve curve;
private org.bouncycastle.math.ec.ECCurve bcCurve;
private ECNamedCurveParameterSpec spec;
private final BigInteger fieldOrder;
private static final int FIELD_ELEMENT_BIT_SIZE = 256;
static {
Security.insertProviderAt(new BouncyCastleProvider(), 1);
}
public ArithmeticTest()
{
spec= ECNamedCurveTable.getParameterSpec("secp256r1");
bcCurve = spec.getCurve();
ECNamedCurveSpec conversionSpec = new ECNamedCurveSpec(spec.getName(), spec.getCurve(), spec.getG(), spec.getN());
curve = conversionSpec.getCurve();
fieldOrder = new BigInteger ("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16);
}
そして、これらは、ヘルパー関数です:
private ECPoint getG()
{
return spec.getG();
}
private ECFieldElement getFieldElement(BigInteger i)
{
return bcCurve.fromBigInteger(i);
}
private randomIntInField(boolean nonzero)
{
final int ARGUMENT_IS_LARGER = -1;
SecureRandom rand = new SecureRandom();
BigInteger result;
int watchDog = 1000;
do {
result = new BigInteger(FIELD_ELEMENT_BIT_SIZE, rand);
if (--watchDog == 0)
throw new RuntimeException("Damn what are the odds?");
}
while (nonzero && result.equals(BigInteger.ZERO) || result.compareTo(fieldOrder)!= ARGUMENT_IS_LARGER);
return result;
}
}
は問題は何とか無作為化からできますか?
['normalize'](http://javadox.com/org.bouncycastle/bcprov-jdk15on/1.53/org/bouncycastle/math/ec/ECPoint.html#normalize--)関数を試してみてください。計算を実行して正しい結果が得られたかどうかを確認した後、 'ECPoint'インスタンスで –
興味深い点、ありがとう! 残念ながら、結果は変わりません。 –
このテストを試したところ、次のようになります。 'public void equals_representationNoSeCuenta(){ ECPoint p = getG()。twice(); ECPoint pNormalized = p.normalize(); assertEquals(pNormalized、p); } ' (申し訳ありませんが、おそらくこれはコードを投稿する最良の方法ではありません) –