diff --git a/crypto/src/crypto/agreement/ECDHBasicAgreement.cs b/crypto/src/crypto/agreement/ECDHBasicAgreement.cs
index fa587b234..c33f16f78 100644
--- a/crypto/src/crypto/agreement/ECDHBasicAgreement.cs
+++ b/crypto/src/crypto/agreement/ECDHBasicAgreement.cs
@@ -1,3 +1,5 @@
+using System;
+
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Crypto;
@@ -20,19 +22,19 @@ namespace Org.BouncyCastle.Crypto.Agreement
* Section 7.2.2).
*/
public class ECDHBasicAgreement
- : IBasicAgreement
+ : IBasicAgreement
{
protected internal ECPrivateKeyParameters privKey;
public virtual void Init(
- ICipherParameters parameters)
+ ICipherParameters parameters)
{
- if (parameters is ParametersWithRandom)
- {
- parameters = ((ParametersWithRandom)parameters).Parameters;
- }
+ if (parameters is ParametersWithRandom)
+ {
+ parameters = ((ParametersWithRandom)parameters).Parameters;
+ }
- this.privKey = (ECPrivateKeyParameters)parameters;
+ this.privKey = (ECPrivateKeyParameters)parameters;
}
public virtual int GetFieldSize()
@@ -44,11 +46,12 @@ namespace Org.BouncyCastle.Crypto.Agreement
ICipherParameters pubKey)
{
ECPublicKeyParameters pub = (ECPublicKeyParameters) pubKey;
- ECPoint P = pub.Q.Multiply(privKey.D);
+ ECPoint P = pub.Q.Multiply(privKey.D).Normalize();
- // if ( p.IsInfinity ) throw new Exception("d*Q == infinity");
+ if (P.IsInfinity)
+ throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH");
- return P.X.ToBigInteger();
+ return P.AffineXCoord.ToBigInteger();
}
}
}
diff --git a/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs b/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs
index e1c572373..89be7061e 100644
--- a/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs
+++ b/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs
@@ -52,11 +52,15 @@ namespace Org.BouncyCastle.Crypto.Agreement
{
ECPublicKeyParameters pub = (ECPublicKeyParameters) pubKey;
ECDomainParameters parameters = pub.Parameters;
- ECPoint P = pub.Q.Multiply(parameters.H.Multiply(key.D));
- // if ( p.IsInfinity ) throw new Exception("Invalid public key");
+ BigInteger hd = parameters.H.Multiply(key.D).Mod(parameters.N);
- return P.X.ToBigInteger();
+ ECPoint P = pub.Q.Multiply(hd).Normalize();
+
+ if (P.IsInfinity)
+ throw new InvalidOperationException("Infinity is not a valid agreement value for ECDHC");
+
+ return P.AffineXCoord.ToBigInteger();
}
}
}
diff --git a/crypto/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs b/crypto/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs
index 28437a268..1de80d1e5 100644
--- a/crypto/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs
+++ b/crypto/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs
@@ -44,7 +44,7 @@ namespace Org.BouncyCastle.Crypto.Agreement
DHKdfParameters dhKdfParams = new DHKdfParameters(
new DerObjectIdentifier(algorithm),
keySize,
- bigIntToBytes(result));
+ BigIntToBytes(result));
kdf.Init(dhKdfParams);
@@ -54,10 +54,9 @@ namespace Org.BouncyCastle.Crypto.Agreement
return new BigInteger(1, keyBytes);
}
- private byte[] bigIntToBytes(
- BigInteger r)
+ private byte[] BigIntToBytes(BigInteger r)
{
- int byteLength = X9IntegerConverter.GetByteLength(privKey.Parameters.G.X);
+ int byteLength = X9IntegerConverter.GetByteLength(privKey.Parameters.Curve);
return X9IntegerConverter.IntegerToBytes(r, byteLength);
}
}
diff --git a/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs b/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs
index 3559d3e81..f55ae46af 100644
--- a/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs
+++ b/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs
@@ -35,15 +35,18 @@ namespace Org.BouncyCastle.Crypto.Agreement
ECPrivateKeyParameters staticPrivateKey = privParams.StaticPrivateKey;
- ECPoint agreement = calculateMqvAgreement(staticPrivateKey.Parameters, staticPrivateKey,
+ ECPoint agreement = CalculateMqvAgreement(staticPrivateKey.Parameters, staticPrivateKey,
privParams.EphemeralPrivateKey, privParams.EphemeralPublicKey,
- pubParams.StaticPublicKey, pubParams.EphemeralPublicKey);
+ pubParams.StaticPublicKey, pubParams.EphemeralPublicKey).Normalize();
- return agreement.X.ToBigInteger();
+ if (agreement.IsInfinity)
+ throw new InvalidOperationException("Infinity is not a valid agreement value for MQV");
+
+ return agreement.AffineXCoord.ToBigInteger();
}
-
+
// The ECMQV Primitive as described in SEC-1, 3.4
- private static ECPoint calculateMqvAgreement(
+ private static ECPoint CalculateMqvAgreement(
ECDomainParameters parameters,
ECPrivateKeyParameters d1U,
ECPrivateKeyParameters d2U,
@@ -55,36 +58,32 @@ namespace Org.BouncyCastle.Crypto.Agreement
int e = (n.BitLength + 1) / 2;
BigInteger powE = BigInteger.One.ShiftLeft(e);
- // The Q2U public key is optional
- ECPoint q;
- if (Q2U == null)
- {
- q = parameters.G.Multiply(d2U.D);
- }
- else
- {
- q = Q2U.Q;
- }
+ ECCurve curve = parameters.Curve;
- BigInteger x = q.X.ToBigInteger();
+ ECPoint[] points = new ECPoint[]{
+ // The Q2U public key is optional
+ ECAlgorithms.ImportPoint(curve, Q2U == null ? parameters.G.Multiply(d2U.D) : Q2U.Q),
+ ECAlgorithms.ImportPoint(curve, Q1V.Q),
+ ECAlgorithms.ImportPoint(curve, Q2V.Q)
+ };
+
+ curve.NormalizeAll(points);
+
+ ECPoint q2u = points[0], q1v = points[1], q2v = points[2];
+
+ BigInteger x = q2u.AffineXCoord.ToBigInteger();
BigInteger xBar = x.Mod(powE);
BigInteger Q2UBar = xBar.SetBit(e);
- BigInteger s = d1U.D.Multiply(Q2UBar).Mod(n).Add(d2U.D).Mod(n);
+ BigInteger s = d1U.D.Multiply(Q2UBar).Add(d2U.D).Mod(n);
- BigInteger xPrime = Q2V.Q.X.ToBigInteger();
+ BigInteger xPrime = q2v.AffineXCoord.ToBigInteger();
BigInteger xPrimeBar = xPrime.Mod(powE);
BigInteger Q2VBar = xPrimeBar.SetBit(e);
BigInteger hs = parameters.H.Multiply(s).Mod(n);
- //ECPoint p = Q1V.Q.Multiply(Q2VBar).Add(Q2V.Q).Multiply(hs);
- ECPoint p = ECAlgorithms.SumOfTwoMultiplies(
- Q1V.Q, Q2VBar.Multiply(hs).Mod(n), Q2V.Q, hs);
-
- if (p.IsInfinity)
- throw new InvalidOperationException("Infinity is not a valid agreement value for MQV");
-
- return p;
+ return ECAlgorithms.SumOfTwoMultiplies(
+ q1v, Q2VBar.Multiply(hs).Mod(n), q2v, hs);
}
}
}
diff --git a/crypto/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs b/crypto/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs
index 093ce4056..7d79fc468 100644
--- a/crypto/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs
+++ b/crypto/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs
@@ -44,7 +44,7 @@ namespace Org.BouncyCastle.Crypto.Agreement
DHKdfParameters dhKdfParams = new DHKdfParameters(
new DerObjectIdentifier(algorithm),
keySize,
- bigIntToBytes(result));
+ BigIntToBytes(result));
kdf.Init(dhKdfParams);
@@ -54,10 +54,9 @@ namespace Org.BouncyCastle.Crypto.Agreement
return new BigInteger(1, keyBytes);
}
- private byte[] bigIntToBytes(
- BigInteger r)
+ private byte[] BigIntToBytes(BigInteger r)
{
- int byteLength = X9IntegerConverter.GetByteLength(privParams.StaticPrivateKey.Parameters.G.X);
+ int byteLength = X9IntegerConverter.GetByteLength(privParams.StaticPrivateKey.Parameters.Curve);
return X9IntegerConverter.IntegerToBytes(r, byteLength);
}
}
diff --git a/crypto/src/crypto/signers/ECDsaSigner.cs b/crypto/src/crypto/signers/ECDsaSigner.cs
index d602ec3bb..3b0b8ddf1 100644
--- a/crypto/src/crypto/signers/ECDsaSigner.cs
+++ b/crypto/src/crypto/signers/ECDsaSigner.cs
@@ -84,10 +84,10 @@ namespace Org.BouncyCastle.Crypto.Signers
}
while (k.SignValue == 0 || k.CompareTo(n) >= 0);
- ECPoint p = key.Parameters.G.Multiply(k);
+ ECPoint p = key.Parameters.G.Multiply(k).Normalize();
// 5.3.3
- BigInteger x = p.X.ToBigInteger();
+ BigInteger x = p.AffineXCoord.ToBigInteger();
r = x.Mod(n);
}
@@ -95,7 +95,7 @@ namespace Org.BouncyCastle.Crypto.Signers
BigInteger d = ((ECPrivateKeyParameters)key).D;
- s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r).Mod(n))).Mod(n);
+ s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r))).Mod(n);
}
while (s.SignValue == 0);
@@ -131,12 +131,12 @@ namespace Org.BouncyCastle.Crypto.Signers
ECPoint G = key.Parameters.G;
ECPoint Q = ((ECPublicKeyParameters) key).Q;
- ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2);
+ ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2).Normalize();
if (point.IsInfinity)
return false;
- BigInteger v = point.X.ToBigInteger().Mod(n);
+ BigInteger v = point.AffineXCoord.ToBigInteger().Mod(n);
return v.Equals(r);
}
diff --git a/crypto/src/crypto/signers/ECGOST3410Signer.cs b/crypto/src/crypto/signers/ECGOST3410Signer.cs
index 294d4791a..3d71ace04 100644
--- a/crypto/src/crypto/signers/ECGOST3410Signer.cs
+++ b/crypto/src/crypto/signers/ECGOST3410Signer.cs
@@ -88,9 +88,9 @@ namespace Org.BouncyCastle.Crypto.Signers
}
while (k.SignValue == 0);
- ECPoint p = key.Parameters.G.Multiply(k);
+ ECPoint p = key.Parameters.G.Multiply(k).Normalize();
- BigInteger x = p.X.ToBigInteger();
+ BigInteger x = p.AffineXCoord.ToBigInteger();
r = x.Mod(n);
}
@@ -144,12 +144,12 @@ namespace Org.BouncyCastle.Crypto.Signers
ECPoint G = key.Parameters.G; // P
ECPoint Q = ((ECPublicKeyParameters)key).Q;
- ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2);
+ ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2).Normalize();
if (point.IsInfinity)
return false;
- BigInteger R = point.X.ToBigInteger().Mod(n);
+ BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n);
return R.Equals(r);
}
diff --git a/crypto/src/crypto/signers/ECNRSigner.cs b/crypto/src/crypto/signers/ECNRSigner.cs
index 1d9af3d13..ba953aca4 100644
--- a/crypto/src/crypto/signers/ECNRSigner.cs
+++ b/crypto/src/crypto/signers/ECNRSigner.cs
@@ -9,181 +9,181 @@ using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
- /**
- * EC-NR as described in IEEE 1363-2000
- */
- public class ECNRSigner
- : IDsa
- {
- private bool forSigning;
- private ECKeyParameters key;
- private SecureRandom random;
-
- public string AlgorithmName
- {
- get { return "ECNR"; }
- }
-
- public void Init(
- bool forSigning,
- ICipherParameters parameters)
- {
- this.forSigning = forSigning;
-
- if (forSigning)
- {
- if (parameters is ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom) parameters;
-
- this.random = rParam.Random;
- parameters = rParam.Parameters;
- }
- else
- {
- this.random = new SecureRandom();
- }
-
- if (!(parameters is ECPrivateKeyParameters))
- throw new InvalidKeyException("EC private key required for signing");
-
- this.key = (ECPrivateKeyParameters) parameters;
- }
- else
- {
- if (!(parameters is ECPublicKeyParameters))
- throw new InvalidKeyException("EC public key required for verification");
-
- this.key = (ECPublicKeyParameters) parameters;
- }
- }
-
- // Section 7.2.5 ECSP-NR, pg 34
- /**
- * generate a signature for the given message using the key we were
- * initialised with. Generally, the order of the curve should be at
- * least as long as the hash of the message of interest, and with
- * ECNR it *must* be at least as long.
- *
- * @param digest the digest to be signed.
- * @exception DataLengthException if the digest is longer than the key allows
- */
- public BigInteger[] GenerateSignature(
- byte[] message)
- {
- if (!this.forSigning)
- {
- // not properly initilaized... deal with it
- throw new InvalidOperationException("not initialised for signing");
- }
-
- BigInteger n = ((ECPrivateKeyParameters) this.key).Parameters.N;
- int nBitLength = n.BitLength;
-
- BigInteger e = new BigInteger(1, message);
- int eBitLength = e.BitLength;
-
- ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)key;
-
- if (eBitLength > nBitLength)
- {
- throw new DataLengthException("input too large for ECNR key.");
- }
-
- BigInteger r = null;
- BigInteger s = null;
-
- AsymmetricCipherKeyPair tempPair;
- do // generate r
- {
- // generate another, but very temporary, key pair using
- // the same EC parameters
- ECKeyPairGenerator keyGen = new ECKeyPairGenerator();
-
- keyGen.Init(new ECKeyGenerationParameters(privKey.Parameters, this.random));
-
- tempPair = keyGen.GenerateKeyPair();
-
- // BigInteger Vx = tempPair.getPublic().getW().getAffineX();
- ECPublicKeyParameters V = (ECPublicKeyParameters) tempPair.Public; // get temp's public key
- BigInteger Vx = V.Q.X.ToBigInteger(); // get the point's x coordinate
-
- r = Vx.Add(e).Mod(n);
- }
- while (r.SignValue == 0);
-
- // generate s
- BigInteger x = privKey.D; // private key value
- BigInteger u = ((ECPrivateKeyParameters) tempPair.Private).D; // temp's private key value
- s = u.Subtract(r.Multiply(x)).Mod(n);
-
- return new BigInteger[]{ r, s };
- }
-
- // Section 7.2.6 ECVP-NR, pg 35
- /**
- * return true if the value r and s represent a signature for the
- * message passed in. Generally, the order of the curve should be at
- * least as long as the hash of the message of interest, and with
- * ECNR, it *must* be at least as long. But just in case the signer
- * applied mod(n) to the longer digest, this implementation will
- * apply mod(n) during verification.
- *
- * @param digest the digest to be verified.
- * @param r the r value of the signature.
- * @param s the s value of the signature.
- * @exception DataLengthException if the digest is longer than the key allows
- */
- public bool VerifySignature(
- byte[] message,
- BigInteger r,
- BigInteger s)
- {
- if (this.forSigning)
- {
- // not properly initilaized... deal with it
- throw new InvalidOperationException("not initialised for verifying");
- }
-
- ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key;
- BigInteger n = pubKey.Parameters.N;
- int nBitLength = n.BitLength;
-
- BigInteger e = new BigInteger(1, message);
- int eBitLength = e.BitLength;
-
- if (eBitLength > nBitLength)
- {
- throw new DataLengthException("input too large for ECNR key.");
- }
-
- // r in the range [1,n-1]
- if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
- {
- return false;
- }
-
- // TODO So why is this different from the spec?
- // s in the range [0,n-1] NB: ECNR spec says 0
- if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0)
- {
- return false;
- }
-
- // compute P = sG + rW
-
- ECPoint G = pubKey.Parameters.G;
- ECPoint W = pubKey.Q;
- // calculate P using Bouncy math
- ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r);
+ /**
+ * EC-NR as described in IEEE 1363-2000
+ */
+ public class ECNRSigner
+ : IDsa
+ {
+ private bool forSigning;
+ private ECKeyParameters key;
+ private SecureRandom random;
+
+ public string AlgorithmName
+ {
+ get { return "ECNR"; }
+ }
+
+ public void Init(
+ bool forSigning,
+ ICipherParameters parameters)
+ {
+ this.forSigning = forSigning;
+
+ if (forSigning)
+ {
+ if (parameters is ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom) parameters;
+
+ this.random = rParam.Random;
+ parameters = rParam.Parameters;
+ }
+ else
+ {
+ this.random = new SecureRandom();
+ }
+
+ if (!(parameters is ECPrivateKeyParameters))
+ throw new InvalidKeyException("EC private key required for signing");
+
+ this.key = (ECPrivateKeyParameters) parameters;
+ }
+ else
+ {
+ if (!(parameters is ECPublicKeyParameters))
+ throw new InvalidKeyException("EC public key required for verification");
+
+ this.key = (ECPublicKeyParameters) parameters;
+ }
+ }
+
+ // Section 7.2.5 ECSP-NR, pg 34
+ /**
+ * generate a signature for the given message using the key we were
+ * initialised with. Generally, the order of the curve should be at
+ * least as long as the hash of the message of interest, and with
+ * ECNR it *must* be at least as long.
+ *
+ * @param digest the digest to be signed.
+ * @exception DataLengthException if the digest is longer than the key allows
+ */
+ public BigInteger[] GenerateSignature(
+ byte[] message)
+ {
+ if (!this.forSigning)
+ {
+ // not properly initilaized... deal with it
+ throw new InvalidOperationException("not initialised for signing");
+ }
+
+ BigInteger n = ((ECPrivateKeyParameters) this.key).Parameters.N;
+ int nBitLength = n.BitLength;
+
+ BigInteger e = new BigInteger(1, message);
+ int eBitLength = e.BitLength;
+
+ ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)key;
+
+ if (eBitLength > nBitLength)
+ {
+ throw new DataLengthException("input too large for ECNR key.");
+ }
+
+ BigInteger r = null;
+ BigInteger s = null;
+
+ AsymmetricCipherKeyPair tempPair;
+ do // generate r
+ {
+ // generate another, but very temporary, key pair using
+ // the same EC parameters
+ ECKeyPairGenerator keyGen = new ECKeyPairGenerator();
+
+ keyGen.Init(new ECKeyGenerationParameters(privKey.Parameters, this.random));
+
+ tempPair = keyGen.GenerateKeyPair();
+
+ // BigInteger Vx = tempPair.getPublic().getW().getAffineX();
+ ECPublicKeyParameters V = (ECPublicKeyParameters) tempPair.Public; // get temp's public key
+ ECPoint vq = V.Q.Normalize();
+ BigInteger Vx = vq.AffineXCoord.ToBigInteger(); // get the point's x coordinate
+
+ r = Vx.Add(e).Mod(n);
+ }
+ while (r.SignValue == 0);
+
+ // generate s
+ BigInteger x = privKey.D; // private key value
+ BigInteger u = ((ECPrivateKeyParameters) tempPair.Private).D; // temp's private key value
+ s = u.Subtract(r.Multiply(x)).Mod(n);
+
+ return new BigInteger[]{ r, s };
+ }
+
+ // Section 7.2.6 ECVP-NR, pg 35
+ /**
+ * return true if the value r and s represent a signature for the
+ * message passed in. Generally, the order of the curve should be at
+ * least as long as the hash of the message of interest, and with
+ * ECNR, it *must* be at least as long. But just in case the signer
+ * applied mod(n) to the longer digest, this implementation will
+ * apply mod(n) during verification.
+ *
+ * @param digest the digest to be verified.
+ * @param r the r value of the signature.
+ * @param s the s value of the signature.
+ * @exception DataLengthException if the digest is longer than the key allows
+ */
+ public bool VerifySignature(
+ byte[] message,
+ BigInteger r,
+ BigInteger s)
+ {
+ if (this.forSigning)
+ {
+ // not properly initilaized... deal with it
+ throw new InvalidOperationException("not initialised for verifying");
+ }
+
+ ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key;
+ BigInteger n = pubKey.Parameters.N;
+ int nBitLength = n.BitLength;
+
+ BigInteger e = new BigInteger(1, message);
+ int eBitLength = e.BitLength;
+
+ if (eBitLength > nBitLength)
+ {
+ throw new DataLengthException("input too large for ECNR key.");
+ }
+
+ // r in the range [1,n-1]
+ if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
+ {
+ return false;
+ }
+
+ // s in the range [0,n-1] NB: ECNR spec says 0
+ if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0)
+ {
+ return false;
+ }
+
+ // compute P = sG + rW
+
+ ECPoint G = pubKey.Parameters.G;
+ ECPoint W = pubKey.Q;
+ // calculate P using Bouncy math
+ ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r).Normalize();
if (P.IsInfinity)
return false;
- BigInteger x = P.X.ToBigInteger();
- BigInteger t = r.Subtract(x).Mod(n);
+ BigInteger x = P.AffineXCoord.ToBigInteger();
+ BigInteger t = r.Subtract(x).Mod(n);
- return t.Equals(e);
- }
- }
+ return t.Equals(e);
+ }
+ }
}
|