private static byte[] blake2sSelfTest() { var inc = Blake2s.CreateIncrementalHasher(blake2sCheck.Length); foreach (int diglen in new[] { 16, 20, 28, 32 }) { foreach (int msglen in new[] { 0, 3, 64, 65, 255, 1024 }) { var msg = getTestSequence(msglen); var key = getTestSequence(diglen); inc.Update(Blake2s.ComputeHash(diglen, msg)); inc.Update(Blake2s.ComputeHash(diglen, key, msg)); } } return(inc.Finish()); }
private static byte[] blake2sNoAllocSelfTest() { Span <byte> buff = stackalloc byte[Blake2b.DefaultDigestLength]; var inc = Blake2s.CreateIncrementalHasher(blake2sCheck.Length); foreach (int diglen in new[] { 16, 20, 28, 32 }) { foreach (int msglen in new[] { 0, 3, 64, 65, 255, 1024 }) { var msg = getTestSequence(msglen); var key = getTestSequence(diglen); Blake2s.ComputeAndWriteHash(diglen, msg, buff); inc.Update(buff.Slice(0, diglen)); Blake2s.ComputeAndWriteHash(diglen, key, msg, buff); inc.Update(buff.Slice(0, diglen)); } } return(inc.TryFinish(buff, out int len) ? buff.Slice(0, len).ToArray() : Array.Empty <byte>()); }
public static void WireguardTest() { var protocol = new Protocol( HandshakePattern.IK, CipherFunction.ChaChaPoly, HashFunction.Blake2s, PatternModifiers.Psk2 ); var buffer = new byte[Protocol.MaxMessageLength]; var buffer2 = new byte[Protocol.MaxMessageLength]; int bufferRead = 0; using (var hs = protocol.Create(true, new ReadOnlySpan <byte>(Encoding.UTF8.GetBytes("WireGuard v1 zx2c4 [email protected]")), OurPrivate, TheirPublic, new byte[][] { Preshared })) { var now = DateTimeOffset.UtcNow; //replace with Noda.Time? var tai64n = new byte[12]; (4611686018427387914ul + (ulong)now.ToUnixTimeSeconds()).ToBigEndian(tai64n); ((uint)(now.Millisecond * 1e6)).ToBigEndian(tai64n, 8); var initiationPacket = new List <byte> { 1, 0, 0, 0 }; //type initiation initiationPacket.AddRange(((uint)28).ToLittleEndian()); //sender, random 4byte var(bytesWritten, _, _) = hs.WriteMessage(tai64n, buffer); initiationPacket.AddRange(buffer.Take(bytesWritten)); // should be 24byte, ephemeral, static, timestamp var hasher = Blake2s.CreateIncrementalHasher(32); var hashThis = Encoding.UTF8.GetBytes("mac1----").Concat(TheirPublic).ToArray(); hasher.Update(hashThis); var finishedHash = hasher.Finish(); hasher = Blake2s.CreateIncrementalHasher(16, finishedHash); hashThis = initiationPacket.ToArray(); hasher.Update(hashThis); finishedHash = hasher.Finish(); initiationPacket.AddRange(finishedHash); //mac1 initiationPacket.AddRange(Enumerable.Repeat((byte)0, 16)); //mac2 = zeros if no cookie last received var socket = new DatagramSocket(); var responsePacket = new TaskCompletionSource <int>(); var autoResetEvent = new AutoResetEvent(false); socket.MessageReceived += (sender, args) => { bufferRead = args.GetDataStream().AsStreamForRead().Read(buffer); autoResetEvent.Set(); }; socket.ConnectAsync(new HostName("demo.wireguard.com"), "12913").AsTask().Wait(); var streamWriter = new BinaryWriter(socket.OutputStream.AsStreamForWrite()); streamWriter.Write(initiationPacket.ToArray()); streamWriter.Flush(); var successful = autoResetEvent.WaitOne(5000); if (!successful) { return; } if (buffer[0] != 2) //type init response { return; //"response packet type wrong: want %d, got %d" } if (bufferRead != 92) //always this length! for type=2 { return; //"response packet too short: want %d, got %d" } if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0) { return; //"response packet has non-zero reserved fields" } var theirIndex = buffer.LittleEndianToUInt32(4); var ourIndex = buffer.LittleEndianToUInt32(8); if (ourIndex != 28) { return; //log.Fatalf("response packet index wrong: want %d, got %d", 28, ourIndex) } var span = new Span <byte>(buffer); var(bytesRead, handshakeHash, transport) = hs.ReadMessage(span.Slice(12, 48), span.Slice(100)); //write on same buffer behind the received package (which if (bytesRead != 0) { return; //"unexpected payload: %x" } var icmpHeader = new IcmpHeader() { Type = 8, Id = 921, Sequence = 438 }; var pingMessage = icmpHeader.GetProtocolPacketBytes(Encoding.UTF8.GetBytes("WireGuard")); var pingHeader = new Ipv4Header() { Version = 4, Length = 20, TotalLength = (ushort)(20 + pingMessage.Length), Protocol = 1, Ttl = 20, SourceAddress = new IPAddress(new byte[] { 10, 189, 129, 2 }), DestinationAddress = new IPAddress(new byte[] { 10, 189, 129, 1 }) }.GetProtocolPacketBytes(new byte[0]); span[0] = 4; span.Slice(1, 3).Assign((byte)0); theirIndex.ToLittleEndian(buffer, 4); 0L.ToLittleEndian(buffer, 8); //this is the counter, little endian u64 bytesWritten = transport.WriteMessage( pingHeader.Concat(pingMessage).Concat(Enumerable.Repeat((byte)0, 11)).ToArray(), //pad message with 0 to make mod 16=0 span.Slice(16)); //using (var streamWriter = new BinaryWriter(socket.OutputStream.AsStreamForWrite())) streamWriter.Write(span.Slice(0, 16 + bytesWritten).ToArray()); streamWriter.Flush(); successful = autoResetEvent.WaitOne(5000); if (!successful) { return; } if (buffer[0] != 4) { return;//"response packet type wrong: want %d, got %d" } if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0) { return; //"response packet has non-zero reserved fields" } var replyPacket = buffer2.AsSpan(0, transport.ReadMessage(span.Slice(16, bufferRead - 16), buffer2)); if (replyPacket.Length != 48) { return; } var replyHeaderLen = ((int)(replyPacket[0] & 0x0f)) << 2; var replyLen = buffer2.BigEndianToUInt16(2); var our_index_received = buffer.LittleEndianToUInt32(4); if (our_index_received != 28) { return; } var nonce = buffer2.LittleEndianToUInt64(8); //if (nonce != 0)//not parsed correctly? // return; var replyMessage = IcmpHeader.Create(buffer2.AsSpan(replyHeaderLen, replyLen - replyHeaderLen).ToArray(), ref bytesRead); if (replyMessage.Type != 0 || replyMessage.Code != 0) { return; } if (replyMessage.Id != 921 || replyMessage.Sequence != 438) { return; } var replyPayload = Encoding.UTF8.GetString(buffer2.AsSpan(replyLen - replyHeaderLen + bytesRead, replyHeaderLen - bytesRead)); if (replyPayload != "WireGuard") //trim necessary? { return; } } }
public void KatBlake2sKeyed(KatEntry ka) { var hash = compute(Blake2s.CreateIncrementalHasher(ka.Key), ka.Data); Assert.True(hash.SequenceEqual(ka.Digest)); }