//проверка цифровой подписи. public bool VerifDs(byte[] h, string sign, EcPoint q) { string rvector = sign.Substring(0, sign.Length / 2); string svector = sign.Substring(sign.Length / 2, sign.Length / 2); var r = new BigInteger(rvector, 16); var s = new BigInteger(svector, 16); if ((r < 1) || (r > (_n - 1)) || (s < 1) || (s > (_n - 1))) { return(false); } var a = new BigInteger(h); BigInteger e = a % _n; if (e == 0) { e = 1; } BigInteger v = e.modInverse(_n); BigInteger z1 = (s * v) % _n; BigInteger z2 = _n + ((-(r * v)) % _n); _g = GDecompression(); EcPoint A = EcPoint.Multiply(_g, z1); EcPoint b = EcPoint.Multiply(q, z2); EcPoint c = A + b; BigInteger R = c.X % _n; return(R == r); }
//формирование цифровой подписи. public string GenDs(byte[] h, BigInteger d) { var a = new BigInteger(h); BigInteger e = a % _n; if (e == 0) { e = 1; } var k = new BigInteger(); BigInteger r; BigInteger s; do { do { k.genRandomBits(_n.bitCount(), new Random()); }while (k < 0 || k > _n); var c = EcPoint.Multiply(_g, k); r = c.X % _n; s = (r * d + k * e) % _n; }while (r == 0 || s == 0); string rvector = Padding(r.ToHexString(), _n.bitCount() / 4); string svector = Padding(s.ToHexString(), _n.bitCount() / 4); return(rvector + svector); }
//восстановление координат Y из координаты X и бита четности Y. private EcPoint GDecompression() { byte y = _xG[0]; byte[] x = new byte[_xG.Length - 1]; Array.Copy(_xG, 1, x, 0, _xG.Length - 1); BigInteger xcord = new BigInteger(x); BigInteger temp = (xcord * xcord * xcord + _a * xcord + _b) % _p; BigInteger beta = ModSqrt(temp, _p); BigInteger ycord = (beta % 2 == y % 2) ? beta : _p - beta; EcPoint g = new EcPoint { A = _a, B = _b, FieldChar = _p, X = xcord, Y = ycord }; _g = g; return(g); }
//генерация публичного ключа (с помощью секретного). public EcPoint GenPublicKey(BigInteger d) { return(EcPoint.Multiply(GDecompression(), d)); }