From 87ab5d8470829879219e50213912bab6b1ab8fe8 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 4 Jul 2020 00:09:03 +0700 Subject: [PATCH] Blind the inversion when normalizing - see the paper "Yet another GCD based inversion side-channel affecting ECC implementations" by Nir Drucker and Shay Gueron. --- .../org/bouncycastle/math/ec/ECPoint.java | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java b/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java index 20882dacc9..575ddb851e 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java +++ b/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java @@ -1,8 +1,11 @@ package org.bouncycastle.math.ec; import java.math.BigInteger; +import java.security.SecureRandom; import java.util.Hashtable; +import org.bouncycastle.crypto.CryptoServicesRegistrar; + /** * base class for points on elliptic curves. */ @@ -222,13 +225,31 @@ public ECPoint normalize() } default: { - ECFieldElement Z1 = getZCoord(0); - if (Z1.isOne()) + ECFieldElement z = getZCoord(0); + if (z.isOne()) { return this; } - return normalize(Z1.invert()); + if (null == curve) + { + throw new IllegalStateException("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. + */ + SecureRandom r = CryptoServicesRegistrar.getSecureRandom(); + ECFieldElement b = curve.randomFieldElementMult(r); + ECFieldElement zInv = z.multiply(b).invert().multiply(b); + return normalize(zInv); } } }