public void RotateSendKey() { (byte[] newChainingKey, byte[] newSendKey) = HmacSha256.ComputeHashes(ChainingKey, SendEncryptionKey); ChainingKey = newChainingKey; SendEncryptionKey = newSendKey; SendNonce.Reset(); }
public void RotateReceiveKey() { (byte[] newChainingKey, byte[] newReceiveKey) = HmacSha256.ComputeHashes(ChainingKey, ReceiveDecryptionKey); ChainingKey = newChainingKey; ReceiveDecryptionKey = newReceiveKey; ReceiveNonce.Reset(); }
public void GenerateHashesTest() { String salt = "2640f52eebcd9e882958951c794250eedb28002c05d7dc2ea0f195406042caf1"; String data = "1e2fb3c8fe8fb9f262f649f64d26ecf0f2c0a805a767cf02dc2d77a6ef1fdcc3"; (byte[] output1, byte[] output2) = HmacSha256.ComputeHashes(salt.HexToByteArray(), data.HexToByteArray()); String output1Expected = "b61ec1191326fa240decc9564369dbb3ae2b34341d1e11ad64ed89f89180582f"; String output2Expected = "e68f69b7f096d7917245f5e5cf8ae1595febe4d4644333c99f9c4a1282031c9f"; Assert.Equal(output1Expected, output1.ToHex()); Assert.Equal(output2Expected, output2.ToHex()); }
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)); }
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)); }
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); }
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; }
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)); }