diff options
author | vnugent <public@vaughnnugent.com> | 2024-01-28 19:56:02 -0500 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2024-01-28 19:56:02 -0500 |
commit | 87645bfad3943e1110e4cb2e038124083e8ae793 (patch) | |
tree | c327a4437c98d973f45c313cf8259ad75515c4fe /back-end/libs/NVault.Crypto.Secp256k1 | |
parent | c438ee90e3be4e5e01ae3d045d6b841a03bd46eb (diff) |
progress update
Diffstat (limited to 'back-end/libs/NVault.Crypto.Secp256k1')
8 files changed, 0 insertions, 908 deletions
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs deleted file mode 100644 index bb014df..0000000 --- a/back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs +++ /dev/null @@ -1,274 +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.Security.Cryptography; -using System.Runtime.InteropServices; - -using VNLib.Hashing; -using VNLib.Utils; -using VNLib.Utils.Memory; -using VNLib.Utils.Extensions; - -using static NVault.Crypto.Secp256k1.LibSecp256k1; - -namespace NVault.Crypto.Secp256k1 -{ - /// <summary> - /// The callback function signature required for ECDH hash functions - /// </summary> - /// <param name="state">The callback state</param> - /// <returns>The return value to be passed as a result of the operation</returns> - public delegate int Secp256k1EcdhHashFunc(in Secp256HashFuncState state); - - public static unsafe class ContextExtensions - { - /// <summary> - /// Signs a 32byte message digest with the specified secret key on the current context and writes the signature to the specified buffer - /// </summary> - /// <param name="context"></param> - /// <param name="secretKey">The 32byte secret key used to sign messages from the user</param> - /// <param name="digest">The 32byte message digest to compute the signature of</param> - /// <param name="signature">The buffer to write the signature output to, must be at-least 64 bytes</param> - /// <returns>The number of bytes written to the signature buffer, or less than 1 if the operation failed</returns> - public static ERRNO SchnorSignDigest(this in Secp256k1Context context, ReadOnlySpan<byte> secretKey, ReadOnlySpan<byte> digest, Span<byte> signature) - { - //Check the signature buffer size - if (signature.Length < SignatureSize) - { - return ERRNO.E_FAIL; - } - - //Message digest must be exactly 32 bytes long - if (digest.Length != (int)HashAlg.SHA256) - { - return ERRNO.E_FAIL; - } - - //Secret key size must be exactly the size of the secret key struct - if(secretKey.Length != sizeof(Secp256k1SecretKey)) - { - return ERRNO.E_FAIL; - } - - //Stack allocated keypair - KeyPair keyPair = new(); - - //Init the secret key struct from key data - Secp256k1SecretKey secKeyStruct = MemoryMarshal.Read<Secp256k1SecretKey>(secretKey); - - //Randomize the context and create the keypair - if (!context.CreateKeyPair(&keyPair, &secKeyStruct)) - { - return ERRNO.E_FAIL; - } - - //Create the random nonce - byte* random = stackalloc byte[RandomBufferSize]; - - //Fill the buffer with random bytes - context.Lib.GetRandomBytes(new Span<byte>(random, RandomBufferSize)); - - try - { - fixed (byte* sigPtr = &MemoryMarshal.GetReference(signature), - digestPtr = &MemoryMarshal.GetReference(digest)) - { - //Sign the message hash and write the output to the signature buffer - if (context.Lib._signHash(context.Context, sigPtr, digestPtr, &keyPair, random) != 1) - { - return ERRNO.E_FAIL; - } - } - } - finally - { - //Erase entropy - MemoryUtil.InitializeBlock(random, RandomBufferSize); - - //Clear the keypair, contains the secret key, even if its stack allocated - MemoryUtil.ZeroStruct(&keyPair); - } - - //Signature size is always 64 bytes - return SignatureSize; - } - - /// <summary> - /// Generates an x-only Schnor encoded public key from the specified secret key on the - /// current context and writes it to the specified buffer. - /// </summary> - /// <param name="context"></param> - /// <param name="secretKey">The 32byte secret key used to derrive the public key from</param> - /// <param name="pubKeyBuffer">The buffer to write the x-only Schnor encoded public key</param> - /// <returns>The number of bytes written to the output buffer, or 0 if the operation failed</returns> - /// <exception cref="CryptographicException"></exception> - public static ERRNO GeneratePubKeyFromSecret(this in Secp256k1Context context, ReadOnlySpan<byte> secretKey, Span<byte> pubKeyBuffer) - { - if (secretKey.Length != sizeof(Secp256k1SecretKey)) - { - throw new CryptographicException($"Your secret key must be exactly {sizeof(Secp256k1SecretKey)} bytes long"); - } - - if (pubKeyBuffer.Length < XOnlyPublicKeySize) - { - throw new CryptographicException($"Your public key buffer must be at least {XOnlyPublicKeySize} bytes long"); - } - - //Protect for released lib - context.Lib.SafeLibHandle.ThrowIfClosed(); - - //Stack allocated keypair and x-only public key - Secp256k1PublicKey xOnlyPubKey = new(); - Secp256k1SecretKey secKeyStruct = MemoryMarshal.Read<Secp256k1SecretKey>(secretKey); - KeyPair keyPair = new(); - - try - { - //Init context and keypair - if (!context.CreateKeyPair(&keyPair, &secKeyStruct)) - { - return ERRNO.E_FAIL; - } - - //X-only public key from the keypair - if (context.Lib._createXonly(context.Context, &xOnlyPubKey, 0, &keyPair) != 1) - { - return ERRNO.E_FAIL; - } - - fixed (byte* pubBuffer = &MemoryMarshal.GetReference(pubKeyBuffer)) - { - //Serialize the public key to the buffer as an X-only public key without leading status byte - if (context.Lib._serializeXonly(context.Context, pubBuffer, &xOnlyPubKey) != 1) - { - return ERRNO.E_FAIL; - } - } - } - finally - { - //Clear the keypair, contains the secret key, even if its stack allocated - MemoryUtil.ZeroStruct(&keyPair); - } - - //PubKey length is constant - return XOnlyPublicKeySize; - } - - /// <summary> - /// Verifies that a given secret key is valid using the current context - /// </summary> - /// <param name="context"></param> - /// <param name="secretKey">The secret key to verify</param> - /// <returns>A boolean value that indicates if the secret key is valid or not</returns> - /// <exception cref="CryptographicException"></exception> - public static bool VerifySecretKey(this in Secp256k1Context context, ReadOnlySpan<byte> secretKey) - { - if (secretKey.Length != sizeof(Secp256k1SecretKey)) - { - throw new CryptographicException($"Your secret key must be exactly {sizeof(Secp256k1SecretKey)} bytes long"); - } - - context.Lib.SafeLibHandle.ThrowIfClosed(); - - //Get sec key ref and verify - fixed(byte* ptr = &MemoryMarshal.GetReference(secretKey)) - { - return context.Lib._secKeyVerify.Invoke(context.Context, ptr) == 1; - } - } - - - [StructLayout(LayoutKind.Sequential)] - private readonly ref struct EcdhHashFuncState - { - public readonly IntPtr HashFunc { get; init; } - public readonly IntPtr Opaque { get; init; } - public readonly int OutLen { get; init; } - } - - /// <summary> - /// Verifies that a given secret key is valid using the current context - /// </summary> - /// <param name="context"></param> - /// <param name="secretKey">The secret key to verify</param> - /// <returns>A boolean value that indicates if the secret key is valid or not</returns> - /// <exception cref="ArgumentException"></exception> - public static bool ComputeSharedKey(this in Secp256k1Context context, Span<byte> data, ReadOnlySpan<byte> xOnlyPubKey, ReadOnlySpan<byte> secretKey, Secp256k1EcdhHashFunc callback, IntPtr opaque) - { - if (secretKey.Length != sizeof(Secp256k1SecretKey)) - { - throw new ArgumentException($"Your secret key buffer must be exactly {sizeof(Secp256k1SecretKey)} bytes long"); - } - - //Init callback state struct - EcdhHashFuncState state = new() - { - HashFunc = Marshal.GetFunctionPointerForDelegate(callback), - Opaque = opaque, - OutLen = data.Length - }; - - context.Lib.SafeLibHandle.ThrowIfClosed(); - - //Stack allocated keypair and x-only public key - Secp256k1PublicKey peerPubKey = new(); - - //Parse the public key from the buffer - fixed (byte* pubkeyPtr = &MemoryMarshal.GetReference(xOnlyPubKey)) - { - context.Lib._xOnlyPubkeyParse(context.Context, &peerPubKey, pubkeyPtr); - } - - fixed (byte* dataPtr = &MemoryMarshal.GetReference(data), - secKeyPtr = &MemoryMarshal.GetReference(secretKey)) - { - return context.Lib._ecdh.Invoke( - context.Context, - dataPtr, - &peerPubKey, - secKeyPtr, - UmanagedEcdhHashFuncCallback, - &state - ) == 1; - } - - /* - * Umanaged wrapper function for invoking the safe user callback - * from the unmanaged lib - */ - static int UmanagedEcdhHashFuncCallback(byte* output, byte* x32, byte* y32, void* opaque) - { - //Recover the callback - if (opaque == null) - { - return 0; - } - - EcdhHashFuncState* state = (EcdhHashFuncState*)opaque; - - //Init user-state structure - Secp256HashFuncState userState = new(output, state->OutLen, x32, 32, new(opaque)); - - //Recover the function pointer - Secp256k1EcdhHashFunc callback = Marshal.GetDelegateForFunctionPointer<Secp256k1EcdhHashFunc>(state->HashFunc); - - //Invoke the callback - return callback(in userState); - } - } - } -}
\ No newline at end of file diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/IRandomSource.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/IRandomSource.cs deleted file mode 100644 index 4e1861d..0000000 --- a/back-end/libs/NVault.Crypto.Secp256k1/src/IRandomSource.cs +++ /dev/null @@ -1,32 +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; - -namespace NVault.Crypto.Secp256k1 -{ - /// <summary> - /// Represents a generator for random data, that fills abinary buffer with random bytes - /// on demand. - /// </summary> - public interface IRandomSource - { - /// <summary> - /// Fills the given buffer with random bytes - /// </summary> - /// <param name="buffer">Binary buffer to fill with random data</param> - void GetRandomBytes(Span<byte> buffer); - } -}
\ No newline at end of file diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs deleted file mode 100644 index 8dda269..0000000 --- a/back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs +++ /dev/null @@ -1,284 +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.InteropServices; - -using VNLib.Hashing; -using VNLib.Utils; -using VNLib.Utils.Native; -using VNLib.Utils.Extensions; - -namespace NVault.Crypto.Secp256k1 -{ - - internal unsafe delegate int EcdhHasFunc(byte* output, byte* x32, byte* y32, void* data); - - public unsafe class LibSecp256k1 : VnDisposeable - { - public const int SignatureSize = 64; - public const int RandomBufferSize = 32; - public const int XOnlyPublicKeySize = 32; - - public static readonly int SecretKeySize = sizeof(Secp256k1SecretKey); - - /* - * Unsafe structures that represent the native keypair and x-only public key - * structures. They hold character arrays - */ - [StructLayout(LayoutKind.Sequential, Size = 96)] - internal struct KeyPair - { - public fixed byte data[96]; - } - - /// <summary> - /// 1:1 with the secp256k1_pubkey structure - /// </summary> - [StructLayout(LayoutKind.Sequential, Size = 64)] - internal struct Secp256k1PublicKey - { - public fixed byte data[64]; - } - - - //Native methods - [SafeMethodName("secp256k1_context_create")] - internal delegate IntPtr ContextCreate(int flags); - - [SafeMethodName("secp256k1_context_destroy")] - internal delegate void ContextDestroy(IntPtr context); - - [SafeMethodName("secp256k1_context_randomize")] - internal delegate int RandomizeContext(IntPtr context, byte* seed32); - - [SafeMethodName("secp256k1_keypair_create")] - internal delegate int KeypairCreate(IntPtr context, KeyPair* keyPair, byte* secretKey); - - [SafeMethodName("secp256k1_keypair_xonly_pub")] - internal delegate int KeypairXOnlyPub(IntPtr ctx, Secp256k1PublicKey* pubkey, int pk_parity, KeyPair* keypair); - - [SafeMethodName("secp256k1_xonly_pubkey_serialize")] - internal delegate int XOnlyPubkeySerialize(IntPtr ctx, byte* output32, Secp256k1PublicKey* pubkey); - - [SafeMethodName("secp256k1_schnorrsig_sign32")] - internal delegate int SignHash(IntPtr ctx, byte* sig64, byte* msg32, KeyPair* keypair, byte* aux_rand32); - - [SafeMethodName("secp256k1_ec_seckey_verify")] - internal delegate int SecKeyVerify(IntPtr ctx, in byte* seckey); - - [SafeMethodName("secp256k1_ec_pubkey_serialize")] - internal delegate int PubKeySerialize(IntPtr ctx, byte* outPubKey, ulong* outLen, Secp256k1PublicKey* pubKey, uint flags); - - [SafeMethodName("secp256k1_xonly_pubkey_parse")] - internal delegate int XOnlyPubkeyParse(IntPtr ctx, Secp256k1PublicKey* pubkey, byte* input32); - - [SafeMethodName("secp256k1_ecdh")] - internal delegate int Ecdh( - IntPtr ctx, - byte* output, - Secp256k1PublicKey* pubkey, - byte* scalar, - EcdhHasFunc hashFunc, - void* dataPtr - ); - - - /// <summary> - /// Loads the Secp256k1 library from the specified path and creates a wrapper class (loads methods from the library) - /// </summary> - /// <param name="dllPath">The realtive or absolute path to the shared library</param> - /// <param name="search">The DLL probing path pattern</param> - /// <returns>The <see cref="LibSecp256k1"/> library wrapper class</returns> - /// <exception cref="DllNotFoundException"></exception> - /// <exception cref="ArgumentNullException"></exception> - /// <exception cref="MissingMemberException"></exception> - /// <exception cref="EntryPointNotFoundException"></exception> - public static LibSecp256k1 LoadLibrary(string dllPath, DllImportSearchPath search, IRandomSource? random) - { - _ = dllPath?? throw new ArgumentNullException(nameof(dllPath)); - - //try to load the library - SafeLibraryHandle lib = SafeLibraryHandle.LoadLibrary(dllPath, search); - - //try to create the wrapper class, if it fails, dispose the library - try - { - //setup fallback random source if null - random ??= new FallbackRandom(); - - //Create the lib - return new LibSecp256k1(lib, random); - } - catch - { - //Dispose the library if the creation failed - lib.Dispose(); - throw; - } - } - - /// <summary> - /// Loads the Secp256k1 library from the specified path and creates a wrapper class (loads methods from the library) - /// </summary> - /// <param name="handle">The handle to the shared library</param> - /// <param name="random">An optional random source to create random entropy and secrets from</param> - /// <returns>The <see cref="LibSecp256k1"/> library wrapper class</returns> - /// <exception cref="ArgumentNullException"></exception> - /// <exception cref="MissingMemberException"></exception> - /// <exception cref="EntryPointNotFoundException"></exception> - public static LibSecp256k1 FromHandle(SafeLibraryHandle handle, IRandomSource? random) - { - _ = handle ?? throw new ArgumentNullException(nameof(handle)); - //setup fallback random source if null - random ??= new FallbackRandom(); - //Create the lib - return new LibSecp256k1(handle, random); - } - - /// <summary> - /// The underlying library handle - /// </summary> - public SafeLibraryHandle SafeLibHandle { get; } - - internal readonly KeypairCreate _createKeyPair; - internal readonly ContextCreate _create; - internal readonly RandomizeContext _randomize; - internal readonly ContextDestroy _destroy; - internal readonly KeypairXOnlyPub _createXonly; - internal readonly XOnlyPubkeySerialize _serializeXonly; - internal readonly SignHash _signHash; - internal readonly SecKeyVerify _secKeyVerify; - internal readonly PubKeySerialize _pubKeySerialize; - internal readonly Ecdh _ecdh; - internal readonly XOnlyPubkeyParse _xOnlyPubkeyParse; - private readonly IRandomSource _randomSource; - - /// <summary> - /// Creates a new instance of the <see cref="LibSecp256k1"/> class from the specified library handle - /// </summary> - /// <param name="handle">The library handle that referrences the secp256k1 platform specific library</param> - /// <remarks> - /// This method attempts to capture all the native methods from the library, which may throw if the library is not valid. - /// </remarks> - /// <exception cref="ArgumentNullException"></exception> - /// <exception cref="MissingMemberException"></exception> - /// <exception cref="EntryPointNotFoundException"></exception> - public LibSecp256k1(SafeLibraryHandle handle, IRandomSource randomSource) - { - //Store library handle - SafeLibHandle = handle ?? throw new ArgumentNullException(nameof(handle)); - - //Get all method handles and store them - _create = handle.DangerousGetMethod<ContextCreate>(); - _createKeyPair = handle.DangerousGetMethod<KeypairCreate>(); - _randomize = handle.DangerousGetMethod<RandomizeContext>(); - _destroy = handle.DangerousGetMethod<ContextDestroy>(); - _createXonly = handle.DangerousGetMethod<KeypairXOnlyPub>(); - _serializeXonly = handle.DangerousGetMethod<XOnlyPubkeySerialize>(); - _signHash = handle.DangerousGetMethod<SignHash>(); - _secKeyVerify = handle.DangerousGetMethod<SecKeyVerify>(); - _pubKeySerialize = handle.DangerousGetMethod<PubKeySerialize>(); - _ecdh = handle.DangerousGetMethod<Ecdh>(); - _xOnlyPubkeyParse = handle.DangerousGetMethod<XOnlyPubkeyParse>(); - - //Store random source - _randomSource = randomSource; - } - - /// <summary> - /// Creates a new instance of the <see cref="LibSecp256k1"/> class from the specified library handle - /// with a fallback random source - /// </summary> - /// <param name="handle">The library handle</param> - /// <exception cref="ArgumentNullException"></exception> - /// <exception cref="MissingMemberException"></exception> - /// <exception cref="EntryPointNotFoundException"></exception> - public LibSecp256k1(SafeLibraryHandle handle):this(handle, new FallbackRandom()) - {} - - /// <summary> - /// Generates a new secret key and writes it to the specified buffer. The buffer size must be exactly <see cref="SecretKeySize"/> bytes long - /// <para> - /// NOTE: You should verify this validity of the key against the library with a new <see cref="Secp256k1Context"/> - /// </para> - /// </summary> - /// <param name="buffer">The secret key buffer</param> - /// <exception cref="ArgumentException"></exception> - public void CreateSecretKey(Span<byte> buffer) - { - //Protect for released lib - SafeLibHandle.ThrowIfClosed(); - - if(buffer.Length != sizeof(Secp256k1SecretKey)) - { - throw new ArgumentException($"Buffer must be exactly {sizeof(Secp256k1SecretKey)} bytes long", nameof(buffer)); - } - - //Fill the buffer with random bytes - _randomSource.GetRandomBytes(buffer); - } - - /// <summary> - /// Fills the given buffer with random bytes from - /// the internal random source - /// </summary> - /// <param name="buffer">The buffer to fill with random data</param> - public void GetRandomBytes(Span<byte> buffer) - { - //Protect for released lib - SafeLibHandle.ThrowIfClosed(); - - _randomSource.GetRandomBytes(buffer); - } - - /// <summary> - /// Creates a new <see cref="Secp256k1Context"/> from the current managed library - /// </summary> - /// <param name="Lib"></param> - /// <returns>The new <see cref="Secp256k1Context"/> object from the library</returns> - /// <exception cref="OutOfMemoryException"></exception> - public Secp256k1Context CreateContext() - { - //Protect for released lib - SafeLibHandle.ThrowIfClosed(); - - //Create new context - IntPtr context = _create(1); - - if (context == IntPtr.Zero) - { - throw new OutOfMemoryException("Failed to create the new Secp256k1 context"); - } - - return new Secp256k1Context(this, context); - } - - protected override void Free() - { - //Free native library - SafeLibHandle.Dispose(); - } - - private record class FallbackRandom : IRandomSource - { - public void GetRandomBytes(Span<byte> buffer) - { - //Use the random generator from the crypto lib - RandomHash.GetRandomBytes(buffer); - } - } - } -}
\ No newline at end of file diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/NVault.Crypto.Secp256k1.csproj b/back-end/libs/NVault.Crypto.Secp256k1/src/NVault.Crypto.Secp256k1.csproj deleted file mode 100644 index 5014d89..0000000 --- a/back-end/libs/NVault.Crypto.Secp256k1/src/NVault.Crypto.Secp256k1.csproj +++ /dev/null @@ -1,27 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>net8.0</TargetFramework> - <Nullable>enable</Nullable> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <PackageReadmeFile>README.md</PackageReadmeFile> - <RootNamespace>NVault.Crypto.Secp256k1</RootNamespace> - <AssemblyName>NVault.Crypto.Secp256k1</AssemblyName> - </PropertyGroup> - - <PropertyGroup> - <Authors>Vaughn Nugent</Authors> - <Company>Vaughn Nugent</Company> - <Product>NVault.Crypto.Secp256k1</Product> - <Description>Provides a managed library for the Bitcoin Core secp256k1 library, along with other helper types for NVault</Description> - <Copyright>Copyright © 2024 Vaughn Nugent</Copyright> - <PackageProjectUrl>https://www.vaughnnugent.com/resources/software/modules/NVault</PackageProjectUrl> - <RepositoryUrl>https://github.com/VnUgE/NVault/tree/master/</RepositoryUrl> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="VNLib.Hashing.Portable" Version="0.1.0-ci0109" /> - <PackageReference Include="VNLib.Utils" Version="0.1.0-ci0109" /> - </ItemGroup> - -</Project> diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs deleted file mode 100644 index c82321c..0000000 --- a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs +++ /dev/null @@ -1,56 +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.InteropServices; - -namespace NVault.Crypto.Secp256k1 -{ - [StructLayout(LayoutKind.Sequential)] - public unsafe readonly ref struct Secp256HashFuncState - { - - /// <summary> - /// The opaque pointer passed to the hash function - /// </summary> - public readonly IntPtr Opaque { get; } - - private readonly byte* _output; - private readonly byte* _xCoord; - private readonly int _outputLength; - private readonly int _xCoordLength; - - internal Secp256HashFuncState(byte* output, int outputLength, byte* xCoord, int xCoordLength, IntPtr opaque) - { - Opaque = opaque; - _output = output; - _outputLength = outputLength; - _xCoord = xCoord; - _xCoordLength = xCoordLength; - } - - /// <summary> - /// Gets the output buffer as a span - /// </summary> - /// <returns>The output buffer span</returns> - public readonly Span<byte> GetOutput() => new(_output, _outputLength); - - /// <summary> - /// Gets the x coordinate argument as a span - /// </summary> - /// <returns>The xcoordinate buffer span</returns> - public readonly ReadOnlySpan<byte> GetXCoordArg() => new(_xCoord, _xCoordLength); - } -}
\ No newline at end of file diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs deleted file mode 100644 index dfb3ff8..0000000 --- a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs +++ /dev/null @@ -1,76 +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.Extensions; -using VNLib.Utils.Memory; - -using static NVault.Crypto.Secp256k1.LibSecp256k1; - -namespace NVault.Crypto.Secp256k1 -{ - /// <summary> - /// Represents a Secp256k1 context, it is used to randomize the instance, create key pairs, - /// and frees the context when disposed - /// </summary> - /// <param name="Lib">The <see cref="LibSecp256k1"/> library instance</param> - /// <param name="Context">A pointer to the initialized context instance</param> - public readonly record struct Secp256k1Context(LibSecp256k1 Lib, IntPtr Context) : IDisposable - { - /// <summary> - /// Randomizes the context with random data using the library's random source - /// </summary> - /// <returns>True if the context was successfully randomized, false otherwise</returns> - public unsafe readonly bool Randomize() - { - Lib.SafeLibHandle.ThrowIfClosed(); - - //Randomze the context - byte* entropy = stackalloc byte[RandomBufferSize]; - - //Get random bytes - Lib.GetRandomBytes(new Span<byte>(entropy, RandomBufferSize)); - - //call native randomize method - bool result = Lib._randomize(Context, entropy) == 1; - - //Zero the randomness buffer before returning to avoid leaking random data - MemoryUtil.InitializeBlock(entropy, RandomBufferSize); - - return result; - } - - internal unsafe readonly bool CreateKeyPair(KeyPair* keyPair, Secp256k1SecretKey* secretKey) - { - Lib.SafeLibHandle.ThrowIfClosed(); - - //Create the keypair from the secret key - return Lib._createKeyPair(Context, keyPair, (byte*)secretKey) == 1; - } - - /// <summary> - /// Releases the context instance and frees the memory - /// </summary> - public readonly void Dispose() - { - if (Context != IntPtr.Zero) - { - //Free the context - Lib._destroy(Context); - } - } - } -}
\ No newline at end of file diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs deleted file mode 100644 index 35734ae..0000000 --- a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs +++ /dev/null @@ -1,58 +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.InteropServices; - -using VNLib.Utils.Memory; - -namespace NVault.Crypto.Secp256k1 -{ - /// <summary> - /// Represents a Secp256k1 secret key, the size is fixed, and should use - /// the sizeof() operator to get the size - /// </summary> - [StructLayout(LayoutKind.Sequential, Size = 32)] - public unsafe struct Secp256k1SecretKey - { - private fixed byte data[32]; - - /// <summary> - /// Implict cast to a span of raw bytes - /// </summary> - /// <param name="key">The secret key to cast</param> - public static implicit operator Span<byte>(Secp256k1SecretKey key) => new(key.data, 32); - - /// <summary> - /// Casts the secret key span to a <see cref="Secp256k1SecretKey"/> via a structure copy - /// </summary> - /// <param name="key">The key data to copy</param> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public static explicit operator Secp256k1SecretKey(ReadOnlySpan<byte> key) => FromSpan(key); - - /// <summary> - /// Creates a new <see cref="Secp256k1SecretKey"/> from a span of bytes - /// by copying the bytes into the struct - /// </summary> - /// <param name="span">The secret key data to copy</param> - /// <returns>An initilaized <see cref="Secp256k1SecretKey"/></returns> - public static Secp256k1SecretKey FromSpan(ReadOnlySpan<byte> span) - { - Secp256k1SecretKey newKey = new(); - MemoryUtil.CopyStruct(span, ref newKey); - return newKey; - } - } -}
\ No newline at end of file diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/UnmanagedRandomSource.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/UnmanagedRandomSource.cs deleted file mode 100644 index 360de21..0000000 --- a/back-end/libs/NVault.Crypto.Secp256k1/src/UnmanagedRandomSource.cs +++ /dev/null @@ -1,101 +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.InteropServices; - -using VNLib.Utils; -using VNLib.Utils.Native; -using VNLib.Utils.Extensions; - -namespace NVault.Crypto.Secp256k1 -{ - - /// <summary> - /// A wrapper class for an unmanaged random source that conforms to the <see cref="IRandomSource"/> interface - /// </summary> - public class UnmanagedRandomSource : VnDisposeable, IRandomSource - { - public const string METHOD_NAME = "getRandomBytes"; - - unsafe delegate void UnmanagedRandomSourceDelegate(byte* buffer, int size); - - - private readonly bool OwnsHandle; - private readonly SafeLibraryHandle _library; - private readonly UnmanagedRandomSourceDelegate _getRandomBytes; - - /// <summary> - /// Loads the unmanaged random source from the given library - /// and attempts to get the random bytes method <see cref="METHOD_NAME"/> - /// </summary> - /// <param name="path"></param> - /// <param name="search"></param> - /// <returns>The wrapped library that conforms to the <see cref="IRandomSource"/></returns> - public static UnmanagedRandomSource LoadLibrary(string path, DllImportSearchPath search) - { - //Try to load the library - SafeLibraryHandle lib = SafeLibraryHandle.LoadLibrary(path, search); - try - { - return new UnmanagedRandomSource(lib, true); - } - catch - { - //release lib - lib.Dispose(); - throw; - } - } - - /// <summary> - /// Creates the unmanaged random source from the given library - /// </summary> - /// <param name="lib">The library handle to wrap</param> - /// <exception cref="ObjectDisposedException"></exception> - /// <exception cref="EntryPointNotFoundException"></exception> - public UnmanagedRandomSource(SafeLibraryHandle lib, bool ownsHandle) - { - lib.ThrowIfClosed(); - - _library = lib; - - //get the method delegate - _getRandomBytes = lib.DangerousGetMethod<UnmanagedRandomSourceDelegate>(METHOD_NAME); - - OwnsHandle = ownsHandle; - } - - public unsafe void GetRandomBytes(Span<byte> buffer) - { - _library.ThrowIfClosed(); - - //Fix buffer and call unmanaged method - fixed(byte* ptr = &MemoryMarshal.GetReference(buffer)) - { - _getRandomBytes(ptr, buffer.Length); - } - } - - ///<inheritdoc/> - protected override void Free() - { - if (OwnsHandle) - { - _library.Dispose(); - } - } - } -}
\ No newline at end of file |