Open danielcrenna opened 6 years ago
It doesn't work on .NET standard? /cc @BurningEnlightenment
Also: https://github.com/bfriesen/LibsodiumDotNetStandardSpike /cc @bfriesen
Right, there's a lot of WIP but nothing concrete/importable for .NET Standard 2.0; I assume the challenge is transparent packaging and resolution of native libraries at runtime? If there's some specific set of tasks off of master that I can help with, let me know.
On Sep 24, 2017, at 6:29 PM, Frank Denis notifications@github.com wrote:
Also: https://github.com/bfriesen/LibsodiumDotNetStandardSpike /cc @bfriesen
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.
@jedisct1 Thanks for the pointers.
I was able to get @BurningEnlightenment's fork building with a few caveats. After that work, as it turns out, I didn't actually need crypto_sign_ed25519_sk_to_seed
, since it seems to function as a simple array copy, and using the private key directly would produce the same result as Chaos.NaCl which is equivalent to crypto_sign_seed_keypair
.
Caveats:
net461
/netstandard1.3
rather than netstandard2.0
; attempting to target netstandard2.0 results in compiler warnings:
"Package 'libsodium 1.0.12-preview-01' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETStandard,Version=v2.0'. This package may not be fully compatible with your project"Utilities
Sodium
access internal
means I had to extend with a proxy class for Ed25519
to access the methods I was looking for. So, it works, but it's far from something I could probably get away with shipping in production. I also don't know how libsodium-net will protect, for example, an attacker replacing libsodium itself dynamically with their own interop assemblies.
If there is a timeline for the .NET Standard stream reaching NuGet let me know, and if there are any work items I can pitch in to help on if there is something back this fork, since it appears mostly ready to go.
FYI, here is my hybrid Chaos.NaCl/libsodium-net class:
using System;
using Sodium.Interop;
namespace Sodium
{
public static class Ed25519
{
public static readonly int PublicKeySizeInBytes = 32;
public static readonly int SignatureSizeInBytes = 64;
public static readonly int ExpandedPrivateKeySizeInBytes = 32 * 2;
public static readonly int PrivateKeySeedSizeInBytes = 32; // 64 in Chaos.NaCl
public static readonly int SharedKeySizeInBytes = 32;
public static bool Verify(byte[] signature, byte[] message, byte[] publicKey)
{
if (signature == null)
throw new ArgumentNullException(nameof(signature));
if (message == null)
throw new ArgumentNullException(nameof(message));
if (publicKey == null)
throw new ArgumentNullException(nameof(publicKey));
if (signature.Length != SignatureSizeInBytes)
throw new ArgumentException(string.Format("Signature size must be {0}", SignatureSizeInBytes), nameof(signature.Length));
if (publicKey.Length != PublicKeySizeInBytes)
throw new ArgumentException(string.Format("Public key size must be {0}", PublicKeySizeInBytes), nameof(publicKey.Length));
long bufferLength = SignatureSizeInBytes;
return SodiumLibrary.crypto_sign_open(signature, ref bufferLength, message, message.Length, publicKey) != 0;
}
public static byte[] Sign(byte[] message, byte[] expandedPrivateKey)
{
var signature = new byte[SignatureSizeInBytes];
long bufferLength = SignatureSizeInBytes;
SodiumLibrary.crypto_sign(signature, ref bufferLength, message, message.Length, expandedPrivateKey);
return signature;
}
public static byte[] PublicKeyFromSeed(byte[] privateKeySeed)
{
KeyPairFromSeed(out var publicKey, out var _, privateKeySeed);
return publicKey;
}
public static byte[] ExpandedPrivateKeyFromSeed(byte[] privateKeySeed)
{
KeyPairFromSeed(out var _, out var privateKey, privateKeySeed);
return privateKey;
}
public static void KeyPairFromSeed(out byte[] publicKey, out byte[] expandedPrivateKey, byte[] privateKeySeed)
{
if (privateKeySeed == null)
throw new ArgumentNullException(nameof(privateKeySeed));
if (privateKeySeed.Length != PrivateKeySeedSizeInBytes)
throw new ArgumentException(nameof(privateKeySeed));
var pk = new byte[32]; // alloc
var sk = new byte[32]; // alloc
SodiumLibrary.crypto_sign_seed_keypair(pk, sk, privateKeySeed);
publicKey = pk;
expandedPrivateKey = sk;
}
public static void PublicKeyFromPrivateKey(out byte[] publicKey, byte[] privateKey)
{
var pk = new byte[32]; // alloc
var sk = new byte[32]; // alloc
SodiumLibrary.crypto_sign_seed_keypair(pk, sk, privateKey);
publicKey = pk;
}
}
}
libsodium also requires 64 bytes for the secret key (sk
in your example - it includes a copy of the public key in addition to the actual secret key).
Hello,
Since libsodium-net does not currently work on .NET Standard (https://github.com/adamcaudill/libsodium-net/pull/155), I'm using your library for Ed25519.
However, I can't use it to recreate a public key given a known good private key, for the reasons listed here: https://bitcoin.stackexchange.com/a/42456; it may be that this implementation is just missing the method
crypto_sign_ed25519_sk_to_seed
, is that correct?