private void RemoteTimestamp(BlockchainProof proof) { var uri = _configuration.RemoteServer(); uri = uri.Append($"/api/timestamp/{proof.MerkleRoot.ConvertToBase64()}"); using (var client = new WebClient()) { var json = client.DownloadString(uri); if (!string.IsNullOrEmpty(json)) { var timestamp = JsonConvert.DeserializeObject <Timestamp>(json); if (timestamp.Proof != null) { if (timestamp.Proof.Confirmations > 0) { proof.Receipt = ByteExtensions.Combine(timestamp.Path, timestamp.Proof.Receipt); proof.Address = timestamp.Proof.Address; proof.Confirmations = timestamp.Proof.Confirmations; proof.Blockchain = timestamp.Proof.Blockchain; } } } } }
public static byte[] Encode(List <NetworkAddress> addresses) { List <byte[]> addressData = new List <byte[]>(); foreach (var address in addresses) { switch (address.Type) { case AddressType.IpV4: addressData.Add(EncodeIpV4(address)); break; case AddressType.IpV6: addressData.Add(EncodeIpV6(address)); break; // TODO: support TOR // case AddressType.TorV2: // byte[] torv2 = new byte[12]; // torv2[0] = 2; // break; // case AddressType.TorV3: // byte[] torv3 = new byte[37]; // torv3[0] = 3; // addressData.Add(torv3); // break; } } return(ByteExtensions.Combine(addressData.ToArray())); }
public byte[] GetBytes() { var properties = GetProperties(); var propertyData = new List <byte[]>(); int index = 0; ValidateProperties(properties); propertyData.Add(_messageDefinition.TypeId.GetBytesBigEndian()); foreach (var property in properties) { var definition = _messageDefinition.Properties[index]; if (definition.Type.VariableLength) { ushort length = (ushort)((ushort)property.Length / definition.Type.LengthPerProperty); propertyData.Add(ByteExtensions.Combine(length.GetBytesBigEndian(), property)); } else { if (property.Length != definition.Type.Length) { throw new ArgumentException("wrong property size"); } propertyData.Add(property); } index++; } return(ByteExtensions.Combine(propertyData.ToArray())); }
public byte[] GetDataWithRealmAndHmac(byte[] nextHmac) { if (ShortChannelId.Length != 8) { throw new ArgumentException("invalid property size.", nameof(ShortChannelId)); } if (Padding.Length != 12) { throw new ArgumentException("invalid property size.", nameof(Padding)); } if (nextHmac.Length != 32) { throw new ArgumentException("invalid property size.", nameof(nextHmac)); } return(ByteExtensions.Combine( new[] { Realm }, ShortChannelId, AmountToForward.GetBytesBigEndian(), OutgoingCltvValue.GetBytesBigEndian(), Padding, nextHmac)); }
public override List <byte[]> GetProperties() { return(new List <byte[]> { ChannelId, Signature, ByteExtensions.Combine(HtlcSignatures.ToArray()) }); }
public byte[] GetData() { return(ByteExtensions.Combine( Hmac, ((ushort)FailureMessageData.Length).GetBytesBigEndian(), FailureMessageData, ((ushort)Pad.Length).GetBytesBigEndian(), Pad)); }
public static (byte[] plainText, byte[] mac) DecryptWithAdditionalData(byte[] key, byte[] nonce, byte[] additionalData, byte[] cipherText) { var polyKey = ChaCha20Encrypt(new byte[32], key, nonce); var data = ByteExtensions.Combine(additionalData, Pad16(additionalData), cipherText, Pad16(cipherText), BitConverter.GetBytes((long)additionalData.Length), BitConverter.GetBytes((long)cipherText.Length)); var mac = CalculateMac(polyKey, data); var plainText = ChaCha20Decrypt(cipherText, key, nonce, true); return(plainText, mac); }
public byte[] Encode(List <byte[]> shortIdsToEncode, bool compress) { var data = ByteExtensions.Combine(shortIdsToEncode.ToArray()); if (compress) { ZLibCompression zLibCompression = new ZLibCompression(); var compressed = zLibCompression.Compress(data); return(ByteExtensions.Combine(new byte[] { 1 }, compressed)); } return(ByteExtensions.Combine(new byte[] { 0 }, data)); }
public static (byte[], byte[]) EncryptWithAdditionalData(byte[] key, byte[] nonce, byte[] additionalData, byte[] plaintext, bool skipFirst64Byte = true) { var polyKey = ChaCha20Encrypt(new byte[32], key, nonce); var cipherText = ChaCha20Encrypt(plaintext, key, nonce, skipFirst64Byte); var data = ByteExtensions.Combine(additionalData, Pad16(additionalData), cipherText, Pad16(cipherText), BitConverter.GetBytes((long)additionalData.Length), BitConverter.GetBytes((long)cipherText.Length)); var macTag = CalculateMac(polyKey, data); return(cipherText, macTag); }
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)); }
/// <summary> /// Loads the embedded album art from the item with the given path. /// MPD usually implements this by reading embedded pictures from binary tags (e.g. ID3v2’s APIC tag). /// Uses <see cref="Commands.Database.ReadPicture"/> recursively under the hood to get the full image and returns the image content as a byte array. /// Returns null if the file can't be found or contains no image. /// </summary> /// <param name="path">path to an item</param> /// <returns>AlbumArt with byte[] image or null</returns> public async Task <IAlbumArt> LoadEmbeddedAlbumArt(string path) { var completed = false; var offset = 0; var array = new byte[0]; IAlbumArt art = null; while (!completed) { var result = await SendAsync(new Commands.Database.ReadPicture(path, offset)); if (result.Result != null && !result.Status.HasError) { if (result.Result.ChunkLength == 0) { completed = true; art = new AlbumArt { Bytes = array, ItemPath = path, MimeType = result.Result.MimeType }; } else { offset += result.Result.ChunkLength; array = ByteExtensions.Combine(array, result.Result.Binary); } } else { completed = true; } } return(art.HasContent ? art : null); }
public byte[] Build(byte[] messageData) { if (messageData.Length > 65535) { throw new MessageException("Message size exceeds maximum size."); } (byte[] encryptedLength, byte[] lengthMac) = ChaCha20Poly1305.EncryptWithAdditionalData(_transportState.SendEncryptionKey, _transportState.SendNonce.GetBytes(), new byte[0], ((ushort)messageData.Length).GetBytesBigEndian()); _transportState.SendNonce.Increment(); (byte[] encryptedMessage, byte[] messageMac) = ChaCha20Poly1305.EncryptWithAdditionalData(_transportState.SendEncryptionKey, _transportState.SendNonce.GetBytes(), new byte[0], messageData); _transportState.SendNonce.Increment(); if (_transportState.SendNonce.Value == 1000) { _transportState.RotateSendKey(); } return(ByteExtensions.Combine(encryptedLength, lengthMac, encryptedMessage, messageMac)); }
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)); }
/* * Implementation of * https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md#packet-construction */ public OnionPacket Build() { var hopsCount = HopsData.Count; List <byte[]> hopSharedSecrets = new List <byte[]>(); var ephemeralKey = SessionKey.PrivateKey.D; var ephemeralKeys = new List <BigInteger>(); for (var i = 0; i < hopsCount; i++) { ephemeralKeys.Add(ephemeralKey); // Perform ECDH and hash the result. var ecdhResult = HopsData[i].PublicKey.PublicKeyParameters.Q.Multiply(ephemeralKey); var hopSharedSecret = SHA256.ComputeHash(ecdhResult.GetEncoded()); hopSharedSecrets.Add(hopSharedSecret); // Derive ephemeral public key from private key. ECKeyPair ephemeralKeyPair = new ECKeyPair(ephemeralKey.ToByteArrayUnsigned(), true); // Compute blinding factor. var combined = ephemeralKeyPair.PublicKeyCompressed.ConcatToNewArray(hopSharedSecret); BigInteger blindingFactor = new BigInteger(1, SHA256.ComputeHash(combined)); // Blind ephemeral key for next hop. ephemeralKey = ephemeralKey.Multiply(blindingFactor); ephemeralKey = ephemeralKey.Mod(ECKeyPair.Secp256K1.N); } // Generate the padding, called "filler strings" in the paper. var filler = GenerateFiller(Rho, hopsCount, HopDataSize, hopSharedSecrets); // Allocate and initialize fields to zero-filled slices var routingInfoSize = HopDataSize * HopsMaximumCount; var routingInfo = new byte[routingInfoSize]; var nextHmac = new byte[HmacSize]; // Compute the routing information for each hop along with a // MAC of the routing information using the shared key for that hop. for (int i = hopsCount - 1; i >= 0; i--) { var rhoKey = GenerateKey(Rho, hopSharedSecrets[i]); var muKey = GenerateKey(Mu, hopSharedSecrets[i]); var perHopData = HopsData[i].GetDataWithRealmAndHmac(nextHmac); var streamBytes = GenerateCipherStream(rhoKey, (uint)routingInfoSize); // Shift right Array.Copy(routingInfo, 0, routingInfo, HopDataSize, routingInfo.Length - HopDataSize); // Add per hop data Array.Copy(perHopData, 0, routingInfo, 0, perHopData.Length); routingInfo = Xor(routingInfo, streamBytes); if (i == hopsCount - 1) { Array.Copy(filler, 0, routingInfo, routingInfo.Length - filler.Length, filler.Length); } var packet = routingInfo.ConcatToNewArray(AssociatedData); nextHmac = CalculateMac(muKey, packet); } byte version = 0x0; var data = ByteExtensions.Combine(new byte[] { version }, SessionKey.PublicKeyCompressed, routingInfo, nextHmac); return(new OnionPacket(SessionKey, nextHmac, HopsData, version, data)); }
public byte[] GetBytes() => ByteExtensions.Combine(BitConverter.GetBytes(0), BitConverter.GetBytes(_value));