Skip to content

Commit

Permalink
Add automatic EC point validation for decoded points and for multipli…
Browse files Browse the repository at this point in the history
…er outputs.
  • Loading branch information
peterdettman committed Jul 22, 2014
1 parent 8bfd438 commit 5cb2f05
Show file tree
Hide file tree
Showing 26 changed files with 401 additions and 637 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public static ECPoint decodePoint(ECCurve curve, byte[] bytes)
xp = xp.addOne();
}

ECFieldElement yp;
ECFieldElement yp = null;
if (xp.isZero())
{
yp = curve.getB().sqrt();
Expand All @@ -134,15 +134,19 @@ public static ECPoint decodePoint(ECCurve curve, byte[] bytes)
{
ECFieldElement beta = xp.square().invert().multiply(curve.getB()).add(curve.getA()).add(xp);
ECFieldElement z = solveQuadraticEquation(curve, beta);
if (z == null)
if (z != null)
{
throw new RuntimeException("Invalid point compression");
if (!trace(z).equals(k))
{
z = z.addOne();
}
yp = xp.multiply(z);
}
if (!trace(z).equals(k))
{
z = z.addOne();
}
yp = xp.multiply(z);
}

if (yp == null)
{
throw new IllegalArgumentException("Invalid point compression");
}

return curve.createPoint(xp.toBigInteger(), yp.toBigInteger());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ public ECPoint multiply(ECPoint p, BigInteger k)
}

ECPoint positive = multiplyPositive(p, k.abs());
return sign > 0 ? positive : positive.negate();
ECPoint result = sign > 0 ? positive : positive.negate();

/*
* Although the various multipliers ought not to produce invalid output under normal
* circumstances, a final check here is advised to guard against fault attacks.
*/
return ECAlgorithms.validatePoint(result);
}

protected abstract ECPoint multiplyPositive(ECPoint p, BigInteger k);
Expand Down
56 changes: 50 additions & 6 deletions core/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ public static ECPoint sumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
ECEndomorphism endomorphism = c.getEndomorphism();
if (endomorphism instanceof GLVEndomorphism)
{
return implSumOfMultipliesGLV(imported, ks, (GLVEndomorphism)endomorphism);
return ECAlgorithms.validatePoint(implSumOfMultipliesGLV(imported, ks, (GLVEndomorphism)endomorphism));
}

return implSumOfMultiplies(imported, ks);
return ECAlgorithms.validatePoint(implSumOfMultiplies(imported, ks));
}

public static ECPoint sumOfTwoMultiplies(ECPoint P, BigInteger a,
Expand All @@ -70,17 +70,18 @@ public static ECPoint sumOfTwoMultiplies(ECPoint P, BigInteger a,
ECCurve.F2m f2mCurve = (ECCurve.F2m)cp;
if (f2mCurve.isKoblitz())
{
return P.multiply(a).add(Q.multiply(b));
return ECAlgorithms.validatePoint(P.multiply(a).add(Q.multiply(b)));
}
}

ECEndomorphism endomorphism = cp.getEndomorphism();
if (endomorphism instanceof GLVEndomorphism)
{
return implSumOfMultipliesGLV(new ECPoint[]{ P, Q }, new BigInteger[]{ a, b }, (GLVEndomorphism)endomorphism);
return ECAlgorithms.validatePoint(
implSumOfMultipliesGLV(new ECPoint[]{ P, Q }, new BigInteger[]{ a, b }, (GLVEndomorphism)endomorphism));
}

return implShamirsTrickWNaf(P, a, Q, b);
return ECAlgorithms.validatePoint(implShamirsTrickWNaf(P, a, Q, b));
}

/*
Expand Down Expand Up @@ -108,7 +109,7 @@ public static ECPoint shamirsTrick(ECPoint P, BigInteger k,
ECCurve cp = P.getCurve();
Q = importPoint(cp, Q);

return implShamirsTrickJsf(P, k, Q, l);
return ECAlgorithms.validatePoint(implShamirsTrickJsf(P, k, Q, l));
}

public static ECPoint importPoint(ECCurve c, ECPoint p)
Expand Down Expand Up @@ -152,6 +153,49 @@ public static void montgomeryTrick(ECFieldElement[] zs, int off, int len)
zs[off] = u;
}

/**
* Simple shift-and-add multiplication. Serves as reference implementation
* to verify (possibly faster) implementations, and for very small scalars.
*
* @param p
* The point to multiply.
* @param k
* The multiplier.
* @return The result of the point multiplication <code>kP</code>.
*/
public static ECPoint referenceMultiply(ECPoint p, BigInteger k)
{
BigInteger x = k.abs();
ECPoint q = p.getCurve().getInfinity();
int t = x.bitLength();
if (t > 0)
{
if (x.testBit(0))
{
q = p;
}
for (int i = 1; i < t; i++)
{
p = p.twice();
if (x.testBit(i))
{
q = q.add(p);
}
}
}
return k.signum() < 0 ? q.negate() : q;
}

public static ECPoint validatePoint(ECPoint p)
{
if (!p.isValid())
{
throw new IllegalArgumentException("Invalid point");
}

return p;
}

static ECPoint implShamirsTrickJsf(ECPoint P, BigInteger k,
ECPoint Q, BigInteger l)
{
Expand Down
Loading

0 comments on commit 5cb2f05

Please sign in to comment.