Exemplo n.º 1
0
        // 4.1. DH functions

        /// <summary>
        /// Create a X25519 static keyPair out of a private key.
        /// </summary>
        /// <param name="privateKey">Private key, if null - generates a random key pair</param>
        /// <returns>X25519 key pair</returns>
        public static KeyPair GenerateKeyPair(byte[] privateKey = null)
        {
            var keyPair = new KeyPair()
            {
                PublicKey  = new byte[Asymmetric.DhLen],
                PrivateKey = new byte[Asymmetric.DhLen]
            };

            if (privateKey == null)
            {
                var random = new RNGCryptoServiceProvider();
#if !DEBUG_DETERMINISTIC
                random.GetBytes(keyPair.PrivateKey, 0, keyPair.PrivateKey.Length);
#endif
            }
            else
            {
                if (privateKey.Length != Asymmetric.DhLen)
                {
                    throw new Exception($"disco: expecting {Asymmetric.DhLen} byte key array");
                }

                privateKey.CopyTo(keyPair.PrivateKey, 0);
            }

            keyPair.PublicKey = ScalarMult.Base(keyPair.PrivateKey);

            return(keyPair);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Load Dico key pair from file
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns>Disco key pair</returns>
        public static KeyPair LoadDiscoKeyPair(string fileName)
        {
            var hex = File.ReadAllText(fileName);

            if (hex.Length != 128)
            {
                throw new Exception("Disco: Disco key pair file is not correctly formated");
            }

            var keyPair = new KeyPair();

            keyPair.ImportPublicKey(hex.Substring(0, 64));
            keyPair.ImportPrivateKey(hex.Substring(64, 64));

            return(keyPair);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Disco peer initialization
        /// </summary>
        /// <param name="handshakeType">Noise handshake pattern</param>
        /// <param name="initiator">This party initiates connection</param>
        /// <param name="prologue">Prologue string, some data prior to handshake</param>
        /// <param name="s">local static key</param>
        /// <param name="e">local ephemeral key</param>
        /// <param name="rs">remote static key</param>
        /// <param name="re">remote ephemeral key</param>
        /// <returns>Initialized Disco handshake state</returns>
        public static HandshakeState InitializeDisco(
            NoiseHandshakeType handshakeType,
            bool initiator,
            byte[] prologue,
            KeyPair s,
            KeyPair e,
            KeyPair rs,
            KeyPair re)
        {
            var handshakePattern = HandshakePattern.GetPattern(handshakeType);

            var handshakeState = new HandshakeState
            {
                SymmetricState = new SymmetricState($"Noise_{handshakePattern.Name}_25519_STROBEv1.0.2"),
                Initiator      = initiator,
                ShouldWrite    = initiator
            };

            try
            {
                if (prologue != null)
                {
                    handshakeState.SymmetricState.MixHash(prologue);
                }

                if (s != null)
                {
                    handshakeState.S = s;
                }

                if (e != null)
                {
                    throw new NotSupportedException("disco: fallback patterns are not implemented");
                }

                if (rs != null)
                {
                    handshakeState.Rs = rs;
                }

                if (re != null)
                {
                    throw new NotSupportedException("disco: fallback patterns are not implemented");
                }

                //Calls MixHash() once for each public key listed in the pre-messages from handshake_pattern,
                //with the specified public key as input (see Section 7 for an explanation of pre-messages).
                //If both initiator and responder have pre-messages, the initiator's public keys are hashed first.

                // initiator pre-message pattern
                foreach (var token in handshakePattern.PreMessagePatterns[0])
                {
                    if (token == Tokens.TokenS)
                    {
                        if (initiator)
                        {
                            if (s == null)
                            {
                                throw new Exception("disco: the static key of the client should be set");
                            }

                            handshakeState.SymmetricState.MixHash(s.PublicKey);
                        }
                        else
                        {
                            if (rs == null)
                            {
                                throw new Exception("disco: the remote static key of the server should be set");
                            }

                            handshakeState.SymmetricState.MixHash(rs.PublicKey);
                        }
                    }
                    else
                    {
                        throw new Exception("disco: token of pre-message not supported");
                    }
                }

                // responder pre-message pattern
                foreach (var token in handshakePattern.PreMessagePatterns[1])
                {
                    if (token == Tokens.TokenS)
                    {
                        if (initiator)
                        {
                            if (rs == null)
                            {
                                throw new Exception("disco: the remote static key of the client should be set");
                            }

                            handshakeState.SymmetricState.MixHash(rs.PublicKey);
                        }
                        else
                        {
                            if (s == null)
                            {
                                throw new Exception("disco: the static key of the server should be set");
                            }

                            handshakeState.SymmetricState.MixHash(s.PublicKey);
                        }
                    }
                    else
                    {
                        throw new NotSupportedException("disco: token of pre - message not supported");
                    }
                }

                handshakeState.MessagePatterns = handshakePattern.MessagePatterns;
                return(handshakeState);
            }
            catch (Exception)
            {
                handshakeState.Dispose();
                throw;
            }
        }
Exemplo n.º 4
0
 /// <summary>
 /// Perform DH on public key
 /// </summary>
 /// <param name="keyPair">Containing private key</param>
 /// <param name="publicKey">Remote party's public key</param>
 /// <returns>DH result</returns>
 public static byte[] Dh(KeyPair keyPair, byte[] publicKey)
 {
     return(ScalarMult.Mult(keyPair.PrivateKey, publicKey));
 }