//функция вычисления квадратоного корня по модулю простого числа q public BigInteger ModSqrt(BigInteger a, BigInteger q) { BigInteger b = new BigInteger(); do { b.genRandomBits(255, new Random()); } while (Legendre(b, q) == 1); BigInteger s = 0; BigInteger t = q - 1; while ((t & 1) != 1) { s++; t = t >> 1; } BigInteger InvA = a.modInverse(q); BigInteger c = b.modPow(t, q); BigInteger r = a.modPow(((t + 1) / 2), q); BigInteger d = new BigInteger(); for (int i = 1; i < s; i++) { BigInteger temp = 2; temp = temp.modPow((s - i - 1), q); d = (r.modPow(2, q) * InvA).modPow(temp, q); if (d == (q - 1)) r = (r * c) % q; c = c.modPow(2, q); } return r; }
//Генерируем секретный ключ заданной длины public BigInteger GenPrivateKey(int BitSize) { BigInteger d = new BigInteger(); d.genRandomBits(BitSize, new Random()); return d; }
//подписываем сообщение public string GenerateSignature(byte[] h, BigInteger d) { BigInteger alpha = new BigInteger(h); BigInteger e = alpha % n; if (e == 0) e = 1; BigInteger k = new BigInteger(); ECPoint C = new ECPoint(); BigInteger r = new BigInteger(); BigInteger s = new BigInteger(); do { do { k.genRandomBits(n.bitCount(), new Random()); } while ((k < 0) || (k > n)); C = ECPoint.multiply(k, G); 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; }