2017-08-18 4 views
1

J'ai l'impression qu'il est plus approprié d'effectuer des opérations arithmétiques sur les exposants en utilisant des objets ECFieldElement au lieu de BigIntegers, mais selon mes tests, cela donne des résultats incorrects.Java - Arithmétique des éléments de champ de la courbe elliptique dans Bouncy Castle

test Routines (__gVirt_NP_NN_NNPS<__ 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 et testMultDistributativity_ECFieldElement_SmallValues réussir, mais testMultDistributativity_ECFieldElement_RandomValues échoue sur la moitié de ses cas de test. Par ailleurs, 1/2 est la probabilité que deux éléments de champ aléatoire totalisent un nombre supérieur à l'ordre du champ. Je ne comprends pas comment cela peut gâcher les choses si.

Chargement de la courbe:

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); 
    } 

Et ce sont les fonctions d'aide:

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; 

    } 
} 

Le problème peut-être de la randomisation en quelque sorte?

+2

Pourriez-vous essayer et exécuter la fonction ['normalize'] (http://javadox.com/org.bouncycastle/bcprov-jdk15on/1.53/org/bouncycastle/math/ec/ECPoint.html#normalize--) sur les instances 'ECPoint' après avoir effectué les calculs et voir si vous obtenez les bons résultats? –

+0

Point intéressant, merci! Malheureusement, cela ne change pas le résultat. –

+0

Juste essayé ce test, il passe: 'public void equals_representationNoSeCuenta() { ECPoint p = getG(). Deux fois(); ECPoint pNormalized = p.normalize(); assertEquals (pNormalisé, p); } ' (Désolé ce n'est probablement pas la meilleure façon de poster du code.) –

Répondre

2

Je suis sous l'impression qu'il est plus approprié d'effectuer des opérations arithmétiques sur exposants utilisant des objets ECFieldElement au lieu de BigIntegers, mais selon mes tests, faisant cède des résultats incorrects.

Non! Les exposants (les arguments scalaires à ECPoint.multiply) ne doivent absolument pas être manipulés en utilisant ECFieldElement. Les scalaires doivent être ajoutés les uns aux autres modulo l'ordre de groupe, qui est disponible via ECCurve.getOrder.

Votre test échoue donc à chaque fois que la somme fC est réduite par rapport au module de champ (~ 50% comme vous le dites).

+0

Oh mon dieu, cela aurait dû être évident! Merci. –