diff --git a/Meshtastic.Test/Crypto/XEdDSASigningTests.cs b/Meshtastic.Test/Crypto/XEdDSASigningTests.cs index 9f51479..aef385e 100644 --- a/Meshtastic.Test/Crypto/XEdDSASigningTests.cs +++ b/Meshtastic.Test/Crypto/XEdDSASigningTests.cs @@ -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() { @@ -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); @@ -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); @@ -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); @@ -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] diff --git a/Meshtastic/Crypto/XEdDSASigning.cs b/Meshtastic/Crypto/XEdDSASigning.cs index a94ec17..7726c10 100644 --- a/Meshtastic/Crypto/XEdDSASigning.cs +++ b/Meshtastic/Crypto/XEdDSASigning.cs @@ -6,6 +6,9 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Math; using System.Text; +using Meshtastic.Protobufs; +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Crypto.Digests; namespace Meshtastic.Crypto; @@ -31,6 +34,73 @@ public static (byte[] edPrivateKey, byte[] edPublicKey) GenerateSigningKeyPair() return (privateKey, publicKey); } + /* + * Reflected private methods from BouncyCastle's Org.BouncyCastle.Math.EC.Rfc8032.Ed25519 used directly, + * because proper public methods differ in implementation details from those in Meshtastic firmware. + * Using those methods seems less wrong than to re-implement them here. + */ + private static Action? ed25519_ScalarMultBaseEncoded; + private static Action? ed25519_ImplSign; + + private static void Ed25519_ScalarMultBaseEncoded(byte[] k, byte[] r, int rOff) + { + if (ed25519_ScalarMultBaseEncoded == null) + { + var method = typeof(Ed25519).GetMethod("ScalarMultBaseEncoded", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static, [typeof(byte[]), typeof(byte[]), typeof(int)]); + if (method == null) throw new InvalidOperationException("Reflected private method \"ScalarMultBaseEncoded\" in \"Org.BouncyCastle.Math.EC.Rfc8032.Ed25519\" not found."); + ed25519_ScalarMultBaseEncoded = (Action)method.CreateDelegate(typeof(Action)); + } + + ed25519_ScalarMultBaseEncoded(k, r, rOff); + } + + private static void Ed25519_ImplSign(IDigest d, byte[] h, byte[] s, byte[] pk, int pkOff, byte[]? ctx, byte phflag, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + { + if (ed25519_ImplSign == null) + { + var method = typeof(Ed25519) + .GetMethod("ImplSign", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static, + [ + typeof(IDigest), + typeof(byte[]), + typeof(byte[]), + typeof(byte[]), + typeof(int), + typeof(byte[]), + typeof(byte), + typeof(byte[]), + typeof(int), + typeof(int), + typeof(byte[]), + typeof(int) + ]); + if (method == null) throw new InvalidOperationException("Reflected private method \"ImplSign\" in \"Org.BouncyCastle.Math.EC.Rfc8032.Ed25519\" not found."); + ed25519_ImplSign = (Action)method.CreateDelegate(typeof(Action)); + } + + ed25519_ImplSign(d, h, s, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + private static byte[] GeneratePublicKeyFromPrivateKey(byte[] ed25519PrivateKey) + { + /* + * Normally the public key should be obtained by calling: + * new Ed25519PrivateKeyParameters(ed25519PrivateKey).GeneratePublicKey().GetEncoded() + * but in firmware's function XEdDSA::priv_curve_to_ed_keys private key is used as-is + * as a scalar, while BouncyCastle's GeneratePublicKey first passes private key material + * through SHA512 to obtain 64-byte seed, of which 2nd half is used as a scalar and multiplied + * by curve's base point to obtain public key. + * + * Reimplementing field multiplication, as provided by ScalarMultBaseEncoded, in this project + * seems pointless - hence use of reflection to gain access to this primitive to generate + * a public key directly from provided material. + */ + + var ed25519PublicKey = new byte[32]; + Ed25519_ScalarMultBaseEncoded(ed25519PrivateKey, ed25519PublicKey, 0); + return ed25519PublicKey; + } + /// /// Generate Ed25519 keys from an X25519 private key (simplified for demo) /// @@ -41,32 +111,37 @@ public static (byte[] edPrivateKey, byte[] edPublicKey) GenerateEdDSAKeysFromX25 if (x25519PrivateKey.Length != 32) throw new ArgumentException("X25519 private key must be 32 bytes", nameof(x25519PrivateKey)); - // For simplicity, use the X25519 key as seed for Ed25519 key generation - // In a full XEdDSA implementation, this would use proper key derivation - var hashedSeed = SHA256.HashData(x25519PrivateKey); - - var keyPairGen = new Ed25519KeyPairGenerator(); - var secureRandom = new SecureRandom(); - secureRandom.SetSeed(hashedSeed); - keyPairGen.Init(new KeyGenerationParameters(secureRandom, 256)); - - var keyPair = keyPairGen.GenerateKeyPair(); - // Proper XEdDSA key derivation with domain separation - // Ed25519 seed = SHA-512("XEdDSA" || x25519PrivateKey)[0..31] - byte[] domain = Encoding.ASCII.GetBytes("XEdDSA"); - byte[] input = new byte[domain.Length + x25519PrivateKey.Length]; - Buffer.BlockCopy(domain, 0, input, 0, domain.Length); - Buffer.BlockCopy(x25519PrivateKey, 0, input, domain.Length, x25519PrivateKey.Length); - byte[] hash = SHA512.HashData(input); - byte[] ed25519Seed = new byte[32]; - Array.Copy(hash, 0, ed25519Seed, 0, 32); - - // Create Ed25519 private key from seed - var edPrivateKeyParam = new Ed25519PrivateKeyParameters(ed25519Seed, 0); - var edPublicKeyParam = edPrivateKeyParam.GeneratePublicKey(); - var privateKey = edPrivateKeyParam.GetEncoded(); - var publicKey = edPublicKeyParam.GetEncoded(); - return (privateKey, publicKey); + var ed25519PrivateKey = new byte[32]; + Array.Copy(x25519PrivateKey, ed25519PrivateKey, ed25519PrivateKey.Length); + + // Clamp X25519 + ed25519PrivateKey[0] &= 0xF8; + ed25519PrivateKey[31] &= 0x7F; + ed25519PrivateKey[31] |= 0x40; + + var x25519PublicKey = PKIEncryption.GetPublicKeyFromPrivateKey(x25519PrivateKey); + var ed25519PublicKey = GeneratePublicKeyFromPrivateKey(ed25519PrivateKey); + + // If resulting public key is positive, return as-is + if ((ed25519PublicKey[31] & 0x80) == 0) return (ed25519PrivateKey, ed25519PublicKey); + + // Ed25519 Group Order + var L = new BigInteger("7237005577332262213973186563042994240857116359379907606001950938285454250989"); + + // Negate private key + var privateKeyScalar = new BigInteger(1, ed25519PrivateKey.Reverse().ToArray()); + var negatedPrivateKeyScalar = L.Subtract(privateKeyScalar.Mod(L)); + var negatedPrivateKeyBytes = negatedPrivateKeyScalar.ToByteArrayUnsigned(); + byte[] negatedPrivateKey = new byte[32]; + for (int i = 0; i < negatedPrivateKeyBytes.Length && i < 32; i++) + { + negatedPrivateKey[i] = negatedPrivateKeyBytes[negatedPrivateKeyBytes.Length - 1 - i]; + } + + // Recompute public key from negated privated key + var negatedPublicKey = GeneratePublicKeyFromPrivateKey(negatedPrivateKey); + + return (negatedPrivateKey, negatedPublicKey); } /// @@ -74,23 +149,11 @@ public static (byte[] edPrivateKey, byte[] edPublicKey) GenerateEdDSAKeysFromX25 /// /// 32-byte X25519 public key /// 32-byte Ed25519 public key - public static byte[] ConvertX25519PublicKeyToEd25519(byte[] x25519PublicKey) + public static byte[] ConvertX25519PublicKeyToEd25519(byte[] x25519PublicKey, bool forcePositive = false) { if (x25519PublicKey.Length != 32) throw new ArgumentException("X25519 public key must be 32 bytes", nameof(x25519PublicKey)); - // Simplified conversion - in practice would use proper birational map - // For demo purposes, derive deterministic Ed25519 key from X25519 key - var hashedKey = SHA256.HashData(x25519PublicKey); - - var keyPairGen = new Ed25519KeyPairGenerator(); - var secureRandom = new SecureRandom(); - secureRandom.SetSeed(hashedKey); - keyPairGen.Init(new KeyGenerationParameters(secureRandom, 256)); - - var keyPair = keyPairGen.GenerateKeyPair(); - var edPublicKey = ((Ed25519PublicKeyParameters)keyPair.Public).GetEncoded(); - // Clear the sign bit (bit 7 of the last byte) as per Ed25519 specification // Implements the birational map from Montgomery (X25519) u to Edwards (Ed25519) y: // y = (u - 1) / (u + 1) mod p @@ -125,33 +188,80 @@ public static byte[] ConvertX25519PublicKeyToEd25519(byte[] x25519PublicKey) // If yBytes is shorter than 32 bytes, the rest is already zero // Set the sign bit to 0 (positive x) - edPublicKeyResult[31] &= 0x7F; + if (forcePositive) edPublicKeyResult[31] &= 0x7F; return edPublicKeyResult; } + private static byte[] BuildSigningBuffer(MeshPacket meshPacket) + { + return [ + ..BitConverter.GetBytes(meshPacket.From), + ..BitConverter.GetBytes(meshPacket.Id), + ..BitConverter.GetBytes((uint)meshPacket.Decoded.Portnum), + ..meshPacket.Decoded.Payload.ToByteArray() + ]; + } + + /// + /// Verify MeshPacket signature using provided node's X25519 public key. + /// + /// Public key of sender node. + /// Packet to verify. + /// True is packet signature is valid + public static bool VerifyPacketSignature(byte[] senderPublicKey, MeshPacket meshPacket) + { + var message = BuildSigningBuffer(meshPacket); + var signature = meshPacket.Decoded.XeddsaSignature.ToByteArray(); + var edPublicKey = ConvertX25519PublicKeyToEd25519(senderPublicKey); + return Verify(message, signature, edPublicKey); + } + + /// + /// Adds a signature to provided MeshPacket. + /// + /// Private X25519 key of packet sender. + /// Packet to sign. + public static void AddPacketSignature(byte[] senderPrivateKey, MeshPacket meshPacket) + { + var message = BuildSigningBuffer(meshPacket); + var (edPrivateKey, edPublicKey) = GenerateEdDSAKeysFromX25519(senderPrivateKey); + var signature = Sign(message, edPrivateKey, edPublicKey); + meshPacket.Decoded.XeddsaSignature = Google.Protobuf.ByteString.CopyFrom(signature); + } + /// /// Sign a message using Ed25519 /// /// Message to sign /// Ed25519 private key - /// Use SHA-256 instead of SHA-512 for hashing before signing + /// Ed25519 public key /// 64-byte signature - public static byte[] Sign(byte[] message, byte[] edPrivateKey, byte[] edPublicKey, bool useShortHash = true) + public static byte[] Sign(byte[] message, byte[] edPrivateKey, byte[] edPublicKey) { if (message == null) throw new ArgumentNullException(nameof(message)); if (edPrivateKey.Length != 32) throw new ArgumentException("Ed25519 private key must be 32 bytes", nameof(edPrivateKey)); + var signature = new byte[64]; + /* + * Ed25519Signer computes public key from private key differently than firmware (see comment for GeneratePublicKeyFromPrivateKey) + * and causes signature verification by actual radios to fail, so instead use Ed25519 primitive directly, explicitly passing + * public key computed derived as in XEdDSA::priv_curve_to_ed_keys. + * + * Also, Ed25519.Sign passes sk (private key) through SHA-512 before feeding it to actual ImplSign, which for some reason + * later fails to verify both by firmware and by Ed25519.Verify. + * + * The following code is inlined from BouncyCastle's Ed25519 class, method: + * private static void ImplSign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte phflag, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + */ - // Hash the message using the selected algorithm - var messageHash = useShortHash ? SHA256.HashData(message) : SHA512.HashData(message); + var digest = new Sha512Digest(); + var h = new byte[64]; - // Create Ed25519 signer - var signer = new Ed25519Signer(); - var privateKeyParams = new Ed25519PrivateKeyParameters(edPrivateKey, 0); - - signer.Init(true, privateKeyParams); - signer.BlockUpdate(messageHash, 0, messageHash.Length); - - return signer.GenerateSignature(); + digest.BlockUpdate(edPrivateKey, 0, 32); + digest.DoFinal(h, 0); + + Ed25519_ImplSign(digest, h, edPrivateKey /* original argument: s, scalar computed from h */, edPublicKey, 0, null, 0, message, 0, message.Length, signature, 0); + + return signature; } /// @@ -160,32 +270,13 @@ public static byte[] Sign(byte[] message, byte[] edPrivateKey, byte[] edPublicKe /// Original message /// 64-byte signature /// Ed25519 public key of the signer - /// Use SHA-256 instead of SHA-512 for hashing /// True if signature is valid - public static bool Verify(byte[] message, byte[] signature, byte[] edPublicKey, bool useShortHash = true) + public static bool Verify(byte[] message, byte[] signature, byte[] edPublicKey) { if (message == null) throw new ArgumentNullException(nameof(message)); if (signature == null || signature.Length != 64) throw new ArgumentException("Signature must be 64 bytes", nameof(signature)); if (edPublicKey == null || edPublicKey.Length != 32) throw new ArgumentException("Ed25519 public key must be 32 bytes", nameof(edPublicKey)); - - try - { - // Hash the message using the selected algorithm - var messageHash = useShortHash ? SHA256.HashData(message) : SHA512.HashData(message); - - // Create Ed25519 verifier - var verifier = new Ed25519Signer(); - var publicKeyParams = new Ed25519PublicKeyParameters(edPublicKey, 0); - - verifier.Init(false, publicKeyParams); - verifier.BlockUpdate(messageHash, 0, messageHash.Length); - - return verifier.VerifySignature(signature); - } - catch - { - return false; - } + return Ed25519.Verify(signature, 0, edPublicKey, 0, message, 0, message.Length); } /// @@ -196,13 +287,13 @@ public static bool Verify(byte[] message, byte[] signature, byte[] edPublicKey, /// X25519 public key of the signer /// Use SHA-256 instead of SHA-512 for verification /// True if signature is valid - public static bool VerifyWithX25519Key(byte[] message, byte[] signature, byte[] x25519PublicKey, bool useShortHash = true) + public static bool VerifyWithX25519Key(byte[] message, byte[] signature, byte[] x25519PublicKey) { try { // Convert X25519 public key to Ed25519 public key var edPublicKey = ConvertX25519PublicKeyToEd25519(x25519PublicKey); - return Verify(message, signature, edPublicKey, useShortHash); + return Verify(message, signature, edPublicKey); } catch { diff --git a/Meshtastic/Data/MessageFactories/NodeInfoMessageFactory.cs b/Meshtastic/Data/MessageFactories/NodeInfoMessageFactory.cs index e4cad69..5000c3f 100644 --- a/Meshtastic/Data/MessageFactories/NodeInfoMessageFactory.cs +++ b/Meshtastic/Data/MessageFactories/NodeInfoMessageFactory.cs @@ -17,13 +17,11 @@ public static class NodeInfoMessageFactory /// Device state containing configuration /// User information to broadcast /// Whether to sign the packet with XEdDSA - /// Use SHA-256 instead of SHA-512 for signatures /// MeshPacket containing the NodeInfo public static MeshPacket CreateNodeInfoMessage( DeviceStateContainer deviceStateContainer, User user, - bool signPacket = false, - bool useShortHash = true) + bool signPacket = false) { if (deviceStateContainer == null) throw new ArgumentNullException(nameof(deviceStateContainer)); @@ -55,7 +53,7 @@ public static MeshPacket CreateNodeInfoMessage( { try { - AddXEdDSASignature(meshPacket, deviceStateContainer, useShortHash); + AddXEdDSASignature(meshPacket, deviceStateContainer); } catch (Exception) { @@ -106,12 +104,10 @@ public static User CreateTestUser( /// /// Received mesh packet /// Public key of the sender - /// Use SHA-256 instead of SHA-512 /// True if signature is valid public static bool VerifyNodeInfoSignature( MeshPacket meshPacket, - byte[] senderPublicKey, - bool useShortHash = true) + byte[] senderPublicKey) { if (meshPacket?.Decoded?.Payload == null) return false; @@ -127,7 +123,7 @@ public static bool VerifyNodeInfoSignature( // For now, we'll demonstrate the verification process var mockSignature = new byte[64]; // This would come from the packet - return XEdDSASigning.Verify(payload, mockSignature, senderPublicKey, useShortHash); + return XEdDSASigning.Verify(payload, mockSignature, senderPublicKey); } catch { @@ -142,7 +138,7 @@ private static bool HasSigningCapability(DeviceStateContainer deviceStateContain return deviceStateContainer.LocalConfig?.Security?.PublicKey != null; } - private static void AddXEdDSASignature(MeshPacket meshPacket, DeviceStateContainer deviceStateContainer, bool useShortHash) + private static void AddXEdDSASignature(MeshPacket meshPacket, DeviceStateContainer deviceStateContainer) { if (meshPacket.Decoded?.Payload == null) return; @@ -157,7 +153,7 @@ private static void AddXEdDSASignature(MeshPacket meshPacket, DeviceStateContain // Sign the payload var payload = meshPacket.Decoded.Payload.ToByteArray(); - var signature = XEdDSASigning.Sign(payload, edPrivateKey, edPublicKey, useShortHash); + var signature = XEdDSASigning.Sign(payload, edPrivateKey, edPublicKey); // Note: In the actual implementation, we would add the signature to the packet // For now, we'll store it in a custom field or metadata @@ -200,14 +196,12 @@ public static NodeInfoPayloadAnalysis AnalyzePayloadSizes(User user) var signedSha256Packet = CreateNodeInfoMessage( deviceStateContainer: testDeviceState, user: user, - signPacket: true, - useShortHash: true); + signPacket: true); var signedSha512Packet = CreateNodeInfoMessage( deviceStateContainer: testDeviceState, user: user, - signPacket: true, - useShortHash: false); + signPacket: true); // Since signing currently fails silently due to no private key, // we'll simulate the signature overhead by creating packets with mock signatures