cacfc06088
Port From (https://github.com/TrinityCore/TrinityCore/commit/20f38369f30309e2c0cd53eca9cfe9c49376ed8c)
133 lines
5.9 KiB
C#
133 lines
5.9 KiB
C#
using System;
|
|
using Framework.Cryptography.Ed25519.Internal.Ed25519Ref10;
|
|
using System.Diagnostics.Contracts;
|
|
|
|
namespace Framework.Cryptography.Ed25519
|
|
{
|
|
public static class Ed25519
|
|
{
|
|
/// <summary>
|
|
/// Public Keys are 32 byte values. All possible values of this size a valid.
|
|
/// </summary>
|
|
public const int PublicKeySize = 32;
|
|
/// <summary>
|
|
/// Signatures are 64 byte values
|
|
/// </summary>
|
|
public const int SignatureSize = 64;
|
|
/// <summary>
|
|
/// Private key seeds are 32 byte arbitrary values. This is the form that should be generated and stored.
|
|
/// </summary>
|
|
public const int PrivateKeySeedSize = 32;
|
|
/// <summary>
|
|
/// A 64 byte expanded form of private key. This form is used internally to improve performance
|
|
/// </summary>
|
|
public const int ExpandedPrivateKeySize = 32 * 2;
|
|
|
|
/// <summary>
|
|
/// Verify Ed25519 signature
|
|
/// </summary>
|
|
/// <param name="signature">Signature bytes</param>
|
|
/// <param name="message">Message</param>
|
|
/// <param name="publicKey">Public key</param>
|
|
/// <returns>True if signature is valid, false if it's not</returns>
|
|
public static bool Verify(ArraySegment<byte> signature, ArraySegment<byte> message, ArraySegment<byte> publicKey, int phflag = -1, byte[] ctx = null)
|
|
{
|
|
return Ed25519Operations.crypto_sign_verify(signature.Array, signature.Offset, message.Array, message.Offset, message.Count, publicKey.Array, publicKey.Offset, phflag, ctx);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verify Ed25519 signature
|
|
/// </summary>
|
|
/// <param name="signature">Signature bytes</param>
|
|
/// <param name="message">Message</param>
|
|
/// <param name="publicKey">Public key</param>
|
|
/// <returns>True if signature is valid, false if it's not</returns>
|
|
public static bool Verify(byte[] signature, byte[] message, byte[] publicKey, int phflag = -1, byte[] ctx = null)
|
|
{
|
|
return Ed25519Operations.crypto_sign_verify(signature, 0, message, 0, message.Length, publicKey, 0, phflag, ctx);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create new Ed25519 signature
|
|
/// </summary>
|
|
/// <param name="signature">Buffer for signature</param>
|
|
/// <param name="message">Message bytes</param>
|
|
/// <param name="expandedPrivateKey">Expanded form of private key</param>
|
|
public static void Sign(ArraySegment<byte> signature, ArraySegment<byte> message, ArraySegment<byte> expandedPrivateKey, int phflag = -1, byte[] ctx = null)
|
|
{
|
|
Ed25519Operations.crypto_sign(signature.Array, signature.Offset, message.Array, message.Offset, message.Count, expandedPrivateKey.Array, expandedPrivateKey.Offset, phflag, ctx);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create new Ed25519 signature
|
|
/// </summary>
|
|
/// <param name="signature">Buffer for signature</param>
|
|
/// <param name="message">Message bytes</param>
|
|
/// <param name="expandedPrivateKey">Expanded form of private key</param>
|
|
public static byte[] Sign(byte[] message, byte[] expandedPrivateKey, int phflag = -1, byte[] ctx = null)
|
|
{
|
|
var signature = new byte[SignatureSize];
|
|
Sign(new ArraySegment<byte>(signature), new ArraySegment<byte>(message), new ArraySegment<byte>(expandedPrivateKey), phflag, ctx);
|
|
return signature;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculate public key from private key seed
|
|
/// </summary>
|
|
/// <param name="privateKeySeed">Private key seed value</param>
|
|
/// <returns></returns>
|
|
public static byte[] PublicKeyFromSeed(byte[] privateKeySeed)
|
|
{
|
|
byte[] privateKey;
|
|
byte[] publicKey;
|
|
KeyPairFromSeed(out publicKey, out privateKey, privateKeySeed);
|
|
CryptoBytes.Wipe(privateKey);
|
|
return publicKey;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculate expanded form of private key from the key seed.
|
|
/// </summary>
|
|
/// <param name="privateKeySeed">Private key seed value</param>
|
|
/// <returns>Expanded form of the private key</returns>
|
|
public static byte[] ExpandedPrivateKeyFromSeed(byte[] privateKeySeed)
|
|
{
|
|
byte[] privateKey;
|
|
byte[] publicKey;
|
|
KeyPairFromSeed(out publicKey, out privateKey, privateKeySeed);
|
|
CryptoBytes.Wipe(publicKey);
|
|
return privateKey;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculate key pair from the key seed.
|
|
/// </summary>
|
|
/// <param name="publicKey">Public key</param>
|
|
/// <param name="expandedPrivateKey">Expanded form of the private key</param>
|
|
/// <param name="privateKeySeed">Private key seed value</param>
|
|
public static void KeyPairFromSeed(out byte[] publicKey, out byte[] expandedPrivateKey, byte[] privateKeySeed)
|
|
{
|
|
var pk = new byte[PublicKeySize];
|
|
var sk = new byte[ExpandedPrivateKeySize];
|
|
|
|
Ed25519Operations.crypto_sign_keypair(pk, 0, sk, 0, privateKeySeed, 0);
|
|
publicKey = pk;
|
|
expandedPrivateKey = sk;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculate key pair from the key seed.
|
|
/// </summary>
|
|
/// <param name="publicKey">Public key</param>
|
|
/// <param name="expandedPrivateKey">Expanded form of the private key</param>
|
|
/// <param name="privateKeySeed">Private key seed value</param>
|
|
public static void KeyPairFromSeed(ArraySegment<byte> publicKey, ArraySegment<byte> expandedPrivateKey, ArraySegment<byte> privateKeySeed)
|
|
{
|
|
Ed25519Operations.crypto_sign_keypair(
|
|
publicKey.Array, publicKey.Offset,
|
|
expandedPrivateKey.Array, expandedPrivateKey.Offset,
|
|
privateKeySeed.Array, privateKeySeed.Offset);
|
|
}
|
|
}
|
|
}
|