/// <summary> /// Signing /// </summary> /// <param name="data">data to sign</param> /// <returns>signature blob</returns> public byte[] Sign(byte[] data) { BigInteger order = _curve.Order; byte[] hash = _publicKey.HashForSigning(data, _curve); BigInteger e = new BigInteger(hash); using (var rng = new RNGCryptoServiceProvider()) { BigInteger.ModulusRing nring = new BigInteger.ModulusRing(order); for (int tries = 0; tries < 10; ++tries) { try { ECDSAKeyPair tempKeyPair = _curve.GenerateKeyPair(rng); BigInteger r = tempKeyPair.PublicKeyPoint.X % order; if (r == 0) { continue; } BigInteger k = tempKeyPair.PrivateKey; BigInteger s = nring.Multiply(k.ModInverse(order), e + nring.Multiply(r, _privateKey)); if (s == 0) { continue; } SSH2DataWriter writer = new SSH2DataWriter(); writer.WriteBigInteger(r); writer.WriteBigInteger(s); return writer.ToByteArray(); } catch (Exception ex) { Debug.WriteLine(ex); } } } throw new SSHException(Strings.GetString("FailedSigning")); }
/// <summary> /// Calculate point multiplication /// </summary> /// <param name="k1">scalar</param> /// <param name="k2">scalar</param> /// <param name="t">point</param> /// <param name="infinityToNull"> /// if result was point-at-infinity, and this parameter was true, /// null is returned instead of <see cref="ECPointAtInfinity"/>. /// </param> /// <returns>point on the curve, point at infinity, or null if failed</returns> public override ECPoint PointMul(BigInteger k1, BigInteger k2, ECPoint t, bool infinityToNull) { BigInteger.ModulusRing ring = new BigInteger.ModulusRing(p); BigInteger k = ring.Multiply(k1, k2); return PointMul(k, t, infinityToNull); }
public void Verify(byte[] data, byte[] expected) { SSH2DataReader reader = new SSH2DataReader(data); BigInteger r = reader.ReadMPInt(); BigInteger s = reader.ReadMPInt(); if (r == 0 || r >= _curve.Order || s == 0 || s >= _curve.Order) { goto Fail; } if (!IsValid()) { goto Fail; } BigInteger order = _curve.Order; byte[] hash = HashForSigning(expected, _curve); BigInteger e = new BigInteger(hash); BigInteger.ModulusRing nring = new BigInteger.ModulusRing(order); try { BigInteger sInv = s.ModInverse(order); BigInteger u1 = nring.Multiply(e, sInv); BigInteger u2 = nring.Multiply(r, sInv); ECPoint p1 = _curve.PointMul(u1, _curve.BasePoint, true); ECPoint p2 = _curve.PointMul(u2, Point, true); if (p1 == null || p2 == null) { goto Fail; } ECPoint R = _curve.PointAdd(p1, p2, true); if (R == null) { goto Fail; } BigInteger v = R.X % order; if (v != r) { goto Fail; } } catch (Exception) { goto Fail; } return; Fail: throw new VerifyException("Failed to verify"); }