-
-
Notifications
You must be signed in to change notification settings - Fork 940
/
Copy pathED25519Key.cs
132 lines (116 loc) · 3.95 KB
/
ED25519Key.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using System;
using System.Numerics;
using Org.BouncyCastle.Math.EC.Rfc8032;
using Renci.SshNet.Common;
using Renci.SshNet.Security.Cryptography;
namespace Renci.SshNet.Security
{
/// <summary>
/// Contains ED25519 private and public key.
/// </summary>
public class ED25519Key : Key, IDisposable
{
private ED25519DigitalSignature _digitalSignature;
private bool _isDisposed;
/// <summary>
/// Gets the name of the key.
/// </summary>
/// <returns>
/// The name of the key.
/// </returns>
public override string ToString()
{
return "ssh-ed25519";
}
/// <summary>
/// Gets the Ed25519 public key.
/// </summary>
/// <value>
/// An array with <see cref="PublicKey"/> encoded at index 0.
/// </value>
public override BigInteger[] Public
{
get
{
return new BigInteger[] { PublicKey.ToBigInteger2() };
}
}
/// <inheritdoc/>
public override int KeyLength
{
get
{
return Ed25519.PublicKeySize * 8;
}
}
/// <summary>
/// Gets the digital signature.
/// </summary>
protected internal override DigitalSignature DigitalSignature
{
get
{
_digitalSignature ??= new ED25519DigitalSignature(this);
return _digitalSignature;
}
}
/// <summary>
/// Gets the PublicKey Bytes.
/// </summary>
public byte[] PublicKey { get; }
/// <summary>
/// Gets the PrivateKey Bytes.
/// </summary>
public byte[] PrivateKey { get; }
/// <summary>
/// Initializes a new instance of the <see cref="ED25519Key"/> class.
/// </summary>
/// <param name="publicKeyData">The encoded public key data.</param>
public ED25519Key(SshKeyData publicKeyData)
{
ThrowHelper.ThrowIfNull(publicKeyData);
if (publicKeyData.Name != "ssh-ed25519" || publicKeyData.Keys.Length != 1)
{
throw new ArgumentException($"Invalid Ed25519 public key data ({publicKeyData.Name}, {publicKeyData.Keys.Length}).", nameof(publicKeyData));
}
PublicKey = publicKeyData.Keys[0].ToByteArray(isBigEndian: true).TrimLeadingZeros().Pad(Ed25519.PublicKeySize);
PrivateKey = new byte[Ed25519.SecretKeySize];
}
/// <summary>
/// Initializes a new instance of the <see cref="ED25519Key"/> class.
/// </summary>
/// <param name="privateKeyData">
/// The private key data <c>k || ENC(A)</c> as described in RFC 8032.
/// </param>
public ED25519Key(byte[] privateKeyData)
{
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>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="disposing"><see langword="true"/> to release both managed and unmanaged resources; <see langword="false"/> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (_isDisposed)
{
return;
}
if (disposing)
{
_isDisposed = true;
}
}
}
}