From aca28312569e39751d8c926653823d4016718898 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 4 Jul 2020 13:24:19 +0700 Subject: Methods for generating random FEs --- crypto/src/math/ec/ECCurve.cs | 91 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 6 deletions(-) (limited to 'crypto/src/math/ec') diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs index 60fbc887a..7d60e5f99 100644 --- a/crypto/src/math/ec/ECCurve.cs +++ b/crypto/src/math/ec/ECCurve.cs @@ -5,7 +5,7 @@ using Org.BouncyCastle.Math.EC.Abc; using Org.BouncyCastle.Math.EC.Endo; using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Math.Field; -using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Math.EC @@ -99,6 +99,10 @@ namespace Org.BouncyCastle.Math.EC public abstract ECFieldElement FromBigInteger(BigInteger x); public abstract bool IsValidFieldElement(BigInteger x); + public abstract ECFieldElement RandomFieldElement(SecureRandom r); + + public abstract ECFieldElement RandomFieldElementMult(SecureRandom r); + public virtual Config Configure() { return new Config(this, this.m_coord, this.m_endomorphism, this.m_multiplier); @@ -598,6 +602,30 @@ namespace Org.BouncyCastle.Math.EC return x != null && x.SignValue >= 0 && x.CompareTo(Field.Characteristic) < 0; } + public override 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 = Field.Characteristic; + ECFieldElement fe1 = FromBigInteger(ImplRandomFieldElement(r, p)); + ECFieldElement fe2 = FromBigInteger(ImplRandomFieldElement(r, p)); + return fe1.Multiply(fe2); + } + + public override 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 = Field.Characteristic; + ECFieldElement fe1 = FromBigInteger(ImplRandomFieldElementMult(r, p)); + ECFieldElement fe2 = FromBigInteger(ImplRandomFieldElementMult(r, p)); + return fe1.Multiply(fe2); + } + protected override ECPoint DecompressPoint(int yTilde, BigInteger X1) { ECFieldElement x = FromBigInteger(X1); @@ -618,6 +646,28 @@ namespace Org.BouncyCastle.Math.EC return 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.SignValue <= 0 || x.CompareTo(p) >= 0); + return x; + } } /** @@ -793,11 +843,6 @@ namespace Org.BouncyCastle.Math.EC { } - public override bool IsValidFieldElement(BigInteger x) - { - return x != null && x.SignValue >= 0 && x.BitLength <= FieldSize; - } - [Obsolete("Per-point compression property will be removed")] public override ECPoint CreatePoint(BigInteger x, BigInteger y, bool withCompression) { @@ -829,6 +874,29 @@ namespace Org.BouncyCastle.Math.EC return CreateRawPoint(X, Y, withCompression); } + public override bool IsValidFieldElement(BigInteger x) + { + return x != null && x.SignValue >= 0 && x.BitLength <= FieldSize; + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + int m = FieldSize; + return FromBigInteger(BigIntegers.CreateRandomBigInteger(m, r)); + } + + public override 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 = FieldSize; + ECFieldElement fe1 = FromBigInteger(ImplRandomFieldElementMult(r, m)); + ECFieldElement fe2 = FromBigInteger(ImplRandomFieldElementMult(r, m)); + return fe1.Multiply(fe2); + } + protected override ECPoint DecompressPoint(int yTilde, BigInteger X1) { ECFieldElement xp = FromBigInteger(X1), yp = null; @@ -958,6 +1026,17 @@ namespace Org.BouncyCastle.Math.EC return m_order != null && m_cofactor != null && m_b.IsOne && (m_a.IsZero || m_a.IsOne); } } + + private static BigInteger ImplRandomFieldElementMult(SecureRandom r, int m) + { + BigInteger x; + do + { + x = BigIntegers.CreateRandomBigInteger(m, r); + } + while (x.SignValue <= 0); + return x; + } } /** -- cgit 1.4.1