diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2020-07-04 14:10:35 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2020-07-04 14:10:35 +0700 |
commit | 6a08d931d590fe846921e05d21ef614a9ed07d68 (patch) | |
tree | 0d7215227e464ace13317e6931c120209e8e6117 | |
parent | Methods for generating random FEs (diff) | |
download | BouncyCastle.NET-ed25519-6a08d931d590fe846921e05d21ef614a9ed07d68.tar.xz |
Blind the inversion when normalizing
- see the paper "Yet another GCD based inversion side-channel affecting ECC implementations" by Nir Drucker and Shay Gueron.
-rw-r--r-- | crypto/src/math/ec/ECPoint.cs | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/crypto/src/math/ec/ECPoint.cs b/crypto/src/math/ec/ECPoint.cs index 6a7c3ecf0..ad1a385ee 100644 --- a/crypto/src/math/ec/ECPoint.cs +++ b/crypto/src/math/ec/ECPoint.cs @@ -1,9 +1,9 @@ using System; using System.Collections; -using System.Diagnostics; using System.Text; using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Math.EC { @@ -12,6 +12,8 @@ namespace Org.BouncyCastle.Math.EC */ public abstract class ECPoint { + private static readonly SecureRandom Random = new SecureRandom(); + protected static ECFieldElement[] EMPTY_ZS = new ECFieldElement[0]; protected static ECFieldElement[] GetInitialZCoords(ECCurve curve) @@ -230,13 +232,29 @@ namespace Org.BouncyCastle.Math.EC } default: { - ECFieldElement Z1 = RawZCoords[0]; - if (Z1.IsOne) - { + ECFieldElement z = RawZCoords[0]; + if (z.IsOne) return this; - } - return Normalize(Z1.Invert()); + if (null == m_curve) + throw new InvalidOperationException("Detached points must be in affine coordinates"); + + /* + * Use blinding to avoid the side-channel leak identified and analyzed in the paper + * "Yet another GCD based inversion side-channel affecting ECC implementations" by Nir + * Drucker and Shay Gueron. + * + * To blind the calculation of z^-1, choose a multiplicative (i.e. non-zero) field + * element 'b' uniformly at random, then calculate the result instead as (z * b)^-1 * b. + * Any side-channel in the implementation of 'inverse' now only leaks information about + * the value (z * b), and no longer reveals information about 'z' itself. + */ + // TODO Add CryptoServicesRegistrar class and use here + //SecureRandom r = CryptoServicesRegistrar.GetSecureRandom(); + SecureRandom r = Random; + ECFieldElement b = m_curve.RandomFieldElementMult(r); + ECFieldElement zInv = z.Multiply(b).Invert().Multiply(b); + return Normalize(zInv); } } } |