bouncycastle/0001-cve-pre.patch
2021-07-31 17:10:50 +08:00

156 lines
5.5 KiB
Diff

From 744c0dc2958870899d8b604bc3cclalef04db5 Mon Sep 17 00:00:00 2001
From: Peter Dettman <peter.dettman@bouncycastle.org>
Date: Fri, 3 Jul 2020 23:18:22 +0700
Subject: [PATCH] Methods for generating random FEs
---
.../org/bouncycastle/math/ec/ECCurve.java | 90 ++++++++++++++++++-
1 file changed, 86 insertions(+), 4 deletions(-)
diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java b/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java
index 7c10c78..19cbd92 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java
@@ -1,6 +1,7 @@
package org.bouncycastle.math.ec;
import java.math.BigInteger;
+import java.security.SecureRandom;
import java.util.Hashtable;
import java.util.Random;
@@ -107,6 +108,10 @@ protected ECCurve(FiniteField field)
public abstract boolean isValidFieldElement(BigInteger x);
+ public abstract ECFieldElement randomFieldElement(SecureRandom r);
+
+ public abstract ECFieldElement randomFieldElementMult(SecureRandom r);
+
public synchronized Config configure()
{
return new Config(this.coord, this.endomorphism, this.multiplier);
@@ -589,6 +594,30 @@ public boolean isValidFieldElement(BigInteger x)
return x != null && x.signum() >= 0 && x.compareTo(this.getField().getCharacteristic()) < 0;
}
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ BigInteger p = getField().getCharacteristic();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElement(r, p));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElement(r, p));
+ return fe1.multiply(fe2);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ BigInteger p = getField().getCharacteristic();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElementMult(r, p));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElementMult(r, p));
+ return fe1.multiply(fe2);
+ }
+
protected ECPoint decompressPoint(int yTilde, BigInteger X1)
{
ECFieldElement x = this.fromBigInteger(X1);
@@ -611,6 +640,28 @@ protected ECPoint decompressPoint(int yTilde, BigInteger X1)
return this.createRawPoint(x, y, true);
}
+
+ private static BigInteger implRandomFieldElement(SecureRandom r, BigInteger p)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(p.bitLength(), r);
+ }
+ while (x.compareTo(p) >= 0);
+ return x;
+ }
+
+ private static BigInteger implRandomFieldElementMult(SecureRandom r, BigInteger p)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(p.bitLength(), r);
+ }
+ while (x.signum() <= 0 || x.compareTo(p) >= 0);
+ return x;
+ }
}
/**
@@ -790,10 +841,6 @@ protected AbstractF2m(int m, int k1, int k2, int k3)
super(buildField(m, k1, k2, k3));
}
- public boolean isValidFieldElement(BigInteger x)
- {
- return x != null && x.signum() >= 0 && x.bitLength() <= this.getFieldSize();
- }
public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
{
@@ -840,6 +887,30 @@ public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
return this.createRawPoint(X, Y, withCompression);
}
+ public boolean isValidFieldElement(BigInteger x)
+ {
+ return x != null && x.signum() >= 0 && x.bitLength() <= this.getFieldSize();
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int m = getFieldSize();
+ return fromBigInteger(BigIntegers.createRandomBigInteger(m, r));
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ int m = getFieldSize();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElementMult(r, m));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElementMult(r, m));
+ return fe1.multiply(fe2);
+ }
+
+
/**
* Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2).
*
@@ -956,6 +1027,17 @@ public boolean isKoblitz()
{
return this.order != null && this.cofactor != null && this.b.isOne() && (this.a.isZero() || this.a.isOne());
}
+
+ private static BigInteger implRandomFieldElementMult(SecureRandom r, int m)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(m, r);
+ }
+ while (x.signum() <= 0);
+ return x;
+ }
}
/**
--
2.23.0