Browse Source

Ed25519 is now based on BouncyCastle instead of Chaos.NaCl (#1448)

* Ed25519 is now based on BouncyCastle instead of Chaos.NaCl

* Generate PublicKey and fix NullReferenceException

* Rectify variable name

---------

Co-authored-by: Wojciech Nagórski <wojtpl2@gmail.com>
Scott Xu 1 year ago
parent
commit
28301ab329

+ 6 - 3
src/Renci.SshNet/Security/Cryptography/ED25519DigitalSignature.cs

@@ -1,7 +1,8 @@
 using System;
 
+using Org.BouncyCastle.Math.EC.Rfc8032;
+
 using Renci.SshNet.Common;
-using Renci.SshNet.Security.Chaos.NaCl;
 
 namespace Renci.SshNet.Security.Cryptography
 {
@@ -39,7 +40,7 @@ namespace Renci.SshNet.Security.Cryptography
         /// <exception cref="InvalidOperationException">Invalid signature.</exception>
         public override bool Verify(byte[] input, byte[] signature)
         {
-            return Ed25519.Verify(signature, input, _key.PublicKey);
+            return Ed25519.Verify(signature, 0, _key.PublicKey, 0, input, 0, input.Length);
         }
 
         /// <summary>
@@ -52,7 +53,9 @@ namespace Renci.SshNet.Security.Cryptography
         /// <exception cref="SshException">Invalid ED25519Key key.</exception>
         public override byte[] Sign(byte[] input)
         {
-            return Ed25519.Sign(input, _key.PrivateKey);
+            var signature = new byte[Ed25519.SignatureSize];
+            Ed25519.Sign(_key.PrivateKey, 0, _key.PublicKey, 0, input, 0, input.Length, signature, 0);
+            return signature;
         }
 
         /// <summary>

+ 8 - 9
src/Renci.SshNet/Security/Cryptography/ED25519Key.cs

@@ -1,7 +1,8 @@
 using System;
 
+using Org.BouncyCastle.Math.EC.Rfc8032;
+
 using Renci.SshNet.Common;
-using Renci.SshNet.Security.Chaos.NaCl;
 using Renci.SshNet.Security.Cryptography;
 
 namespace Renci.SshNet.Security
@@ -49,7 +50,7 @@ namespace Renci.SshNet.Security
         {
             get
             {
-                return PublicKey.Length * 8;
+                return Ed25519.PublicKeySize * 8;
             }
         }
 
@@ -91,8 +92,7 @@ namespace Renci.SshNet.Security
                 throw new ArgumentException($"Invalid Ed25519 public key data ({publicKeyData.Name}, {publicKeyData.Keys.Length}).", nameof(publicKeyData));
             }
 
-            PublicKey = publicKeyData.Keys[0].ToByteArray().Reverse().TrimLeadingZeros().Pad(Ed25519.PublicKeySizeInBytes);
-            PrivateKey = new byte[Ed25519.ExpandedPrivateKeySizeInBytes];
+            PublicKey = publicKeyData.Keys[0].ToByteArray().Reverse().TrimLeadingZeros().Pad(Ed25519.PublicKeySize);
         }
 
         /// <summary>
@@ -103,11 +103,10 @@ namespace Renci.SshNet.Security
         /// </param>
         public ED25519Key(byte[] privateKeyData)
         {
-            var seed = new byte[Ed25519.PrivateKeySeedSizeInBytes];
-            Buffer.BlockCopy(privateKeyData, 0, seed, 0, seed.Length);
-            Ed25519.KeyPairFromSeed(out var publicKey, out var privateKey, seed);
-            PublicKey = publicKey;
-            PrivateKey = privateKey;
+            PrivateKey = new byte[Ed25519.SecretKeySize];
+            PublicKey = new byte[Ed25519.PublicKeySize];
+            Buffer.BlockCopy(privateKeyData, 0, PrivateKey, 0, Ed25519.SecretKeySize);
+            Ed25519.GeneratePublicKey(privateKeyData, 0, PublicKey, 0);
         }
 
         /// <summary>

+ 3 - 2
src/Renci.SshNet/Security/SshKeyData.cs

@@ -1,8 +1,9 @@
 using System.Collections.Generic;
 using System.Text;
 
+using Org.BouncyCastle.Math.EC.Rfc8032;
+
 using Renci.SshNet.Common;
-using Renci.SshNet.Security.Chaos.NaCl;
 
 namespace Renci.SshNet.Security
 {
@@ -88,7 +89,7 @@ namespace Renci.SshNet.Security
                 var keyData = key.ToByteArray().Reverse();
                 if (Name == "ssh-ed25519")
                 {
-                    keyData = keyData.TrimLeadingZeros().Pad(Ed25519.PublicKeySizeInBytes);
+                    keyData = keyData.TrimLeadingZeros().Pad(Ed25519.PublicKeySize);
                 }
 
                 WriteBinaryString(keyData);