protected virtual AsymmetricCipherKeyPair GenerateECKeyPair(ECDomainParameters ecParams) { ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); ECKeyGenerationParameters keyGenerationParameters = new ECKeyGenerationParameters(ecParams, context.SecureRandom); keyPairGenerator.Init(keyGenerationParameters); return keyPairGenerator.GenerateKeyPair(); }
// 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.Sign == 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 }; }