using System;
using Renci.SshNet.Common;
using Renci.SshNet.Security.Chaos.NaCl;
using Renci.SshNet.Security.Cryptography;
namespace Renci.SshNet.Security
{
///
/// Contains ED25519 private and public key.
///
public class ED25519Key : Key, IDisposable
{
private ED25519DigitalSignature _digitalSignature;
private byte[] _publicKey = new byte[Ed25519.PublicKeySizeInBytes];
#pragma warning disable IDE1006 // Naming Styles
private readonly byte[] privateKey = new byte[Ed25519.ExpandedPrivateKeySizeInBytes];
#pragma warning restore IDE1006 // Naming Styles
private bool _isDisposed;
///
/// Gets the Key String.
///
public override string ToString()
{
return "ssh-ed25519";
}
///
/// Gets or sets the public.
///
///
/// The public.
///
public override BigInteger[] Public
{
get
{
return new BigInteger[] { _publicKey.ToBigInteger2() };
}
set
{
_publicKey = value[0].ToByteArray().Reverse().TrimLeadingZeros().Pad(Ed25519.PublicKeySizeInBytes);
}
}
///
/// Gets the length of the key.
///
///
/// The length of the key.
///
public override int KeyLength
{
get
{
return PublicKey.Length * 8;
}
}
///
/// Gets the digital signature.
///
protected override DigitalSignature DigitalSignature
{
get
{
_digitalSignature ??= new ED25519DigitalSignature(this);
return _digitalSignature;
}
}
///
/// Gets the PublicKey Bytes.
///
public byte[] PublicKey
{
get
{
return _publicKey;
}
}
///
/// Gets the PrivateKey Bytes.
///
public byte[] PrivateKey
{
get
{
return privateKey;
}
}
///
/// Initializes a new instance of the class.
///
public ED25519Key()
{
}
///
/// Initializes a new instance of the class.
///
/// pk data.
public ED25519Key(byte[] pk)
{
_publicKey = pk.TrimLeadingZeros().Pad(Ed25519.PublicKeySizeInBytes);
}
///
/// Initializes a new instance of the class.
///
/// pk data.
/// sk data.
public ED25519Key(byte[] pk, byte[] sk)
{
_publicKey = pk.TrimLeadingZeros().Pad(Ed25519.PublicKeySizeInBytes);
var seed = new byte[Ed25519.PrivateKeySeedSizeInBytes];
Buffer.BlockCopy(sk, 0, seed, 0, seed.Length);
Ed25519.KeyPairFromSeed(out _publicKey, out privateKey, seed);
}
///
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
///
/// Releases unmanaged and - optionally - managed resources
///
/// true to release both managed and unmanaged resources; false to release only unmanaged resources.
protected virtual void Dispose(bool disposing)
{
if (_isDisposed)
{
return;
}
if (disposing)
{
_isDisposed = true;
}
}
///
/// Finalizes an instance of the class.
///
~ED25519Key()
{
Dispose(disposing: false);
}
}
}