2017-08-18 2 views
1

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_BigIntegertestMultDistributativity_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; 

    } 
} 

は問題は何とか無作為化からできますか?

+2

['normalize'](http://javadox.com/org.bouncycastle/bcprov-jdk15on/1.53/org/bouncycastle/math/ec/ECPoint.html#normalize--)関数を試してみてください。計算を実行して正しい結果が得られたかどうかを確認した後、 'ECPoint'インスタンスで –

+0

興味深い点、ありがとう! 残念ながら、結果は変わりません。 –

+0

このテストを試したところ、次のようになります。 'public void equals_representationNoSeCuenta(){ ECPoint p = getG()。twice(); ECPoint pNormalized = p.normalize(); assertEquals(pNormalized、p); } ' (申し訳ありませんが、おそらくこれはコードを投稿する最良の方法ではありません) –

答えて

2

私はECFieldElementを使用して指数に 算術演算を実行することがより適切であるという印象の下にされている の代わりのBigIntegerオブジェクトが、私のテストによると、そうすること 誤った結果が得られます。

いいえ!指数(ECPoint.multiplyへのスカラー引数)は、ECFieldElementを使用して処理されないことが最も確実です。スカラーは、ECCurve.getOrderを介して利用可能なグループ順序をモジュロにして互いに追加する必要があります。

あなたのテストは、フィールドモジュラス(あなたが言うように〜50%)に対して合計fCが減少するといつでも失敗します。

+0

ああ、これは明らかだったはずです!ありがとう。 –

関連する問題