/// <summary> /// Verifies that the server's proof value matches the value /// calculated by the client. /// </summary> /// <param name="serverProof">The 20-byte server proof.</param> /// <exception cref="ArgumentOutOfRangeException">Thrown if /// the server proof value is not exactly 20 bytes.</exception> /// <exception cref="InvalidOperationException">Thrown if the object has not /// yet been initialized.</exception> /// <remarks> /// This method should be called after the <see cref="LoginProof(byte[], int, int, byte[], byte[])">LoginProof</see> method. /// </remarks> /// <returns><b>True</b> if the server proof is valid; /// otherwise <b>false</b>.</returns> public bool VerifyServerProof(byte[] serverProof) { if (serverProof.Length != 20) throw new ArgumentOutOfRangeException("Server proof must be exactly 20 bytes."); using (MemoryStream ms_m2 = new MemoryStream(92)) { BinaryWriter bw = new BinaryWriter(ms_m2); bw.Write(EnsureArrayLength(A.ToByteArray(), 32)); bw.Write(m1.ToByteArray()); bw.Write(k); byte[] client_m2_data = ms_m2.GetBuffer(); ms_m2.Close(); byte[] client_hash_m2 = s_sha.ComputeHash(client_m2_data); BigInteger client_m2 = new BigInteger(client_hash_m2); BigInteger server_m2 = new BigInteger(serverProof); Debug.WriteLine(client_m2.ToHexString(), "Client"); Debug.WriteLine(server_m2.ToHexString(), "Server"); return client_m2.Equals(server_m2); } }
//подписываем сообщение 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; }