summary refs log tree commit diff
path: root/crypto/src/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/crypto')
-rw-r--r--crypto/src/crypto/agreement/ECDHBasicAgreement.cs23
-rw-r--r--crypto/src/crypto/agreement/ECDHCBasicAgreement.cs10
-rw-r--r--crypto/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs7
-rw-r--r--crypto/src/crypto/agreement/ECMqvBasicAgreement.cs51
-rw-r--r--crypto/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs7
-rw-r--r--crypto/src/crypto/signers/ECDsaSigner.cs10
-rw-r--r--crypto/src/crypto/signers/ECGOST3410Signer.cs8
-rw-r--r--crypto/src/crypto/signers/ECNRSigner.cs344
8 files changed, 232 insertions, 228 deletions
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); + } + } }