aboutsummaryrefslogtreecommitdiff
path: root/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2024-10-18 22:10:17 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2024-10-18 22:10:17 -0400
commit44044eb0fb28b774773e3284fd147c91d59d64e3 (patch)
tree429860e6ced91b02b7062f86c74120be5d5f0c11 /wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src
parent6a4a464d9fdc7821cd5c5695656a3fe385497cc5 (diff)
refactor: Wire up unit testing and refactor c# api
Diffstat (limited to 'wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src')
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCCipherUtil.cs (renamed from wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCUtilCipher.cs)65
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptMessageCipher.cs (renamed from wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptCipher.cs)63
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/INostrCrypto.cs88
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCKeyUtil.cs (renamed from wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCUtil.cs)120
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptExtensions.cs75
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptLibrary.cs56
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NostrCrypto.cs167
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Singatures/NCSignatureUtil.cs175
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Singatures/NoscryptSigner.cs (renamed from wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptSigner.cs)60
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/VNLib.Utils.Cryptography.Noscrypt.csproj24
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/internal/FunctionTable.cs2
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/internal/NCUtil.cs104
12 files changed, 524 insertions, 475 deletions
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCUtilCipher.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCCipherUtil.cs
index 72bb75a..5dc2a94 100644
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCUtilCipher.cs
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCCipherUtil.cs
@@ -15,20 +15,24 @@
using System;
using System.Diagnostics;
+using System.Runtime.InteropServices;
+
using VNLib.Utils.Cryptography.Noscrypt.@internal;
+using static VNLib.Utils.Cryptography.Noscrypt.NoscryptLibrary;
+
using NCResult = System.Int64;
namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
{
- internal static class NCUtilCipher
+ public unsafe static class NCCipherUtil
{
/*
* This class wraps the low-level cipher functions provided by
* the Noscrypt utility side-car library.
*/
- public static nint Alloc(NCContext ctx, uint version, uint flags)
+ internal static nint Alloc(NCContext ctx, uint version, uint flags)
{
nint cipher = GetTable(ctx).NCUtilCipherAlloc(version, flags);
@@ -43,7 +47,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
return cipher;
}
- public static uint GetFlags(NCContext ctx, nint cipher)
+ internal static uint GetFlags(NCContext ctx, nint cipher)
{
NCResult result = GetTable(ctx).NCUtilCipherGetFlags(cipher);
@@ -52,9 +56,9 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
return (uint)result;
}
- public static void Free(NCContext ctx, nint cipher) => GetTable(ctx).NCUtilCipherFree(cipher);
+ internal static void Free(NCContext ctx, nint cipher) => GetTable(ctx).NCUtilCipherFree(cipher);
- public static int GetIvSize(NCContext ctx, nint cipher)
+ internal static int GetIvSize(NCContext ctx, nint cipher)
{
NCResult result = GetTable(ctx).NCUtilCipherGetIvSize(cipher);
@@ -63,7 +67,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
return checked((int)result);
}
- public static unsafe void SetProperty(NCContext ctx, nint cipher, uint property, ref readonly byte value, uint valueLen)
+ internal static void SetProperty(NCContext ctx, nint cipher, uint property, ref readonly byte value, uint valueLen)
{
fixed (byte* valPtr = &value)
{
@@ -73,7 +77,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
}
}
- public static uint GetOutputSize(NCContext ctx, nint cipher)
+ internal static uint GetOutputSize(NCContext ctx, nint cipher)
{
NCResult result = GetTable(ctx).NCUtilCipherGetOutputSize(cipher);
@@ -82,7 +86,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
return (uint)result;
}
- public static unsafe uint ReadOutput(NCContext ctx, nint cipher, ref byte outputData, uint outLen)
+ internal static uint ReadOutput(NCContext ctx, nint cipher, ref byte outputData, uint outLen)
{
fixed (byte* outPtr = &outputData)
{
@@ -94,14 +98,14 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
}
}
- public static unsafe void InitCipher(NCContext ctx, nint cipher, byte* inputPtr, uint inputSize)
+ internal static void InitCipher(NCContext ctx, nint cipher, byte* inputPtr, uint inputSize)
{
NCResult result = GetTable(ctx).NCUtilCipherInit(cipher, inputPtr, inputSize);
NCUtil.CheckResult<FunctionTable.NCUtilCipherInitDelegate>(result, raiseOnFailure: true);
}
- public static unsafe void Update(
+ internal static void Update(
NCContext ctx,
nint cipher,
ref readonly NCSecretKey localKey,
@@ -122,7 +126,46 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
}
}
- private static ref readonly FunctionTable GetTable(NCContext ctx) => ref ctx.Library.Functions;
+
+#if DEBUG
+ /*
+ * Conversation key is not meant to be a public api. Callers
+ * should use Encrypt/Decrypt methods to handle encryption.
+ *
+ * This method exists for vector testing purposes only.
+ */
+ public static void GetConverstationKey(
+ NCContext ctx,
+ ref readonly NCSecretKey localKey,
+ ref readonly NCPublicKey remoteKey,
+ Span<byte> conversationKeyOut32
+ )
+ {
+ ArgumentNullException.ThrowIfNull(ctx);
+ ArgumentOutOfRangeException.ThrowIfNotEqual(
+ conversationKeyOut32.Length,
+ NC_CONVERSATION_KEY_SIZE,
+ nameof(conversationKeyOut32)
+ );
+
+ fixed (NCSecretKey* sk = &localKey)
+ fixed (NCPublicKey* pk = &remoteKey)
+ fixed(byte* convKey32Ptr = &MemoryMarshal.GetReference(conversationKeyOut32))
+ {
+ NCResult result = GetTable(ctx).NCGetConversationKey(
+ ctx: ctx.DangerousGetHandle(),
+ sk,
+ pk,
+ convKey32Ptr
+ );
+
+ NCUtil.CheckResult<FunctionTable.NCUtilCipherInitDelegate>(result, raiseOnFailure: true);
+ }
+ }
+#endif
+
+ private static ref readonly FunctionTable GetTable(NCContext ctx)
+ => ref ctx.Library.Functions;
}
}
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptCipher.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptMessageCipher.cs
index b30ea44..e44addf 100644
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptCipher.cs
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptMessageCipher.cs
@@ -18,6 +18,8 @@ using System.Threading;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
using VNLib.Utils.Memory;
using VNLib.Utils.Cryptography.Noscrypt.Random;
using static VNLib.Utils.Cryptography.Noscrypt.NoscryptLibrary;
@@ -27,29 +29,54 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
/// <summary>
/// The noscrypt util cipher wapper
/// </summary>
- /// <param name="ctx"></param>
- /// <param name="flags">Cipher creation flags</param>
+ /// <param name="ctx">A reference to the library context object</param>
+ /// <param name="cipher">A pointer to an existing cipher context that this instance owns</param>
/// <param name="version">The cipher specification version</param>
- public sealed class NoscryptCipher(NCContext ctx, NoscryptCipherVersion version, NoscryptCipherFlags flags) : VnDisposeable
+ public class NoscryptMessageCipher : SafeHandleMinusOneIsInvalid
{
+ private readonly NCContext _context;
+ private readonly NoscryptCipherVersion _version;
private IMemoryHandle<byte>? _ivBuffer;
- private readonly nint _cipher = NCUtilCipher.Alloc(ctx, (uint)version, (uint)flags);
+
+ private NoscryptMessageCipher(NCContext ctx, nint cipher, NoscryptCipherVersion version)
+ : base(ownsHandle: true)
+ {
+ SetHandle(cipher);
+ _context = ctx;
+ _version = version;
+ }
+
+ /// <summary>
+ /// Allocates and initializes a new cipher instance using the specified
+ /// </summary>
+ /// <param name="context">A reference to the noscrypt library context</param>
+ /// <param name="version">The encryption standard to use</param>
+ /// <param name="flags">The raw cipher flags to the pass to the cipher initialization function</param>
+ /// <returns>A new <see cref="NoscryptMessageCipher"/> instance</returns>
+ public static NoscryptMessageCipher Create(NCContext context, NoscryptCipherVersion version, NoscryptCipherFlags flags)
+ {
+ return new(
+ context,
+ NCCipherUtil.Alloc(context, (uint)version, (uint)flags),
+ version
+ );
+ }
/// <summary>
/// The cipher standard version used by this instance
/// </summary>
- public NoscryptCipherVersion Version => version;
+ public NoscryptCipherVersion Version => _version;
/// <summary>
/// Gets the flags set for the cipher instance
/// </summary>
- public uint GetFlags() => NCUtilCipher.GetFlags(ctx, _cipher);
+ public uint GetFlags() => NCCipherUtil.GetFlags(_context, handle);
/// <summary>
/// Gets the cipher's initilaization vector size (or nonce)
/// </summary>
/// <returns>The size of the IV in bytes</returns>
- public int GetIvSize() => NCUtilCipher.GetIvSize(ctx, _cipher);
+ public int GetIvSize() => NCCipherUtil.GetIvSize(_context, handle);
/// <summary>
/// Gets the internal heap buffer that holds the cipher's initalization
@@ -121,9 +148,9 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
fixed (byte* inputPtr = &inputData)
{
- NCUtilCipher.InitCipher(ctx, _cipher, inputPtr, inputSize);
+ NCCipherUtil.InitCipher(_context, handle, inputPtr, inputSize);
- NCUtilCipher.Update(ctx, _cipher, in localKey, in remoteKey);
+ NCCipherUtil.Update(_context, handle, in localKey, in remoteKey);
}
}
@@ -153,7 +180,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
/// Gets the size of the output buffer required to read the cipher output
/// </summary>
/// <returns>The size of the output in bytes</returns>
- public int GetOutputSize() => checked((int)NCUtilCipher.GetOutputSize(ctx, _cipher));
+ public int GetOutputSize() => checked((int)NCCipherUtil.GetOutputSize(_context, handle));
/// <summary>
/// Reads the output data from the cipher into the specified buffer
@@ -166,7 +193,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
{
ArgumentOutOfRangeException.ThrowIfLessThan(size, GetOutputSize());
- return checked((int)NCUtilCipher.ReadOutput(ctx, _cipher, ref outputData, (uint)size));
+ return checked((int)NCCipherUtil.ReadOutput(_context, handle, ref outputData, (uint)size));
}
/// <summary>
@@ -186,7 +213,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
private IMemoryHandle<byte> AllocIvBuffer()
{
//Use the context heap to allocate the internal iv buffer
- MemoryHandle<byte> buffer = MemoryUtil.SafeAlloc<byte>(ctx.Heap, GetIvSize(), zero: true);
+ MemoryHandle<byte> buffer = MemoryUtil.SafeAlloc<byte>(_context.Heap, GetIvSize(), zero: true);
try
{
@@ -199,9 +226,9 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
* buffer is required so we don't need to pin managed memory
* nor worry about the GC moving the buffer.
*/
- NCUtilCipher.SetProperty(
- ctx,
- _cipher,
+ NCCipherUtil.SetProperty(
+ _context,
+ DangerousGetHandle(),
NC_ENC_SET_IV,
ref buffer.GetReference(),
(uint)buffer.Length
@@ -217,10 +244,12 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
}
///<inheritdoc/>
- protected override void Free()
+ protected override bool ReleaseHandle()
{
- NCUtilCipher.Free(ctx, _cipher);
+ NCCipherUtil.Free(_context, handle);
_ivBuffer?.Dispose();
+
+ return true;
}
}
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/INostrCrypto.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/INostrCrypto.cs
deleted file mode 100644
index 9b4d36c..0000000
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/INostrCrypto.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (C) 2024 Vaughn Nugent
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-using System;
-
-using VNLib.Utils.Cryptography.Noscrypt.Encryption;
-
-namespace VNLib.Utils.Cryptography.Noscrypt
-{
- public interface INostrCrypto
- {
-
- /// <summary>
- /// Gets a nostr public key from a secret key.
- /// </summary>
- /// <param name="secretKey">A reference to the secret key to get the public key from</param>
- /// <param name="publicKey">A reference to the public key structure to write the recovered key to</param>
- /// <exception cref="ArgumentException"></exception>
- /// <exception cref="ArgumentNullException"></exception>
- void GetPublicKey(ref readonly NCSecretKey secretKey, ref NCPublicKey publicKey);
-
- /// <summary>
- /// Validates a secret key is in a valid format.
- /// </summary>
- /// <param name="secretKey">A readonly reference to key structure to validate</param>
- /// <returns>True if the key is consiered valid against the secp256k1 curve</returns>
- /// <exception cref="ArgumentException"></exception>
- /// <exception cref="ArgumentNullException"></exception>
- bool ValidateSecretKey(ref readonly NCSecretKey secretKey);
-
- /// <summary>
- /// Allocates a new cipher instance with the supplied options.
- /// </summary>
- /// <param name="version">The cipher specification version</param>
- /// <param name="flags">The cipher initialziation flags</param>
- /// <returns>The cipher instance</returns>
- NoscryptCipher AllocCipher(NoscryptCipherVersion version, NoscryptCipherFlags flags);
-
- /// <summary>
- /// Signs the supplied data with the secret key and random32 nonce, then writes
- /// the message signature to the supplied sig64 buffer.
- /// </summary>
- /// <param name="secretKey">The secret key used to sign the message</param>
- /// <param name="random32">A highly secure random nonce used to seed the signature</param>
- /// <param name="data">A pointer to the first byte in the message to sign</param>
- /// <param name="dataSize">The size of the message in bytes</param>
- /// <param name="sig64">A pointer to the first byte of a 64 byte buffer used to write the message signature to</param>
- /// <exception cref="ArgumentException"></exception>
- /// <exception cref="ArgumentNullException"></exception>
- void SignData(
- ref readonly NCSecretKey secretKey,
- ref readonly byte random32,
- ref readonly byte data,
- uint dataSize,
- ref byte sig64
- );
-
- /// <summary>
- /// Performs cryptographic verification of the supplied data
- /// against the supplied public key.
- /// </summary>
- /// <param name="pubKey">The signer's public key</param>
- /// <param name="data">A pointer to the first byte in the message to sign</param>
- /// <param name="dataSize">The number of bytes in the message</param>
- /// <param name="sig64">A pointer to the signature buffer</param>
- /// <returns>True if the signature could be verified against the public key. False otherwise</returns>
- /// <exception cref="ArgumentException"></exception>
- /// <exception cref="ArgumentNullException"></exception>
- bool VerifyData(
- ref readonly NCPublicKey pubKey,
- ref readonly byte data,
- uint dataSize,
- ref readonly byte sig64
- );
- }
-}
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCUtil.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCKeyUtil.cs
index 307bbc1..50e1c9a 100644
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCUtil.cs
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCKeyUtil.cs
@@ -14,18 +14,21 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using VNLib.Utils.Extensions;
+using VNLib.Utils.Cryptography.Noscrypt.@internal;
using static VNLib.Utils.Cryptography.Noscrypt.NoscryptLibrary;
using NCResult = System.Int64;
namespace VNLib.Utils.Cryptography.Noscrypt
{
-
- public static class NCUtil
+ /// <summary>
+ /// Contains utility methods for working with nostr keys
+ /// </summary>
+ public static unsafe class NCKeyUtil
{
/// <summary>
/// Gets a span of bytes from the current secret key
@@ -115,79 +118,68 @@ namespace VNLib.Utils.Cryptography.Noscrypt
return ref Unsafe.As<byte, NCPublicKey>(ref asBytes);
}
- internal static void CheckResult<T>(NCResult result, bool raiseOnFailure) where T : Delegate
+ /// <summary>
+ /// Gets a nostr public key from a secret key.
+ /// </summary>
+ /// <param name="secretKey">A reference to the secret key to get the public key from</param>
+ /// <param name="publicKey">A reference to the public key structure to write the recovered key to</param>
+ /// <exception cref="ArgumentException"></exception>
+ /// <exception cref="ArgumentNullException"></exception>
+ public static void GetPublicKey(
+ NCContext context,
+ ref readonly NCSecretKey secretKey,
+ ref NCPublicKey publicKey
+ )
{
- //Only negative values are errors
- if (result >= NC_SUCCESS)
- {
- return;
- }
-
- NCResult asPositive = -result;
+ Check(context);
- // Error code are only 8 bits, if an argument error occured, the
- // argument number will be in the next upper 8 bits
- NCErrorCodes errorCode = (NCErrorCodes)(asPositive & 0xFF);
- byte argNumber = (byte)((asPositive >> 8) & 0xFF);
-
- switch (errorCode)
+ fixed (NCSecretKey* pSecKey = &secretKey)
+ fixed (NCPublicKey* pPubKey = &publicKey)
{
- case NCErrorCodes.E_NULL_PTR:
- RaiseNullArgExceptionForArgumentNumber<T>(argNumber);
- break;
- case NCErrorCodes.E_INVALID_ARG:
- RaiseArgExceptionForArgumentNumber<T>(argNumber);
- break;
- case NCErrorCodes.E_ARGUMENT_OUT_OF_RANGE:
- RaiseOORExceptionForArgumentNumber<T>(argNumber);
- break;
- case NCErrorCodes.E_INVALID_CTX:
- throw new InvalidOperationException("The library context object is null or invalid");
- case NCErrorCodes.E_OPERATION_FAILED:
- RaiseOperationFailedException(raiseOnFailure);
- break;
- case NCErrorCodes.E_VERSION_NOT_SUPPORTED:
- throw new NotSupportedException("The requested version is not supported");
-
- default:
- if(raiseOnFailure)
- {
- throw new InvalidOperationException($"The operation failed with error, code: {errorCode} for arugment {argNumber:x}");
- }
- break;
+ NCResult result = GetTable(context).NCGetPublicKey(
+ context.DangerousGetHandle(),
+ pSecKey,
+ pPubKey
+ );
+
+ NCUtil.CheckResult<FunctionTable.NCGetPublicKeyDelegate>(result, raiseOnFailure: true);
}
}
- private static void RaiseOperationFailedException(bool raise)
+ /// <summary>
+ /// Validates a secret key is in a valid format.
+ /// </summary>
+ /// <param name="secretKey">A readonly reference to key structure to validate</param>
+ /// <returns>True if the key is consiered valid against the secp256k1 curve</returns>
+ /// <exception cref="ArgumentException"></exception>
+ /// <exception cref="ArgumentNullException"></exception>
+ public static bool ValidateSecretKey(
+ NCContext context,
+ ref readonly NCSecretKey secretKey
+ )
{
- if (raise)
+ Check(context);
+
+ fixed (NCSecretKey* pSecKey = &secretKey)
{
- throw new InvalidOperationException("The operation failed for an unknown reason");
- }
- }
+ NCResult result = GetTable(context).NCValidateSecretKey(
+ context.DangerousGetHandle(),
+ pSecKey
+ );
- private static void RaiseNullArgExceptionForArgumentNumber<T>(int argNumber) where T : Delegate
- {
- //Get delegate parameters
- Type type = typeof(T);
- ParameterInfo arg = type.GetMethod("Invoke")!.GetParameters()[argNumber];
- throw new ArgumentNullException(arg.Name, "Argument is null or invalid cannot continue");
- }
+ NCUtil.CheckResult<FunctionTable.NCValidateSecretKeyDelegate>(result, raiseOnFailure: false);
- private static void RaiseArgExceptionForArgumentNumber<T>(int argNumber) where T : Delegate
- {
- //Get delegate parameters
- Type type = typeof(T);
- ParameterInfo arg = type.GetMethod("Invoke")!.GetParameters()[argNumber];
- throw new ArgumentException("Argument is null or invalid cannot continue", arg.Name);
+ return result == NC_SUCCESS;
+ }
}
- private static void RaiseOORExceptionForArgumentNumber<T>(int argNumber) where T : Delegate
+ private static void Check(NCContext? context)
{
- //Get delegate parameters
- Type type = typeof(T);
- ParameterInfo arg = type.GetMethod("Invoke")!.GetParameters()[argNumber];
- throw new ArgumentOutOfRangeException(arg.Name, "Argument is out of range of acceptable values");
+ ArgumentNullException.ThrowIfNull(context);
+ context.ThrowIfClosed();
}
+
+ private static ref readonly FunctionTable GetTable(NCContext ctx)
+ => ref ctx.Library.Functions;
}
}
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptExtensions.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptExtensions.cs
deleted file mode 100644
index e96ff96..0000000
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptExtensions.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (C) 2024 Vaughn Nugent
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-using static VNLib.Utils.Cryptography.Noscrypt.NoscryptLibrary;
-
-namespace VNLib.Utils.Cryptography.Noscrypt
-{
-
- public static class NoscryptExtensions
- {
- public static void SignData(
- this INostrCrypto lib,
- ref readonly NCSecretKey secKey,
- ReadOnlySpan<byte> random32,
- ReadOnlySpan<byte> data,
- Span<byte> signatureBuffer
- )
- {
- ArgumentOutOfRangeException.ThrowIfLessThan(signatureBuffer.Length, NC_SIGNATURE_SIZE, nameof(signatureBuffer));
- ArgumentOutOfRangeException.ThrowIfLessThan(random32.Length, 32, nameof(random32));
- ArgumentOutOfRangeException.ThrowIfZero(data.Length, nameof(data));
-
- lib.SignData(
- secretKey: in secKey,
- random32: in MemoryMarshal.GetReference(random32),
- data: in MemoryMarshal.GetReference(data),
- dataSize: (uint)data.Length,
- sig64: ref MemoryMarshal.GetReference(signatureBuffer)
- );
- }
-
-#if DEBUG
- /*
- * Conversation key is not meant to be a public api. Callers
- * should use Encrypt/Decrypt methods to handle encryption.
- *
- * This method exists for vector testing purposes only.
- */
- public static void GetConverstationKey(
- this NostrCrypto lib,
- ref readonly NCSecretKey secretKey,
- ref readonly NCPublicKey publicKey,
- Span<byte> conversationKeyOut32
- )
- {
- ArgumentNullException.ThrowIfNull(lib);
- ArgumentOutOfRangeException.ThrowIfNotEqual(conversationKeyOut32.Length, NC_CONVERSATION_KEY_SIZE, nameof(conversationKeyOut32));
-
- //Get the conversation key
- lib.GetConverstationKey(
- secretKey: in secretKey,
- publicKey: in publicKey,
- key32: ref MemoryMarshal.GetReference(conversationKeyOut32)
- );
-
- }
-#endif
- }
-}
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptLibrary.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptLibrary.cs
index 35c6a49..2df63eb 100644
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptLibrary.cs
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptLibrary.cs
@@ -37,6 +37,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt
public unsafe sealed class NoscryptLibrary(SafeLibraryHandle Library, bool OwnsHandle) : VnDisposeable
{
public const string NoscryptDefaultLibraryName = "noscrypt";
+ public const string NoscryptDllPathEnvName = "NOSCRYPT_DLL_PATH";
//Constant values match the noscrypt.h header
public const int NC_SEC_KEY_SIZE = 0x20;
@@ -172,33 +173,16 @@ namespace VNLib.Utils.Cryptography.Noscrypt
}
/// <summary>
- /// Initializes a new NostrCrypto context wraper directly that owns the internal context.
- /// This may be done once at app startup and is thread-safe for the rest of the
- /// application lifetime.
- /// </summary>
- /// <param name="heap">The heap to allocate the context from</param>
- /// <param name="entropy32">The random entropy data to initialize the context with</param>
- /// <returns>The library wrapper handle</returns>
- public NostrCrypto InitializeCrypto(IUnmangedHeap heap, ReadOnlySpan<byte> entropy32)
- {
- ArgumentNullException.ThrowIfNull(heap);
-
- //Create the crypto interface from the new context object
- return new NostrCrypto(
- context: Initialize(heap, entropy32),
- ownsContext: true
- );
- }
-
- /// <summary>
- /// Initializes a new NostrCrypto context wraper directly that owns the internal context.
- /// This may be done once at app startup and is thread-safe for the rest of the
- /// application lifetime.
+ /// Initialize a new NCContext for use. This may be done once at app startup
+ /// and is thread-safe for the rest of the application lifetime.
/// </summary>
- /// <param name="heap">The heap to allocate the context from</param>
- /// <param name="random">Random source used to generate context entropy</param>
- /// <returns>The library wrapper handle</returns>
- public NostrCrypto InitializeCrypto(IUnmangedHeap heap, IRandomSource random)
+ /// <param name="heap"></param>
+ /// <param name="enropy32">The 32byte random seed/nonce for the noscrypt context</param>
+ /// <returns>The inialized context</returns>
+ /// <exception cref="OutOfMemoryException"></exception>
+ /// <exception cref="ArgumentNullException"></exception>
+ /// <exception cref="ArgumentOutOfRangeException"></exception>
+ public NCContext Initialize(IUnmangedHeap heap, IRandomSource random)
{
ArgumentNullException.ThrowIfNull(random);
@@ -206,13 +190,9 @@ namespace VNLib.Utils.Cryptography.Noscrypt
Span<byte> entropy = stackalloc byte[NC_CTX_ENTROPY_SIZE];
random.GetRandomBytes(entropy);
- NostrCrypto nc = InitializeCrypto(heap, entropy);
-
- MemoryUtil.InitializeBlock(entropy);
-
- return nc;
+ return Initialize(heap, entropy);
}
-
+
///<inheritdoc/>
protected override void Free()
{
@@ -256,6 +236,16 @@ namespace VNLib.Utils.Cryptography.Noscrypt
/// </summary>
/// <returns>The loaded library instance</returns>
/// <exception cref="DllNotFoundException"></exception>
- public static NoscryptLibrary LoadDefault() => Load(NoscryptDefaultLibraryName, DllImportSearchPath.SafeDirectories);
+ public static NoscryptLibrary LoadDefault()
+ {
+ string? libPath = Environment.GetEnvironmentVariable(NoscryptDllPathEnvName);
+ libPath ??= NoscryptDefaultLibraryName;
+
+ Console.WriteLine("Loading library {0}", libPath);
+
+ libPath = libPath.Replace("\"", "");
+
+ return Load(libPath);
+ }
}
}
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NostrCrypto.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NostrCrypto.cs
deleted file mode 100644
index 1e833d2..0000000
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NostrCrypto.cs
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (C) 2024 Vaughn Nugent
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-using System;
-using System.Runtime.CompilerServices;
-using System.Diagnostics.CodeAnalysis;
-
-using VNLib.Utils.Cryptography.Noscrypt.@internal;
-using VNLib.Utils.Cryptography.Noscrypt.Encryption;
-using static VNLib.Utils.Cryptography.Noscrypt.NoscryptLibrary;
-
-using NCResult = System.Int64;
-
-namespace VNLib.Utils.Cryptography.Noscrypt
-{
- /// <summary>
- /// A default implementation of the <see cref="INostrCrypto"/> interface
- /// </summary>
- /// <param name="context">The initialized library context</param>
- public unsafe class NostrCrypto(NCContext context, bool ownsContext) : VnDisposeable, INostrCrypto
- {
- /// <summary>
- /// Gets the underlying library context.
- /// </summary>
- public NCContext Context => context;
-
- private ref readonly FunctionTable Functions => ref context.Library.Functions;
-
- ///<inheritdoc/>
- public NoscryptCipher AllocCipher(NoscryptCipherVersion version, NoscryptCipherFlags flags) => new (context, version, flags);
-
- ///<inheritdoc/>
- public void GetPublicKey(ref readonly NCSecretKey secretKey, ref NCPublicKey publicKey)
- {
- Check();
-
- fixed (NCSecretKey* pSecKey = &secretKey)
- fixed (NCPublicKey* pPubKey = &publicKey)
- {
- NCResult result = Functions.NCGetPublicKey.Invoke(context.DangerousGetHandle(), pSecKey, pPubKey);
- NCUtil.CheckResult<FunctionTable.NCGetPublicKeyDelegate>(result, true);
- }
- }
-
- ///<inheritdoc/>
- public void SignData(
- ref readonly NCSecretKey secretKey,
- ref readonly byte random32,
- ref readonly byte data,
- uint dataSize,
- ref byte sig64
- )
- {
- Check();
-
- fixed (NCSecretKey* pSecKey = &secretKey)
- fixed (byte* pData = &data, pSig = &sig64, pRandom = &random32)
- {
- NCResult result = Functions.NCSignData.Invoke(
- ctx: context.DangerousGetHandle(),
- sk: pSecKey,
- random32: pRandom,
- data: pData,
- dataSize,
- sig64: pSig
- );
-
- NCUtil.CheckResult<FunctionTable.NCSignDataDelegate>(result, true);
- }
- }
-
- ///<inheritdoc/>
- public bool ValidateSecretKey(ref readonly NCSecretKey secretKey)
- {
- Check();
-
- IntPtr libCtx = context.DangerousGetHandle();
-
- fixed (NCSecretKey* pSecKey = &secretKey)
- {
- /*
- * Validate should return a result of 1 if the secret key is valid
- * or a 0 if it is not.
- */
- NCResult result = Functions.NCValidateSecretKey.Invoke(libCtx, pSecKey);
- NCUtil.CheckResult<FunctionTable.NCValidateSecretKeyDelegate>(result, false);
-
- return result == NC_SUCCESS;
- }
- }
-
- ///<inheritdoc/>
- public bool VerifyData(
- ref readonly NCPublicKey pubKey,
- ref readonly byte data,
- uint dataSize,
- ref readonly byte sig64
- )
- {
- Check();
-
- fixed(NCPublicKey* pPubKey = &pubKey)
- fixed (byte* pData = &data, pSig = &sig64)
- {
- NCResult result = Functions.NCVerifyData.Invoke(context.DangerousGetHandle(), pPubKey, pData, dataSize, pSig);
- NCUtil.CheckResult<FunctionTable.NCVerifyDataDelegate>(result, false);
-
- return result == NC_SUCCESS;
- }
- }
-
-#if DEBUG
-
- /// <summary>
- /// DEBUG ONLY: Gets the conversation key for the supplied secret key and public key
- /// </summary>
- /// <param name="secretKey">The sender's private key</param>
- /// <param name="publicKey">The receiver's public key</param>
- /// <param name="key32">A pointer to the 32byte buffer to write the conversation key to</param>
- public void GetConverstationKey(
- ref readonly NCSecretKey secretKey,
- ref readonly NCPublicKey publicKey,
- ref byte key32
- )
- {
- Check();
-
- fixed (NCSecretKey* pSecKey = &secretKey)
- fixed (NCPublicKey* pPubKey = &publicKey)
- fixed (byte* pKey = &key32)
- {
- NCResult result = Functions.NCGetConversationKey.Invoke(context.DangerousGetHandle(), pSecKey, pPubKey, pKey);
- NCUtil.CheckResult<FunctionTable.NCGetConversationKeyDelegate>(result, true);
- }
- }
-
-#endif
- ///<inheritdoc/>
- protected override void Free()
- {
- if(ownsContext)
- {
- context.Dispose();
- }
- }
-
- private static void ThrowIfNullRef([DoesNotReturnIf(false)] ref readonly byte value, string name)
- {
- if(Unsafe.IsNullRef(in value))
- {
- throw new ArgumentNullException(name);
- }
- }
- }
-}
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Singatures/NCSignatureUtil.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Singatures/NCSignatureUtil.cs
new file mode 100644
index 0000000..2755ceb
--- /dev/null
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Singatures/NCSignatureUtil.cs
@@ -0,0 +1,175 @@
+// Copyright (C) 2024 Vaughn Nugent
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+using System;
+using System.Runtime.InteropServices;
+
+using VNLib.Utils.Extensions;
+using VNLib.Utils.Cryptography.Noscrypt.@internal;
+using static VNLib.Utils.Cryptography.Noscrypt.NoscryptLibrary;
+
+using NCResult = System.Int64;
+
+namespace VNLib.Utils.Cryptography.Noscrypt.Singatures
+{
+
+ /// <summary>
+ /// Contains utility methods for signing and verifying data using the noscrypt library
+ /// </summary>
+ public unsafe static class NCSignatureUtil
+ {
+ /// <summary>
+ /// Signs the data using the supplied secret key and
+ /// entropy pointer
+ /// </summary>
+ /// <param name="context">The initialized context memory to pass to the library</param>
+ /// <param name="secretKey">A reference to a structure containing the private key data</param>
+ /// <param name="random32">A pointer to a 32 byte buffer containing high entropy random data</param>
+ /// <param name="data">A pointer to a buffer containing the data to sign</param>
+ /// <param name="dataSize">The size of the data buffer in bytes</param>
+ /// <param name="sig64">A pointer to a 64 byte buffer to write signature data to</param>
+ /// <exception cref="InvalidOperationException"></exception>
+ public static void SignData(
+ NCContext context,
+ ref readonly NCSecretKey secretKey,
+ ref readonly byte random32,
+ ref readonly byte data,
+ uint dataSize,
+ ref byte sig64
+ )
+ {
+ Check(context);
+
+ fixed (NCSecretKey* pSecKey = &secretKey)
+ fixed (byte* pData = &data, pSig = &sig64, pRandom = &random32)
+ {
+ NCResult result = GetTable(context).NCSignData(
+ ctx: context.DangerousGetHandle(),
+ sk: pSecKey,
+ random32: pRandom,
+ data: pData,
+ dataSize,
+ sig64: pSig
+ );
+
+ NCUtil.CheckResult<FunctionTable.NCSignDataDelegate>(result, raiseOnFailure: true);
+ }
+ }
+
+ /// <summary>
+ /// Verifies signed data against the supplied public key
+ /// </summary>
+ /// <param name="context">The initialized context memory to pass to the library</param>
+ /// <param name="publicKey">A reference to a structure containing the public key data</param>
+ /// <param name="data">A pointer to a buffer containing the data to verify</param>
+ /// <param name="dataSize">The size of the data buffer in bytes</param>
+ /// <param name="sig64">A pointer to a 64 byte buffer to read signature data from</param>
+ /// <returns>True if the signature was signed by the supplied public key, false otherwise</returns>
+ public static bool VerifyData(
+ NCContext context,
+ ref readonly NCPublicKey publicKey,
+ ref readonly byte data,
+ uint dataSize,
+ ref readonly byte sig64
+ )
+ {
+ Check(context);
+
+ fixed (NCPublicKey* pPubKey = &publicKey)
+ fixed (byte* pData = &data, pSig = &sig64)
+ {
+ NCResult result = GetTable(context).NCVerifyData(
+ context.DangerousGetHandle(),
+ pk: pPubKey,
+ data: pData,
+ dataSize,
+ sig64: pSig
+ );
+
+ NCUtil.CheckResult<FunctionTable.NCVerifyDataDelegate>(result, false);
+
+ return result == NC_SUCCESS;
+ }
+ }
+
+ /// <summary>
+ /// Signs the data using the supplied secret key and
+ /// entropy pointer
+ /// </summary>
+ /// <param name="context">The initialized context memory to pass to the library</param>
+ /// <param name="secretKey">A reference to a structure containing the private key data</param>
+ /// <param name="random32">A pointer to a 32 byte buffer containing high entropy random data</param>
+ /// <param name="data">A pointer to a buffer containing the data to sign</param>
+ /// <param name="signatureBuffer">A pointer to a 64 byte buffer to write signature data to</param>
+ /// <exception cref="InvalidOperationException"></exception>
+ public static void SignData(
+ NCContext context,
+ ref readonly NCSecretKey secretKey,
+ ReadOnlySpan<byte> random32,
+ ReadOnlySpan<byte> data,
+ Span<byte> signatureBuffer
+ )
+ {
+ ArgumentOutOfRangeException.ThrowIfLessThan(signatureBuffer.Length, NC_SIGNATURE_SIZE, nameof(signatureBuffer));
+ ArgumentOutOfRangeException.ThrowIfLessThan(random32.Length, 32, nameof(random32));
+ ArgumentOutOfRangeException.ThrowIfZero(data.Length, nameof(data));
+
+ SignData(
+ context,
+ secretKey: in secretKey,
+ random32: in MemoryMarshal.GetReference(random32),
+ data: in MemoryMarshal.GetReference(data),
+ dataSize: (uint)data.Length,
+ sig64: ref MemoryMarshal.GetReference(signatureBuffer)
+ );
+ }
+
+ /// <summary>
+ /// Verifies signed data against the supplied public key
+ /// </summary>
+ /// <param name="context">The initialized context memory to pass to the library</param>
+ /// <param name="publicKey">A reference to a structure containing the public key data</param>
+ /// <param name="data">A pointer to a buffer containing the data to verify</param>
+ /// <param name="signatureBuffer">A pointer to a 64 byte buffer to read signature data from</param>
+ /// <returns>True if the signature was signed by the supplied public key, false otherwise</returns>
+ public static bool VerifyData(
+ NCContext context,
+ ref readonly NCPublicKey publicKey,
+ ReadOnlySpan<byte> data,
+ ReadOnlySpan<byte> signatureBuffer
+ )
+ {
+ ArgumentOutOfRangeException.ThrowIfLessThan(signatureBuffer.Length, NC_SIGNATURE_SIZE, nameof(signatureBuffer));
+ ArgumentOutOfRangeException.ThrowIfZero(data.Length, nameof(data));
+
+ return VerifyData(
+ context,
+ publicKey: in publicKey,
+ data: in MemoryMarshal.GetReference(data),
+ dataSize: (uint)data.Length,
+ sig64: ref MemoryMarshal.GetReference(signatureBuffer)
+ );
+ }
+
+ private static void Check(NCContext? context)
+ {
+ ArgumentNullException.ThrowIfNull(context);
+ context.ThrowIfClosed();
+ }
+
+ private static ref readonly FunctionTable GetTable(NCContext ctx)
+ => ref ctx.Library.Functions;
+ }
+}
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptSigner.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Singatures/NoscryptSigner.cs
index c81790b..063d2c0 100644
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NoscryptSigner.cs
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Singatures/NoscryptSigner.cs
@@ -14,21 +14,23 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
using System;
-using VNLib.Utils.Cryptography.Noscrypt.Random;
-using VNLib.Utils.Extensions;
-using VNLib.Utils.Memory;
+using VNLib.Utils.Memory;
+using VNLib.Utils.Extensions;
+using VNLib.Utils.Cryptography.Noscrypt;
+using VNLib.Utils.Cryptography.Noscrypt.Random;
using static VNLib.Utils.Cryptography.Noscrypt.NoscryptLibrary;
-namespace VNLib.Utils.Cryptography.Noscrypt
+namespace VNLib.Utils.Cryptography.Noscrypt.Singatures
{
+
/// <summary>
/// A simple wrapper class to sign nostr message data using
/// the noscrypt library
/// </summary>
/// <param name="noscrypt">The noscrypt library instance</param>
/// <param name="random">A random entropy pool used to source random data for signature entropy</param>
- public class NoscryptSigner(INostrCrypto noscrypt, IRandomSource random)
+ public class NoscryptSigner(NCContext context, IRandomSource random)
{
/// <summary>
/// Gets the size of the buffer required to hold the signature
@@ -72,12 +74,16 @@ namespace VNLib.Utils.Cryptography.Noscrypt
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public string SignData(
- ReadOnlySpan<byte> secretKey,
- ReadOnlySpan<byte> message,
+ ReadOnlySpan<byte> secretKey,
+ ReadOnlySpan<byte> message,
INostrSignatureEncoder? format = null
)
{
- return SignData(in NCUtil.AsSecretKey(secretKey), message, format);
+ return SignData(
+ in NCKeyUtil.AsSecretKey(secretKey),
+ message,
+ format
+ );
}
/// <summary>
@@ -90,8 +96,8 @@ namespace VNLib.Utils.Cryptography.Noscrypt
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public string SignData(
- ref readonly NCSecretKey secretkey,
- ReadOnlySpan<byte> message,
+ ref readonly NCSecretKey secretkey,
+ ReadOnlySpan<byte> message,
INostrSignatureEncoder? format = null
)
{
@@ -115,8 +121,8 @@ namespace VNLib.Utils.Cryptography.Noscrypt
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public void SignData(
- ref readonly NCSecretKey secretkey,
- ReadOnlySpan<byte> data,
+ ref readonly NCSecretKey secretkey,
+ ReadOnlySpan<byte> data,
Span<byte> signature
)
{
@@ -126,7 +132,35 @@ namespace VNLib.Utils.Cryptography.Noscrypt
Span<byte> entropy = stackalloc byte[NC_SIG_ENTROPY_SIZE];
random.GetRandomBytes(entropy);
- noscrypt.SignData(in secretkey, entropy, data, signature);
+ NCSignatureUtil.SignData(
+ context,
+ in secretkey,
+ entropy,
+ data,
+ signature
+ );
+ }
+
+ public bool VerifyData(
+ ReadOnlySpan<byte> publicKey,
+ ReadOnlySpan<byte> data,
+ ReadOnlySpan<byte> sig
+ )
+ {
+ return VerifyData(
+ in NCKeyUtil.AsPublicKey(publicKey),
+ data,
+ sig
+ );
+ }
+
+ public bool VerifyData(
+ ref readonly NCPublicKey pk,
+ ReadOnlySpan<byte> data,
+ ReadOnlySpan<byte> sig
+ )
+ {
+ return NCSignatureUtil.VerifyData(context, in pk, data, sig);
}
}
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/VNLib.Utils.Cryptography.Noscrypt.csproj b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/VNLib.Utils.Cryptography.Noscrypt.csproj
index 4d1868c..29a4b8f 100644
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/VNLib.Utils.Cryptography.Noscrypt.csproj
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/VNLib.Utils.Cryptography.Noscrypt.csproj
@@ -1,5 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
-
+
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
@@ -9,7 +9,7 @@
<RootNamespace>VNLib.Utils.Cryptography.Noscrypt</RootNamespace>
<AssemblyName>VNLib.Utils.Cryptography.Noscrypt</AssemblyName>
</PropertyGroup>
-
+
<PropertyGroup>
<Authors>Vaughn Nugent</Authors>
<Company>Vaughn Nugent</Company>
@@ -19,10 +19,22 @@
<PackageProjectUrl>https://www.vaughnnugent.com/resources/software/modules/Noscrypt</PackageProjectUrl>
<RepositoryUrl>https://github.com/VnUgE/noscryot/tree/master/dotnet/VNLib.Utils.Cryptography.Noscrypt</RepositoryUrl>
</PropertyGroup>
-
+
<ItemGroup>
- <PackageReference Include="VNLib.Hashing.Portable" Version="0.1.0-ci0124" />
- <PackageReference Include="VNLib.Utils" Version="0.1.0-ci0124" />
+ <None Include="..\README.md">
+ <Pack>True</Pack>
+ <PackagePath>\</PackagePath>
+ </None>
+ <None Include="..\..\..\..\LICENSE">
+ <Pack>True</Pack>
+ <PackagePath>\</PackagePath>
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
</ItemGroup>
-
+
+ <ItemGroup>
+ <PackageReference Include="VNLib.Hashing.Portable" Version="0.1.0-ci0202" />
+ <PackageReference Include="VNLib.Utils" Version="0.1.0-ci0202" />
+ </ItemGroup>
+
</Project>
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/internal/FunctionTable.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/internal/FunctionTable.cs
index 0cda5e2..269ae4d 100644
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/internal/FunctionTable.cs
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/internal/FunctionTable.cs
@@ -119,7 +119,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.@internal
internal delegate NCResult NCSignDataDelegate(IntPtr ctx, NCSecretKey* sk, byte* random32, byte* data, uint dataSize, byte* sig64);
[SafeMethodName("NCVerifyData")]
- internal delegate NCResult NCVerifyDataDelegate(IntPtr ctx, NCPublicKey* sk, byte* data, uint dataSize, byte* sig64);
+ internal delegate NCResult NCVerifyDataDelegate(IntPtr ctx, NCPublicKey* pk, byte* data, uint dataSize, byte* sig64);
[SafeMethodName("NCGetConversationKey")]
internal delegate NCResult NCGetConversationKeyDelegate(IntPtr ctx, NCSecretKey* sk, NCPublicKey* pk, byte* keyOut32);
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/internal/NCUtil.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/internal/NCUtil.cs
new file mode 100644
index 0000000..16f46c6
--- /dev/null
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/internal/NCUtil.cs
@@ -0,0 +1,104 @@
+// Copyright (C) 2024 Vaughn Nugent
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+using System;
+using System.Reflection;
+using static VNLib.Utils.Cryptography.Noscrypt.NoscryptLibrary;
+
+using NCResult = System.Int64;
+
+namespace VNLib.Utils.Cryptography.Noscrypt.@internal
+{
+
+ public static class NCUtil
+ {
+
+
+ internal static void CheckResult<T>(NCResult result, bool raiseOnFailure) where T : Delegate
+ {
+ //Only negative values are errors
+ if (result >= NC_SUCCESS)
+ {
+ return;
+ }
+
+ NCResult asPositive = -result;
+
+ // Error code are only 8 bits, if an argument error occured, the
+ // argument number will be in the next upper 8 bits
+ NCErrorCodes errorCode = (NCErrorCodes)(asPositive & 0xFF);
+ byte argNumber = (byte)(asPositive >> 8 & 0xFF);
+
+ switch (errorCode)
+ {
+ case NCErrorCodes.E_NULL_PTR:
+ RaiseNullArgExceptionForArgumentNumber<T>(argNumber);
+ break;
+ case NCErrorCodes.E_INVALID_ARG:
+ RaiseArgExceptionForArgumentNumber<T>(argNumber);
+ break;
+ case NCErrorCodes.E_ARGUMENT_OUT_OF_RANGE:
+ RaiseOORExceptionForArgumentNumber<T>(argNumber);
+ break;
+ case NCErrorCodes.E_INVALID_CTX:
+ throw new InvalidOperationException("The library context object is null or invalid");
+ case NCErrorCodes.E_OPERATION_FAILED:
+ RaiseOperationFailedException(raiseOnFailure);
+ break;
+ case NCErrorCodes.E_VERSION_NOT_SUPPORTED:
+ throw new NotSupportedException("The requested version is not supported");
+
+ default:
+ if (raiseOnFailure)
+ {
+ throw new InvalidOperationException($"The operation failed with error, code: {errorCode} for arugment {argNumber:x}");
+ }
+ break;
+ }
+ }
+
+ private static void RaiseOperationFailedException(bool raise)
+ {
+ if (raise)
+ {
+ throw new InvalidOperationException("The operation failed for an unknown reason");
+ }
+ }
+
+ private static void RaiseNullArgExceptionForArgumentNumber<T>(int argNumber) where T : Delegate
+ {
+ //Get delegate parameters
+ Type type = typeof(T);
+ ParameterInfo arg = type.GetMethod("Invoke")!.GetParameters()[argNumber];
+ throw new ArgumentNullException(arg.Name, "Argument is null or invalid cannot continue");
+ }
+
+ private static void RaiseArgExceptionForArgumentNumber<T>(int argNumber) where T : Delegate
+ {
+ //Get delegate parameters
+ Type type = typeof(T);
+ ParameterInfo arg = type.GetMethod("Invoke")!.GetParameters()[argNumber];
+ throw new ArgumentException("Argument is null or invalid cannot continue", arg.Name);
+ }
+
+ private static void RaiseOORExceptionForArgumentNumber<T>(int argNumber) where T : Delegate
+ {
+ //Get delegate parameters
+ Type type = typeof(T);
+ ParameterInfo arg = type.GetMethod("Invoke")!.GetParameters()[argNumber];
+ throw new ArgumentOutOfRangeException(arg.Name, "Argument is out of range of acceptable values");
+ }
+ }
+}