Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 53 additions & 17 deletions Meshtastic.Test/Crypto/XEdDSASigningTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,26 @@ public void ConvertX25519PublicKeyToEd25519_Should_ProduceValidEdPublicKey()
Assert.That(edPublicKey[31] & 0x80, Is.EqualTo(0)); // Sign bit should be 0
}

[Test]
public void ConvertX25519PublicKeyToEd25519_Should_EqualToGenerateEdDSAKeysFromX25519_Positive()
{
var x25519PrivateKey = Convert.FromBase64String("+ATTWKM68dlArUzWrXWlQm45Gi3ZYrOdDt2z5VT5+2o=");
var x25519PublicKey = PKIEncryption.GetPublicKeyFromPrivateKey(x25519PrivateKey);
var edPublicKeyFromPublic = XEdDSASigning.ConvertX25519PublicKeyToEd25519(x25519PublicKey);
var (_, edPublicKeyFromPrivate) = XEdDSASigning.GenerateEdDSAKeysFromX25519(x25519PrivateKey);
Assert.That(edPublicKeyFromPrivate, Is.EqualTo(edPublicKeyFromPublic));
}

[Test]
public void ConvertX25519PublicKeyToEd25519_Should_EqualToGenerateEdDSAKeysFromX25519_Negative()
{
var x25519PrivateKey = Convert.FromBase64String("wJNheemu5n2oPgpu0BpEdomsPlChBSM8gAO7RRWkT2w=");
var x25519PublicKey = PKIEncryption.GetPublicKeyFromPrivateKey(x25519PrivateKey);
var edPublicKeyFromPublic = XEdDSASigning.ConvertX25519PublicKeyToEd25519(x25519PublicKey);
var (_, edPublicKeyFromPrivate) = XEdDSASigning.GenerateEdDSAKeysFromX25519(x25519PrivateKey);
Assert.That(edPublicKeyFromPrivate, Is.EqualTo(edPublicKeyFromPublic));
}

[Test]
public void Sign_Should_ProduceValidSignature()
{
Expand All @@ -58,7 +78,7 @@ public void Sign_Should_ProduceValidSignature()
var (edPrivateKey, edPublicKey) = XEdDSASigning.GenerateEdDSAKeysFromX25519(_testPrivateKey);

// Act
var signature = XEdDSASigning.Sign(message, edPrivateKey, edPublicKey, useShortHash: true);
var signature = XEdDSASigning.Sign(message, edPrivateKey, edPublicKey);

// Assert
Assert.That(signature, Is.Not.Null);
Expand All @@ -72,10 +92,10 @@ public void Verify_Should_ReturnTrue_ForValidSignature()
// Arrange
var message = Encoding.UTF8.GetBytes("Test message for verification");
var (edPrivateKey, edPublicKey) = XEdDSASigning.GenerateEdDSAKeysFromX25519(_testPrivateKey);
var signature = XEdDSASigning.Sign(message, edPrivateKey, edPublicKey, useShortHash: true);
var signature = XEdDSASigning.Sign(message, edPrivateKey, edPublicKey);

// Act
var isValid = XEdDSASigning.Verify(message, signature, edPublicKey, useShortHash: true);
var isValid = XEdDSASigning.Verify(message, signature, edPublicKey);

// Assert
Assert.That(isValid, Is.True);
Expand All @@ -90,7 +110,7 @@ public void Verify_Should_ReturnFalse_ForInvalidSignature()
var (_, edPublicKey) = XEdDSASigning.GenerateEdDSAKeysFromX25519(_testPrivateKey);

// Act
var isValid = XEdDSASigning.Verify(message, invalidSignature, edPublicKey, useShortHash: true);
var isValid = XEdDSASigning.Verify(message, invalidSignature, edPublicKey);

// Assert
Assert.That(isValid, Is.False);
Expand All @@ -103,29 +123,45 @@ public void Verify_Should_ReturnFalse_ForTamperedMessage()
var originalMessage = Encoding.UTF8.GetBytes("Original message");
var tamperedMessage = Encoding.UTF8.GetBytes("Tampered message");
var (edPrivateKey, edPublicKey) = XEdDSASigning.GenerateEdDSAKeysFromX25519(_testPrivateKey);
var signature = XEdDSASigning.Sign(originalMessage, edPrivateKey, edPublicKey, useShortHash: true);
var signature = XEdDSASigning.Sign(originalMessage, edPrivateKey, edPublicKey);

// Act
var isValid = XEdDSASigning.Verify(tamperedMessage, signature, edPublicKey, useShortHash: true);
var isValid = XEdDSASigning.Verify(tamperedMessage, signature, edPublicKey);

// Assert
Assert.That(isValid, Is.False);
}

[TestCase(true)]
[TestCase(false)]
public void SignAndVerify_Should_Work_WithBothHashTypes(bool useShortHash)
[Test]
public void Verify_RealLife_ValidSignature()
{
// Arrange
var message = Encoding.UTF8.GetBytes("Test message for both hash types");
var (edPrivateKey, edPublicKey) = XEdDSASigning.GenerateEdDSAKeysFromX25519(_testPrivateKey);
var rawCapturedPacket = Convert.FromBase64String("DbVdZX4V/////xgVIkwIARIEVGVzdEgBUkDdbuxwz2lvDyBKpCW1ojj+pMPfnRfWiUsDwf1cwisx+82L7fA5/g5OW5LrpWfU4z73AHqysNLKBUOt3TfhBEQONXE20CI9ieBNakgHWGR4B5gBtQE=");
var senderPublicKey = Convert.FromBase64String("t0hKwMywRb2nKFOvVXcjFAGPWgCSta4ZwEkgPkgJWwM=");
var meshPacket = MeshPacket.Parser.ParseFrom(rawCapturedPacket);
var isValid = XEdDSASigning.VerifyPacketSignature(senderPublicKey, meshPacket);
Assert.That(isValid, Is.True);
}

// Act
var signature = XEdDSASigning.Sign(message, edPrivateKey, edPublicKey, useShortHash);
var isValid = XEdDSASigning.Verify(message, signature, edPublicKey, useShortHash);
[Test]
public void Verify_RealLife_InvalidPubkey()
{
var rawCapturedPacket = Convert.FromBase64String("DbVdZX4V/////xgVIkwIARIEVGVzdEgBUkDdbuxwz2lvDyBKpCW1ojj+pMPfnRfWiUsDwf1cwisx+82L7fA5/g5OW5LrpWfU4z73AHqysNLKBUOt3TfhBEQONXE20CI9ieBNakgHWGR4B5gBtQE=");
var senderPublicKey = Convert.FromBase64String("t0hKwMywRb2nKFOvVXcjFAGPWgCSta4ZwEkgPkgJWwM=");
senderPublicKey[0]++;
var meshPacket = MeshPacket.Parser.ParseFrom(rawCapturedPacket);
var isValid = XEdDSASigning.VerifyPacketSignature(senderPublicKey, meshPacket);
Assert.That(isValid, Is.False);
}

// Assert
Assert.That(isValid, Is.True);
[Test]
public void Verify_RealLife_TamperedMessage()
{
var rawCapturedPacket = Convert.FromBase64String("DbVdZX4V/////xgVIkwIARIEVGVzdEgBUkDdbuxwz2lvDyBKpCW1ojj+pMPfnRfWiUsDwf1cwisx+82L7fA5/g5OW5LrpWfU4z73AHqysNLKBUOt3TfhBEQONXE20CI9ieBNakgHWGR4B5gBtQE=");
var senderPublicKey = Convert.FromBase64String("t0hKwMywRb2nKFOvVXcjFAGPWgCSta4ZwEkgPkgJWwM=");
var meshPacket = MeshPacket.Parser.ParseFrom(rawCapturedPacket);
meshPacket.Decoded.Payload = Google.Protobuf.ByteString.CopyFromUtf8("Tampered");
var isValid = XEdDSASigning.VerifyPacketSignature(senderPublicKey, meshPacket);
Assert.That(isValid, Is.False);
}

[Test]
Expand Down
Loading
Loading