Skip to content

Commit

Permalink
Add some docs for Ed25519 signer and bump version
Browse files Browse the repository at this point in the history
  • Loading branch information
Deadpikle committed Jul 14, 2024
1 parent 047a6b8 commit a0303ad
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 17 deletions.
4 changes: 3 additions & 1 deletion Chaos.NaCl/Chaos.NaCl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFrameworks>net8.0;net7.0;net6.0;netstandard2.0;net462</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<OutputPath>bin\$(Configuration)\</OutputPath>
<Version>0.9.0</Version>
<Version>0.9.1</Version>
<Authors>Deadpikle, CodesInChaos</Authors>
<Description>See https://github.com/NetSparkleUpdater/Chaos.NaCl for package description. Used for NetSparkleUpdater ed25519 functionality.</Description>
<Copyright>Copyright 2024</Copyright>
Expand Down Expand Up @@ -35,9 +35,11 @@
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DocumentationFile>bin\Debug\Chaos.NaCl.xml</DocumentationFile>
<DebugType>full</DebugType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DocumentationFile>bin\Release\Chaos.NaCl.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<None Include="..\License.txt" Pack="true" PackagePath="\" />
Expand Down
78 changes: 62 additions & 16 deletions Chaos.NaCl/Ed25519Signer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,60 +6,97 @@
namespace Chaos.NaCl
{
/// <summary>
/// API and constants modified from BouncyCastle on 2024-07-13 (MIT)
/// Uses public key and EXPANDED private key (64 bytes) to
/// create signatures and verify signatures for data.
/// API modified from BouncyCastle on 2024-07-13 (MIT).
/// </summary>
public class Ed25519Signer : IDisposable
{
private const int CoordUints = 8;
private const int PointBytes = CoordUints * 4;
private const int ScalarUints = 8;
private const int ScalarBytes = ScalarUints * 4;

public static readonly int PrehashSize = 64;
public static readonly int PublicKeySize = PointBytes;
public static readonly int SecretKeySize = 32;
public static readonly int SignatureSize = PointBytes + ScalarBytes;

private readonly MemoryStream _buffer;
private byte[] _publicKey;
private byte[] _privateKey;

/// <summary>
/// A simple wrapper class around Ed25519 to assist in creating/validating ed25519 signatures
/// </summary>
public Ed25519Signer()
{
_buffer = new MemoryStream();
}

public virtual void Init(byte[] publicKey, byte[] privateKey)
/// <summary>
/// Initialize the Ed25519Signer with a public key and EXPANDED private key
/// </summary>
/// <param name="publicKey">32 byte public key</param>
/// <param name="expandedPrivateKey">64 byte expanded private key</param>
/// <exception cref="Exception">Throws exception if either key is the wrong length</exception>
public virtual void Init(byte[] publicKey, byte[] expandedPrivateKey)
{
if (publicKey != null && publicKey.Length != Ed25519.PublicKeySizeInBytes)
{
throw new Exception("Invalid public key length");
}
if (expandedPrivateKey != null && expandedPrivateKey.Length != Ed25519.ExpandedPrivateKeySizeInBytes)
{
throw new Exception("Invalid private key length");
}
_publicKey = publicKey;
_privateKey = expandedPrivateKey;
}

/// <summary>
/// Initialize the Ed25519Signer with a private key seed rather than the expanded private key
/// </summary>
/// <param name="publicKey">32 byte public key</param>
/// <param name="privateKey">32 byte private key (seed)</param>
/// <exception cref="Exception">Throws exception if either key is the wrong length</exception>
public virtual void InitWithNonExpandedPrivateKey(byte[] publicKey, byte[] privateKey)
{
if (publicKey != null && publicKey.Length != Ed25519.PublicKeySizeInBytes)
{
throw new Exception("Invalid public key length");
}
if (privateKey != null && privateKey.Length != Ed25519.ExpandedPrivateKeySizeInBytes)
if (privateKey != null && privateKey.Length != Ed25519.PrivateKeySeedSizeInBytes)
{
throw new Exception("Invalid private key length");
}
_publicKey = publicKey;
_privateKey = privateKey;
_privateKey = Ed25519.ExpandedPrivateKeyFromSeed(privateKey);
}

/// <summary>
/// Dispose of any memory as needed; Calls Reset()
/// </summary>
public void Dispose()
{
Reset();
}

/// <summary>
/// Add the given byte to the memory buffer
/// </summary>
/// <param name="b">The byte to append to the memory buffer</param>
public virtual void AddByteToBuffer(byte b)
{
_buffer.WriteByte(b);
}

/// <summary>
/// Add the given data in the given byte array to the memory buffer
/// </summary>
/// <param name="buf">Byte array with data in it</param>
/// <param name="off">Offset to start of data</param>
/// <param name="len">Length of data to add</param>
public virtual void AddToBuffer(byte[] buf, int off, int len)
{
_buffer.Write(buf, off, len);
}

public virtual int GetMaxSignatureSize() => SignatureSize;

/// <summary>
/// Generate a signature based on data in the buffer and the initialized private key
/// </summary>
/// <returns>An ed25519 signature for the current data</returns>
/// <exception cref="Exception">Throws if the private key is not an expanded private key</exception>
public virtual byte[] GenerateSignature()
{
if (_privateKey == null || _privateKey.Length != Ed25519.ExpandedPrivateKeySizeInBytes)
Expand All @@ -74,6 +111,12 @@ public virtual byte[] GenerateSignature()
}
}

/// <summary>
/// Verify the given signature against the data in the memory buffer and the public key
/// </summary>
/// <param name="signature">Signature to verify</param>
/// <returns>True if the signature is valid; false otherwise</returns>
/// <exception cref="Exception">Throws if the public key is not the appropriate length in bytes</exception>
public virtual bool VerifySignature(byte[] signature)
{
if (_publicKey == null || _publicKey.Length != Ed25519.PublicKeySizeInBytes)
Expand All @@ -88,6 +131,9 @@ public virtual bool VerifySignature(byte[] signature)
}
}

/// <summary>
/// Reset the in-memory data buffer by clearing it
/// </summary>
public virtual void Reset()
{
lock (_buffer)
Expand Down

0 comments on commit a0303ad

Please sign in to comment.