156 lines
5.5 KiB
Diff
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
|
|
|