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?
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? –
Point intéressant, merci! Malheureusement, cela ne change pas le résultat. –
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.) –