summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2020-07-04 14:10:35 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2020-07-04 14:10:35 +0700
commit6a08d931d590fe846921e05d21ef614a9ed07d68 (patch)
tree0d7215227e464ace13317e6931c120209e8e6117 /crypto/src
parentMethods for generating random FEs (diff)
downloadBouncyCastle.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.
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/math/ec/ECPoint.cs30
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);
                 }
             }
         }