summary refs log tree commit diff
path: root/crypto/src/crypto/signers/ECNRSigner.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/crypto/signers/ECNRSigner.cs')
-rw-r--r--crypto/src/crypto/signers/ECNRSigner.cs344
1 files changed, 172 insertions, 172 deletions
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); + } + } }