예제 #1
0
        public void Test()
        {
            byte[]    key1       = "2121212121212121212121212121212121212121212121212121212121212121".HexToByteArray();
            ECKeyPair privateKey = new ECKeyPair(key1, true);

            byte[]    key2      = "0242a4ae0c5bef18048fbecf995094b74bfb0f7391418d71ed394784373f41e4f3".HexToByteArray();
            ECKeyPair publicKey = new ECKeyPair(key2, false);

            byte[] result = ECDH.ComputeHashedPoint(publicKey.PublicKeyParameters, privateKey.PrivateKey);

            Assert.Equal("bd8d1d89b9ff4086baf9065df2562ccdd67399a5e9b2c0d427a92d83c1edd8fb", result.ToHex());
        }
예제 #2
0
        public byte[] ApplyActOne(ECKeyPair ephemeralKeyPair = null)
        {
            if (_state.HandshakeState != HandshakeState.Initialized)
            {
                throw new InvalidOperationException($"Invalid handshake state {_state.HandshakeState}. Must be Initialized");
            }

            _state.EphemeralKeyPair = ephemeralKeyPair ?? Secp256K1.GenerateKeyPair();
            byte[] handshakeHash = SHA256.ComputeHash(_state.HandshakeHash.ConcatToNewArray(_state.EphemeralKeyPair.PublicKeyCompressed));
            byte[] ss            = ECDH.ComputeHashedPoint(_state.RemoteAddress.PublicKey.PublicKeyParameters, _state.EphemeralKeyPair.PrivateKey);
            (byte[] chainingKey, byte[] tempK1) = HmacSha256.ComputeHashes(_state.ChainingKey, ss);
            _state.ChainingKey = chainingKey;
            (_, byte[] tag)    = ChaCha20Poly1305.EncryptWithAdditionalData(tempK1, _state.SendNonce.GetBytes(), handshakeHash, new byte[0]);
            handshakeHash      = SHA256.ComputeHash(handshakeHash.ConcatToNewArray(tag));

            _state.HandshakeHash  = handshakeHash;
            _state.HandshakeState = HandshakeState.Act1;
            return(ByteExtensions.Combine(new byte[] { 0 }, _state.EphemeralKeyPair.PublicKeyCompressed, tag));
        }
예제 #3
0
        public byte[] ApplyActTwo(ECKeyPair initiatorEphemeralKey, ECKeyPair localEphemeralKey = null)
        {
            if (_state.HandshakeState != HandshakeState.Act1)
            {
                throw new InvalidOperationException($"Invalid Handshake state {_state.HandshakeState}. Must be Act1");
            }

            _state.EphemeralKeyPair = localEphemeralKey ?? Secp256K1.GenerateKeyPair();
            byte[] handshakeHash = SHA256.ComputeHash(_state.HandshakeHash.ConcatToNewArray(_state.EphemeralKeyPair.PublicKeyCompressed));
            byte[] ss            = ECDH.ComputeHashedPoint(initiatorEphemeralKey.PublicKeyParameters, _state.EphemeralKeyPair.PrivateKey);
            (byte[] chainingKey, byte[] tempK2) = HmacSha256.ComputeHashes(_state.ChainingKey, ss);
            (_, byte[] tag1) = ChaCha20Poly1305.EncryptWithAdditionalData(tempK2, new byte[12], handshakeHash, new byte[0]);
            handshakeHash    = SHA256.ComputeHash(handshakeHash.ConcatToNewArray(tag1));

            _state.HandshakeHash  = handshakeHash;
            _state.ChainingKey    = chainingKey;
            _state.TempKey2       = tempK2;
            _state.HandshakeState = HandshakeState.Act2;
            return(ByteExtensions.Combine(new byte[] { 0 }, _state.EphemeralKeyPair.PublicKeyCompressed, tag1));
        }
예제 #4
0
        public (byte[] tempK1, ECKeyPair ephemeralKey) ReadActOneRequest(Span <byte> message, int length)
        {
            if (_state.HandshakeState != HandshakeState.Initialized)
            {
                throw new InvalidOperationException($"Invalid handshake state {_state.HandshakeState}. Must be Initialized");
            }

            if (length != 50)
            {
                throw new ArgumentException("ACT1_READ_FAILED");
            }

            byte        version = message.Slice(0, 1)[0];
            ECKeyPair   responderEphemeralKey = new ECKeyPair(message.Slice(1, 33), false);
            Span <byte> c = message.Slice(34, 16);

            if (version != 0)
            {
                throw new NotSupportedException("ACT1_BAD_VERSION");
            }

            byte[] handshakeHash = SHA256.ComputeHash(_state.HandshakeHash.ConcatToNewArray(responderEphemeralKey.PublicKeyCompressed));
            byte[] ss            = ECDH.ComputeHashedPoint(responderEphemeralKey.PublicKeyParameters, _state.LocalKeyPair.PrivateKey);
            (byte[] chainingKey, byte[] tempK1) = HmacSha256.ComputeHashes(_state.ChainingKey, ss);
            _state.ChainingKey = chainingKey;

            (_, byte[] mac) = ChaCha20Poly1305.DecryptWithAdditionalData(tempK1, _state.ReceiveNonce.GetBytes(), handshakeHash, new byte[0]);

            if (!c.SequenceEqual(mac))
            {
                throw new ArgumentException("ACT1_BAD_TAG");
            }

            _state.ReceiveNonce.Increment();
            _state.HandshakeHash  = SHA256.ComputeHash(handshakeHash.ConcatToNewArray(c.ToArray()));
            _state.HandshakeState = HandshakeState.Act1;
            return(tempK1, responderEphemeralKey);
        }
예제 #5
0
        public void ReadActThreeRequest(Span <byte> message, int length)
        {
            if (length != 66)
            {
                throw new ArgumentException("ACT3_READ_FAILED");
            }

            byte        version = message.Slice(0, 1)[0];
            Span <byte> c       = message.Slice(1, 49);

            //byte[] t = message.SubArray(50, 16);

            if (version != 0)
            {
                throw new NotSupportedException("ACT3_BAD_VERSION");
            }

            (byte[] rs, _) = ChaCha20Poly1305.DecryptWithAdditionalData(_state.TempKey2, _state.ReceiveNonce.GetBytes(), _state.HandshakeHash, c.ToArray());
            ECKeyPair rsKey = new ECKeyPair(((Span <byte>)rs).Slice(0, 33), false);

            byte[] handshakeHash = SHA256.ComputeHash(_state.HandshakeHash.ConcatToNewArray(c.ToArray()));
            byte[] ss            = ECDH.ComputeHashedPoint(rsKey.PublicKeyParameters, _state.EphemeralKeyPair.PrivateKey);
            (byte[] chainingKey, _) = HmacSha256.ComputeHashes(_state.ChainingKey, ss);

            //byte[] p, byte[] mac2) = ChaCha20Poly1305.decryptWithAD(tempK3, new byte[12], handshakeHash, t);
            // TODO: do mac check

            (byte[] decryptKey, byte[] encryptKey) = HmacSha256.ComputeHashes(chainingKey, new byte[0]);

            _state.ChainingKey          = chainingKey;
            _state.HandshakeHash        = handshakeHash;
            _state.SendEncryptionKey    = encryptKey;
            _state.ReceiveDecryptionKey = decryptKey;
            _state.SendNonce.Reset();
            _state.ReceiveNonce.Reset();
            _state.HandshakeState = HandshakeState.Finished;
        }
예제 #6
0
        public byte[] ApplyActThree(byte[] tempK2, ECKeyPair responderEphemeralKey)
        {
            if (_state.HandshakeState != HandshakeState.Act2)
            {
                throw new InvalidOperationException($"Invalid Handshake state {_state.HandshakeState}. Must be Act2");
            }

            (byte[] cipherText, byte[] tag) = ChaCha20Poly1305.EncryptWithAdditionalData(tempK2, _state.SendNonce.GetBytes(), _state.HandshakeHash, _state.LocalKeyPair.PublicKeyCompressed);
            byte[] cipherAndMac  = cipherText.ConcatToNewArray(tag);
            byte[] handshakeHash = SHA256.ComputeHash(_state.HandshakeHash.ConcatToNewArray(cipherAndMac));
            byte[] ss            = ECDH.ComputeHashedPoint(responderEphemeralKey.PublicKeyParameters, _state.LocalKeyPair.PrivateKey);
            (byte[] chainingKey, byte[] tempK3) = HmacSha256.ComputeHashes(_state.ChainingKey, ss);
            (_, byte[] tag2) = ChaCha20Poly1305.EncryptWithAdditionalData(tempK3, new byte[12], handshakeHash, new byte[0]);
            (byte[] encryptKey, byte[] decryptKey) = HmacSha256.ComputeHashes(chainingKey, new byte[0]);

            _state.HandshakeHash        = handshakeHash;
            _state.ChainingKey          = chainingKey;
            _state.SendEncryptionKey    = encryptKey;
            _state.ReceiveDecryptionKey = decryptKey;
            _state.SendNonce.Reset();
            _state.ReceiveNonce.Reset();
            _state.HandshakeState = HandshakeState.Finished;
            return(ByteExtensions.Combine(new byte[] { 0 }, cipherAndMac, tag2));
        }