void PointCompressTest(int bits, ECGroup group, ECPoint p, int repeats, string name) { int bytes = (bits >> 3) + ((bits & 7) == 0 ? 0 : 1) + 1; for (int i = 0; i < repeats; i++) { byte[] tmp = p.ToByteArray(true); Assert.IsTrue(tmp.Length == bytes, name + " #1"); ECPoint x = new ECPoint(group, tmp).Export(); ECPoint p2 = p.Export(); Assert.IsTrue(x.X.CompareTo(p2.X) == 0, name + " #2"); Assert.IsTrue(x.Y.CompareTo(p2.Y) == 0, name + " #3"); p = p.Multiply(Number.CreateRandomElement(group.P)); } }
public byte[] PerformKeyAgreement(byte[] otherPublicKey1, byte[] otherPublicKey2, int keyDataLength) { ECPoint otherQ1 = new ECPoint(_params.Domain.Group, otherPublicKey1); ECPoint otherQ2 = new ECPoint(_params.Domain.Group, otherPublicKey2); IFiniteField ff = _params.Domain.FieldN; // MQV Primitives if (_params.KeyPair1.D == null) { _params.KeyPair1.CreateNewPrivateKey(); } if (_params.KeyPair2.D == null) { _params.KeyPair2.CreateNewPrivateKey(); } if (_params.KeyPair2.Q == null) { _params.KeyPair2.CreatePublicKeyFromPrivateKey(); } int logBits = _params.Domain.N.BitCount(); logBits = (logBits >> 1) + ((logBits & 1) == 0 ? 0 : 1); Number mod = Number.One << logBits; Number mask = mod - Number.One; Number q2u = (_params.KeyPair2.Q.Export().X & mask) + mod; Number s = ff.Add(_params.KeyPair2.D, ff.Multiply(q2u, _params.KeyPair1.D)); Number q2v = (otherQ2.Export().X & mask) + mod; ECPoint P = otherQ2.Add(otherQ1.Multiply(q2v)).Multiply(s * new Number(new uint[] { _params.Domain.H })); if (P.IsInifinity()) { throw new CryptographicException(); } int keyBytes = (int)((_params.Domain.Bits >> 3) + ((_params.Domain.Bits & 7) == 0 ? 0 : 1)); byte[] sharedSecretValue = P.Export().X.ToByteArray(keyBytes, false); // KDF _kdf.SharedInfo = _sharedInfo; return(_kdf.Calculate(sharedSecretValue, keyDataLength)); }