diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-04-16 17:44:04 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-04-16 17:44:04 +0700 |
commit | 2a06b4ddeee29bc839fc5429c50c8eff3d453c85 (patch) | |
tree | 54ace1fda7422ef260ccc34d099d467344ab979a /crypto/src | |
parent | Add low-weight guard to ECKeyPairGenerator (diff) | |
download | BouncyCastle.NET-ed25519-2a06b4ddeee29bc839fc5429c50c8eff3d453c85.tar.xz |
Set the SecureRandom more intelligently
Change access modifiers to support subclassing
Diffstat (limited to 'crypto/src')
-rw-r--r-- | crypto/src/crypto/signers/DsaSigner.cs | 247 | ||||
-rw-r--r-- | crypto/src/crypto/signers/ECDsaSigner.cs | 38 |
2 files changed, 141 insertions, 144 deletions
diff --git a/crypto/src/crypto/signers/DsaSigner.cs b/crypto/src/crypto/signers/DsaSigner.cs index 419b1972e..fc0780a91 100644 --- a/crypto/src/crypto/signers/DsaSigner.cs +++ b/crypto/src/crypto/signers/DsaSigner.cs @@ -8,129 +8,126 @@ using Org.BouncyCastle.Crypto.Parameters; namespace Org.BouncyCastle.Crypto.Signers { - /** - * The Digital Signature Algorithm - as described in "Handbook of Applied - * Cryptography", pages 452 - 453. - */ - public class DsaSigner - : IDsa - { - private DsaKeyParameters key; - private SecureRandom random; - - public string AlgorithmName - { - get { return "DSA"; } - } - - public void Init( - bool forSigning, - ICipherParameters parameters) - { - 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 DsaPrivateKeyParameters)) - throw new InvalidKeyException("DSA private key required for signing"); - - this.key = (DsaPrivateKeyParameters) parameters; - } - else - { - if (!(parameters is DsaPublicKeyParameters)) - throw new InvalidKeyException("DSA public key required for verification"); - - this.key = (DsaPublicKeyParameters) parameters; - } - } - - /** - * Generate a signature for the given message using the key we were - * initialised with. For conventional DSA the message should be a SHA-1 - * hash of the message of interest. - * - * @param message the message that will be verified later. - */ - public BigInteger[] GenerateSignature( - byte[] message) - { - DsaParameters parameters = key.Parameters; - BigInteger q = parameters.Q; - BigInteger m = calculateE(q, message); - BigInteger k; - - do - { - k = new BigInteger(q.BitLength, random); - } - while (k.CompareTo(q) >= 0); - - BigInteger r = parameters.G.ModPow(k, parameters.P).Mod(q); - - k = k.ModInverse(q).Multiply( - m.Add(((DsaPrivateKeyParameters)key).X.Multiply(r))); - - BigInteger s = k.Mod(q); - - return new BigInteger[]{ r, s }; - } - - /** - * return true if the value r and s represent a DSA signature for - * the passed in message for standard DSA the message should be a - * SHA-1 hash of the real message to be verified. - */ - public bool VerifySignature( - byte[] message, - BigInteger r, - BigInteger s) - { - DsaParameters parameters = key.Parameters; - BigInteger q = parameters.Q; - BigInteger m = calculateE(q, message); - - if (r.SignValue <= 0 || q.CompareTo(r) <= 0) - { - return false; - } - - if (s.SignValue <= 0 || q.CompareTo(s) <= 0) - { - return false; - } - - BigInteger w = s.ModInverse(q); - - BigInteger u1 = m.Multiply(w).Mod(q); - BigInteger u2 = r.Multiply(w).Mod(q); - - BigInteger p = parameters.P; - u1 = parameters.G.ModPow(u1, p); - u2 = ((DsaPublicKeyParameters)key).Y.ModPow(u2, p); - - BigInteger v = u1.Multiply(u2).Mod(p).Mod(q); - - return v.Equals(r); - } - - private BigInteger calculateE( - BigInteger n, - byte[] message) - { - int length = System.Math.Min(message.Length, n.BitLength / 8); - - return new BigInteger(1, message, 0, length); - } - } + /** + * The Digital Signature Algorithm - as described in "Handbook of Applied + * Cryptography", pages 452 - 453. + */ + public class DsaSigner + : IDsa + { + protected DsaKeyParameters key = null; + protected SecureRandom random = null; + + public virtual string AlgorithmName + { + get { return "DSA"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + SecureRandom providedRandom = null; + + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + providedRandom = rParam.Random; + parameters = rParam.Parameters; + } + + if (!(parameters is DsaPrivateKeyParameters)) + throw new InvalidKeyException("DSA private key required for signing"); + + this.key = (DsaPrivateKeyParameters)parameters; + } + else + { + if (!(parameters is DsaPublicKeyParameters)) + throw new InvalidKeyException("DSA public key required for verification"); + + this.key = (DsaPublicKeyParameters)parameters; + } + + this.random = InitSecureRandom(forSigning, providedRandom); + } + + /** + * Generate a signature for the given message using the key we were + * initialised with. For conventional DSA the message should be a SHA-1 + * hash of the message of interest. + * + * @param message the message that will be verified later. + */ + public virtual BigInteger[] GenerateSignature(byte[] message) + { + DsaParameters parameters = key.Parameters; + BigInteger q = parameters.Q; + BigInteger m = CalculateE(q, message); + BigInteger k; + + do + { + k = new BigInteger(q.BitLength, random); + } + while (k.CompareTo(q) >= 0); + + BigInteger r = parameters.G.ModPow(k, parameters.P).Mod(q); + + k = k.ModInverse(q).Multiply( + m.Add(((DsaPrivateKeyParameters)key).X.Multiply(r))); + + BigInteger s = k.Mod(q); + + return new BigInteger[]{ r, s }; + } + + /** + * return true if the value r and s represent a DSA signature for + * the passed in message for standard DSA the message should be a + * SHA-1 hash of the real message to be verified. + */ + public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) + { + DsaParameters parameters = key.Parameters; + BigInteger q = parameters.Q; + BigInteger m = CalculateE(q, message); + + if (r.SignValue <= 0 || q.CompareTo(r) <= 0) + { + return false; + } + + if (s.SignValue <= 0 || q.CompareTo(s) <= 0) + { + return false; + } + + BigInteger w = s.ModInverse(q); + + BigInteger u1 = m.Multiply(w).Mod(q); + BigInteger u2 = r.Multiply(w).Mod(q); + + BigInteger p = parameters.P; + u1 = parameters.G.ModPow(u1, p); + u2 = ((DsaPublicKeyParameters)key).Y.ModPow(u2, p); + + BigInteger v = u1.Multiply(u2).Mod(p).Mod(q); + + return v.Equals(r); + } + + protected virtual BigInteger CalculateE(BigInteger n, byte[] message) + { + int length = System.Math.Min(message.Length, n.BitLength / 8); + + return new BigInteger(1, message, 0, length); + } + + protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided) + { + return !needed ? null : (provided != null) ? provided : new SecureRandom(); + } + } } diff --git a/crypto/src/crypto/signers/ECDsaSigner.cs b/crypto/src/crypto/signers/ECDsaSigner.cs index 508335149..867520535 100644 --- a/crypto/src/crypto/signers/ECDsaSigner.cs +++ b/crypto/src/crypto/signers/ECDsaSigner.cs @@ -15,44 +15,42 @@ namespace Org.BouncyCastle.Crypto.Signers public class ECDsaSigner : IDsa { - private ECKeyParameters key; - private SecureRandom random; + protected ECKeyParameters key = null; + protected SecureRandom random = null; - public string AlgorithmName + public virtual string AlgorithmName { get { return "ECDSA"; } } - public void Init( - bool forSigning, - ICipherParameters parameters) + public virtual void Init(bool forSigning, ICipherParameters parameters) { + SecureRandom providedRandom = null; + if (forSigning) { if (parameters is ParametersWithRandom) { - ParametersWithRandom rParam = (ParametersWithRandom) parameters; + ParametersWithRandom rParam = (ParametersWithRandom)parameters; - this.random = rParam.Random; + providedRandom = 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; + this.key = (ECPrivateKeyParameters)parameters; } else { if (!(parameters is ECPublicKeyParameters)) throw new InvalidKeyException("EC public key required for verification"); - this.key = (ECPublicKeyParameters) parameters; + this.key = (ECPublicKeyParameters)parameters; } + + this.random = InitSecureRandom(forSigning, providedRandom); } // 5.3 pg 28 @@ -63,7 +61,7 @@ namespace Org.BouncyCastle.Crypto.Signers * * @param message the message that will be verified later. */ - public BigInteger[] GenerateSignature(byte[] message) + public virtual BigInteger[] GenerateSignature(byte[] message) { ECDomainParameters ec = key.Parameters; BigInteger n = ec.N; @@ -106,10 +104,7 @@ namespace Org.BouncyCastle.Crypto.Signers * the passed in message (for standard DSA the message should be * a SHA-1 hash of the real message to be verified). */ - public bool VerifySignature( - byte[] message, - BigInteger r, - BigInteger s) + public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) { BigInteger n = key.Parameters.N; @@ -156,5 +151,10 @@ namespace Org.BouncyCastle.Crypto.Signers { return new FixedPointCombMultiplier(); } + + protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided) + { + return !needed ? null : (provided != null) ? provided : new SecureRandom(); + } } } |