From 44044eb0fb28b774773e3284fd147c91d59d64e3 Mon Sep 17 00:00:00 2001 From: vnugent Date: Fri, 18 Oct 2024 22:10:17 -0400 Subject: refactor: Wire up unit testing and refactor c# api --- .../src/NCKeyUtil.cs | 185 +++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCKeyUtil.cs (limited to 'wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCKeyUtil.cs') diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCKeyUtil.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCKeyUtil.cs new file mode 100644 index 0000000..50e1c9a --- /dev/null +++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/NCKeyUtil.cs @@ -0,0 +1,185 @@ +// 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 . + +using System; +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 +{ + /// + /// Contains utility methods for working with nostr keys + /// + public static unsafe class NCKeyUtil + { + /// + /// Gets a span of bytes from the current secret key + /// structure + /// + /// + /// The secret key data span + public unsafe static Span AsSpan(this ref NCSecretKey key) + { + //Safe to cast secret key to bytes, then we can make a span to its memory + ref byte asBytes = ref Unsafe.As(ref key); + return MemoryMarshal.CreateSpan(ref asBytes, sizeof(NCSecretKey)); + } + + /// + /// Gets a span of bytes from the current public key + /// structure + /// + /// + /// The public key data as a data span + public unsafe static Span AsSpan(this ref NCPublicKey key) + { + //Safe to cast secret key to bytes, then we can make a span to its memory + ref byte asBytes = ref Unsafe.As(ref key); + return MemoryMarshal.CreateSpan(ref asBytes, sizeof(NCPublicKey)); + } + + /// + /// Casts a span of bytes to a secret key reference. Note that + /// the new structure reference will point to the same memory + /// as the span. + /// + /// The secret key data + /// A mutable secret key reference + /// + public unsafe static ref NCSecretKey AsSecretKey(Span span) + { + ArgumentOutOfRangeException.ThrowIfLessThan(span.Length, sizeof(NCSecretKey), nameof(span)); + + ref byte asBytes = ref MemoryMarshal.GetReference(span); + return ref Unsafe.As(ref asBytes); + } + + /// + /// Casts a span of bytes to a public key reference. Note that + /// the new structure reference will point to the same memory + /// as the span. + /// + /// The public key data span + /// A mutable reference to the public key structure + /// + public unsafe static ref NCPublicKey AsPublicKey(Span span) + { + ArgumentOutOfRangeException.ThrowIfLessThan(span.Length, sizeof(NCPublicKey), nameof(span)); + + ref byte asBytes = ref MemoryMarshal.GetReference(span); + return ref Unsafe.As(ref asBytes); + } + + /// + /// Casts a read-only span of bytes to a secret key reference. Note that + /// the new structure reference will point to the same memory as the span. + /// + /// The secret key data span + /// A readonly refernce to the secret key structure + /// + public unsafe static ref readonly NCSecretKey AsSecretKey(ReadOnlySpan span) + { + ArgumentOutOfRangeException.ThrowIfLessThan(span.Length, sizeof(NCSecretKey), nameof(span)); + + ref byte asBytes = ref MemoryMarshal.GetReference(span); + return ref Unsafe.As(ref asBytes); + } + + /// + /// Casts a read-only span of bytes to a public key reference. Note that + /// the new structure reference will point to the same memory as the span. + /// + /// The public key data span + /// A readonly reference to the public key structure + /// + public unsafe static ref readonly NCPublicKey AsPublicKey(ReadOnlySpan span) + { + ArgumentOutOfRangeException.ThrowIfLessThan(span.Length, sizeof(NCPublicKey), nameof(span)); + + ref byte asBytes = ref MemoryMarshal.GetReference(span); + return ref Unsafe.As(ref asBytes); + } + + /// + /// Gets a nostr public key from a secret key. + /// + /// A reference to the secret key to get the public key from + /// A reference to the public key structure to write the recovered key to + /// + /// + public static void GetPublicKey( + NCContext context, + ref readonly NCSecretKey secretKey, + ref NCPublicKey publicKey + ) + { + Check(context); + + fixed (NCSecretKey* pSecKey = &secretKey) + fixed (NCPublicKey* pPubKey = &publicKey) + { + NCResult result = GetTable(context).NCGetPublicKey( + context.DangerousGetHandle(), + pSecKey, + pPubKey + ); + + NCUtil.CheckResult(result, raiseOnFailure: true); + } + } + + /// + /// Validates a secret key is in a valid format. + /// + /// A readonly reference to key structure to validate + /// True if the key is consiered valid against the secp256k1 curve + /// + /// + public static bool ValidateSecretKey( + NCContext context, + ref readonly NCSecretKey secretKey + ) + { + Check(context); + + fixed (NCSecretKey* pSecKey = &secretKey) + { + NCResult result = GetTable(context).NCValidateSecretKey( + context.DangerousGetHandle(), + pSecKey + ); + + NCUtil.CheckResult(result, raiseOnFailure: false); + + return result == NC_SUCCESS; + } + } + + private static void Check(NCContext? context) + { + ArgumentNullException.ThrowIfNull(context); + context.ThrowIfClosed(); + } + + private static ref readonly FunctionTable GetTable(NCContext ctx) + => ref ctx.Library.Functions; + } +} -- cgit