Exemple #1
0
        public static void KeyExchange(ArraySegment <byte> sharedKey, ArraySegment <byte> publicKey, ArraySegment <byte> privateKey, bool naclCompat = false)
        {
            if (sharedKey.Array == null)
            {
                throw new ArgumentNullException("sharedKey.Array");
            }
            if (publicKey.Array == null)
            {
                throw new ArgumentNullException("publicKey.Array");
            }
            if (privateKey.Array == null)
            {
                throw new ArgumentNullException("privateKey");
            }
            if (sharedKey.Count != SharedKeySizeInBytes)
            {
                throw new ArgumentException("sharedKey.Count != 32");
            }
            if (publicKey.Count != PublicKeySizeInBytes)
            {
                throw new ArgumentException("publicKey.Count != 32");
            }
            if (privateKey.Count != ExpandedPrivateKeySizeInBytes)
            {
                throw new ArgumentException("privateKey.Count != 64");
            }

            FieldElement montgomeryX, edwardsY, edwardsZ, sharedMontgomeryX;

            FieldOperations.fe_frombytes(out edwardsY, publicKey.Array, publicKey.Offset);
            FieldOperations.fe_1(out edwardsZ);
            Curve25519.EdwardsToMontgomeryX(out montgomeryX, ref edwardsY, ref edwardsZ);

            IHash hasher = AuthenticatorFactory.CreateHashPrimitive(HashFunction.Sha512);

            hasher.BlockUpdate(privateKey.Array, privateKey.Offset, 32);
            byte[] h = new byte[64];
            hasher.DoFinal(h, 0);
            ScalarOperations.sc_clamp(h, 0);
            MontgomeryOperations.scalarmult(out sharedMontgomeryX, h, 0, ref montgomeryX);
            h.SecureWipe();
            FieldOperations.fe_tobytes(sharedKey.Array, sharedKey.Offset, ref sharedMontgomeryX);

            if (naclCompat)
            {
                Curve25519.KeyExchangeOutputHashNaCl(sharedKey.Array, sharedKey.Offset);
            }
        }