Example #1
0
        /// <summary>Generate a shared encryptor.</summary>
        /// <param name="remoteKey">Received remote exchange key.</param>
        /// <returns>Shared encryptor that is guaranteed to be the same on both peers.</returns>
        public ICryptoEncryptor DeriveEncryptor(ArraySegment <byte> remoteKey)
        {
            // Validate
            if (Disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }
            else if (remoteKey.Count != 32)
            {
                throw new ArgumentOutOfRangeException(nameof(remoteKey), string.Format(
                                                          "Remote exchange key count {0} is not 32", remoteKey.Count
                                                          ));
            }

            // Generate shared secret inline
            if (remoteKey.Array.Length == 32)
            {
                byte[] secret = Allocator.CreateKey(32);
                Curve25519.GetSharedSecretInline(PrivateKey, remoteKey.Array, secret);
                return(new CryptoAES(secret, Allocator));
            }

            // Copy key then generate shared secret
            byte[] key = Allocator.CreateKey(32);
            try {
                Array.Copy(remoteKey.Array, remoteKey.Offset, key, 0, 32);
                byte[] secret = Allocator.CreateKey(32);
                Curve25519.GetSharedSecretInline(PrivateKey, key, secret);
                return(new CryptoAES(secret, Allocator));
            } finally {
                Allocator.ReturnKey(ref key);
            }
        }
Example #2
0
        /// <summary>Create a new ECDH key pair for key exchange.</summary>
        /// <param name="random">Random number generator to use for generating keys.</param>
        /// <param name="allocator">Allocator to use for allocating keys.</param>
        public CryptoECDH(ICryptoRandom random, Allocator allocator)
        {
            // Validate
            if (allocator == null)
            {
                throw new ArgumentNullException(nameof(allocator), "No allocator");
            }

            // Initialize
            Allocator = allocator;
            Disposed  = false;

            // Generate private key
            PrivateKey = Allocator.CreateKey(32);
            random.GetBytes(PrivateKey, 0, 32);
            Curve25519.ClampPrivateKeyInline(PrivateKey);

            // Generate public key
            PublicKey = Allocator.CreateKey(32);
            Curve25519.GetPublicKeyInline(PrivateKey, PublicKey);
        }