diff --git a/Beacon.Sdk.Tests/Beacon.Sdk.Tests.csproj b/Beacon.Sdk.Tests/Beacon.Sdk.Tests.csproj
index 21bcddf..ad1198d 100644
--- a/Beacon.Sdk.Tests/Beacon.Sdk.Tests.csproj
+++ b/Beacon.Sdk.Tests/Beacon.Sdk.Tests.csproj
@@ -7,14 +7,18 @@
-
-
-
-
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
-
+
diff --git a/Beacon.Sdk.Tests/CryptoTests.cs b/Beacon.Sdk.Tests/CryptoTests.cs
new file mode 100644
index 0000000..12b927f
--- /dev/null
+++ b/Beacon.Sdk.Tests/CryptoTests.cs
@@ -0,0 +1,72 @@
+namespace Beacon.Sdk.Tests
+{
+ using Core.Infrastructure.Cryptography;
+ using Core.Infrastructure.Cryptography.NaCl;
+ using Core.Infrastructure.Cryptography.BouncyCastle;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using System.Text;
+
+ [TestClass]
+ public class CryptoTests
+ {
+ private byte[] randomPubKeyBytes { get; } =
+ {
+ 0x58, 0x96, 0xB4, 0xDE, 0x36, 0x93, 0x5F, 0x5, 0x79, 0x4E, 0xB8, 0x7, 0x3F, 0xB1, 0x7F, 0xE6, 0xAD,
+ 0x64, 0xFF, 0xE3, 0x48, 0x60, 0x81, 0x1C, 0x9D, 0xDF, 0xB9, 0xE4, 0xF3, 0x2F, 0xF7, 0x5B,
+ };
+
+ private byte[] convertedPubKeyBytes { get; } =
+ {
+ 0x50, 0x94, 0xD3, 0xF3, 0x88, 0xFD, 0x19, 0xF3, 0x3D, 0xBF, 0xA7, 0x3A, 0x6C, 0x9E, 0xCD, 0x80, 0x7C,
+ 0x1C, 0x92, 0x74, 0xE3, 0xA0, 0x71, 0x8F, 0xEC, 0xB8, 0xDD, 0x8D, 0x3E, 0x78, 0x66, 0x15
+ };
+
+ [TestMethod]
+ public void TestSodiumConvertEd25519PublicKeyToCurve25519PublicKey()
+ {
+ var actual = PublicKeyAuth.ConvertEd25519PublicKeyToCurve25519PublicKey(randomPubKeyBytes);
+ CollectionAssert.AreEqual(convertedPubKeyBytes, actual);
+ }
+
+ [TestMethod]
+ public void TestConvertEd25519PublicKeyToCurve25519PublicKey()
+ {
+ var actual = new byte[32];
+ MontgomeryCurve25519.EdwardsToMontgomery(actual, randomPubKeyBytes);
+ CollectionAssert.AreEqual(convertedPubKeyBytes, actual);
+ }
+
+ [TestMethod]
+ public void CanEncryptAndDecryptBySecretBox()
+ {
+ var key = SecureRandom.GetRandomBytes(32);
+ var nonce = SecureRandom.GetRandomBytes(24);
+ var message = Encoding.UTF8.GetBytes("Test message for secret box");
+
+ var cipher = SecretBox.Create(message, nonce, key);
+
+ var decrypted = SecretBox.Open(cipher, nonce, key);
+
+ CollectionAssert.AreEqual(message, decrypted);
+ }
+
+ [TestMethod]
+ public void CanEncryptAndDecryptBySealedSecretBox()
+ {
+ var seed = SecureRandom.GetRandomBytes(32);
+
+ var ed25519keyPair = PublicKeyAuth.GenerateKeyPair(seed);
+
+ var curve25519sk = Ed25519Extensions.ConvertEd25519SecretKeyToCurve25519SecretKey(ed25519keyPair.PrivateKey);
+ var curve25519pk = Ed25519Extensions.ConvertEd25519PublicKeyToCurve25519PublicKey(ed25519keyPair.PublicKey);
+
+ var message = Encoding.UTF8.GetBytes("Test message for secret box");
+
+ var cipher = SealedPublicKeyBox.Create(message, curve25519pk);
+
+ var decrypted = SealedPublicKeyBox.Open(cipher, curve25519sk, curve25519pk);
+
+ CollectionAssert.AreEqual(message, decrypted);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Beacon.Sdk.csproj b/Beacon.Sdk/Beacon.Sdk.csproj
index 0410cff..5ee11f6 100644
--- a/Beacon.Sdk/Beacon.Sdk.csproj
+++ b/Beacon.Sdk/Beacon.Sdk.csproj
@@ -14,19 +14,19 @@
Mikhail Tatarenko
Beacon.Sdk
Beacon .NET SDK for Tezos wallet / dApps developers.
- 1.0.16
+ 1.0.18
Copyright © Baking Bad 2019-2022
enable
- netstandard2.0
+ netstandard2.1
+
-
diff --git a/Beacon.Sdk/Core/Domain/Entities/PeerFactory.cs b/Beacon.Sdk/Core/Domain/Entities/PeerFactory.cs
index 3b58716..2a25494 100644
--- a/Beacon.Sdk/Core/Domain/Entities/PeerFactory.cs
+++ b/Beacon.Sdk/Core/Domain/Entities/PeerFactory.cs
@@ -1,7 +1,6 @@
namespace Beacon.Sdk.Core.Domain.Entities
{
- using System;
- using Infrastructure.Cryptography.Libsodium;
+ using global::Beacon.Sdk.Core.Infrastructure.Cryptography;
using Interfaces;
using Netezos.Encoding;
using Utils;
@@ -17,10 +16,7 @@ public PeerFactory(ICryptographyService cryptographyService)
public static byte[] Hash(byte[] message, int bufferLength)
{
- var buffer = new byte[bufferLength];
- Sodium.CryptoGenericHash(buffer, bufferLength, message, (ulong)message.Length, Array.Empty(), 0);
-
- return buffer;
+ return GenericHash.Hash(message, bufferLength);
}
public Peer Create(HexString hexPublicKey, string name, string version, string relayServer, bool isActive = false)
diff --git a/Beacon.Sdk/Core/Domain/Interfaces/Data/ISessionKeyPairRepository.cs b/Beacon.Sdk/Core/Domain/Interfaces/Data/ISessionKeyPairRepository.cs
index ff5f899..40931a1 100644
--- a/Beacon.Sdk/Core/Domain/Interfaces/Data/ISessionKeyPairRepository.cs
+++ b/Beacon.Sdk/Core/Domain/Interfaces/Data/ISessionKeyPairRepository.cs
@@ -2,7 +2,6 @@
namespace Beacon.Sdk.Core.Domain.Interfaces.Data
{
- using Infrastructure.Cryptography.Libsodium;
using Utils;
public interface ISessionKeyPairRepository
diff --git a/Beacon.Sdk/Core/Domain/Interfaces/ICryptographyService.cs b/Beacon.Sdk/Core/Domain/Interfaces/ICryptographyService.cs
index ea80f39..f9a1c60 100644
--- a/Beacon.Sdk/Core/Domain/Interfaces/ICryptographyService.cs
+++ b/Beacon.Sdk/Core/Domain/Interfaces/ICryptographyService.cs
@@ -2,7 +2,6 @@
namespace Beacon.Sdk.Core.Domain.Interfaces
{
- using Infrastructure.Cryptography.Libsodium;
using Utils;
public interface ICryptographyService
diff --git a/Beacon.Sdk/Core/Domain/P2P/ChannelOpening/ChannelOpeningMessageBuilder.cs b/Beacon.Sdk/Core/Domain/P2P/ChannelOpening/ChannelOpeningMessageBuilder.cs
index 5818edd..1a3f0ea 100644
--- a/Beacon.Sdk/Core/Domain/P2P/ChannelOpening/ChannelOpeningMessageBuilder.cs
+++ b/Beacon.Sdk/Core/Domain/P2P/ChannelOpening/ChannelOpeningMessageBuilder.cs
@@ -32,7 +32,7 @@ public ChannelOpeningMessageBuilder(
public void BuildRecipientId(string relayServer, HexString hexPublicKey)
{
byte[] publicKeyByteArray = hexPublicKey.ToByteArray();
- byte[] hash = GenericHash.Hash(publicKeyByteArray, null, publicKeyByteArray.Length)!;
+ byte[] hash = GenericHash.Hash(publicKeyByteArray, publicKeyByteArray.Length)!;
if (!HexString.TryParse(hash, out HexString hexHash))
throw new InvalidOperationException("Can not parse hash");
diff --git a/Beacon.Sdk/Core/Domain/Services/P2PMessageService.cs b/Beacon.Sdk/Core/Domain/Services/P2PMessageService.cs
index 25b89ad..b6a700a 100644
--- a/Beacon.Sdk/Core/Domain/Services/P2PMessageService.cs
+++ b/Beacon.Sdk/Core/Domain/Services/P2PMessageService.cs
@@ -1,7 +1,7 @@
namespace Beacon.Sdk.Core.Domain.Services
{
using System.Text;
- using Infrastructure.Cryptography.Libsodium;
+ using global::Beacon.Sdk.Core.Infrastructure.Cryptography;
using Interfaces;
using Interfaces.Data;
using Netezos.Encoding;
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/BouncyCastle/Ed25519Extensions.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/BouncyCastle/Ed25519Extensions.cs
new file mode 100644
index 0000000..332a49b
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/BouncyCastle/Ed25519Extensions.cs
@@ -0,0 +1,57 @@
+using Org.BouncyCastle.Crypto.Digests;
+using System;
+
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography.BouncyCastle
+{
+ using NaCl;
+
+ public static class Ed25519Extensions
+ {
+ private const int PUBLIC_KEY_BYTES = 32;
+ private const int SCALAR_BYTES = 32;
+ private const int SECRET_KEY_BYTES = 32 + 32;
+
+ /// Converts the ed25519 public key to curve25519 public key.
+ /// Ed25519 public key.
+ /// The curve25519 public key.
+ ///
+ public static byte[] ConvertEd25519PublicKeyToCurve25519PublicKey(byte[] ed25519PublicKey)
+ {
+ if (ed25519PublicKey == null || ed25519PublicKey.Length != PUBLIC_KEY_BYTES)
+ throw new ArgumentOutOfRangeException(nameof(ed25519PublicKey), ed25519PublicKey?.Length ?? 0, $"ed25519PublicKey must be {PUBLIC_KEY_BYTES} bytes in length.");
+
+ var result = new byte[PUBLIC_KEY_BYTES];
+ MontgomeryCurve25519.EdwardsToMontgomery(result, ed25519PublicKey);
+ return result;
+ }
+
+ /// Converts the ed25519 secret key to curve25519 secret key.
+ /// Ed25519 secret key.
+ /// The curve25519 secret key.
+ ///
+ public static byte[] ConvertEd25519SecretKeyToCurve25519SecretKey(byte[] ed25519SecretKey)
+ {
+ // key can be appended with the public key or not (both are allowed)
+ if (ed25519SecretKey == null || (ed25519SecretKey.Length != PUBLIC_KEY_BYTES && ed25519SecretKey.Length != SECRET_KEY_BYTES))
+ throw new ArgumentOutOfRangeException(nameof(ed25519SecretKey), ed25519SecretKey?.Length ?? 0, $"ed25519SecretKey must be either {PUBLIC_KEY_BYTES} or {SECRET_KEY_BYTES} bytes in length.");
+
+ var sha512 = new Sha512Digest();
+
+ byte[] h = new byte[sha512.GetDigestSize()];
+
+ sha512.BlockUpdate(ed25519SecretKey, 0, SCALAR_BYTES);
+ sha512.DoFinal(h, 0);
+
+ PruneScalar(h);
+
+ return h.AsSpan(0, 32).ToArray();
+ }
+
+ private static void PruneScalar(byte[] n)
+ {
+ n[0] &= 0xF8;
+ n[SCALAR_BYTES - 1] &= 0x7F;
+ n[SCALAR_BYTES - 1] |= 0x40;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/CryptographyService.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/CryptographyService.cs
index 7680260..5a70d2b 100644
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/CryptographyService.cs
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/CryptographyService.cs
@@ -4,14 +4,12 @@ namespace Beacon.Sdk.Core.Infrastructure.Cryptography
using System.Linq;
using System.Text;
using Domain.Interfaces;
- using Libsodium;
using Utils;
- using Sodium = Libsodium.Sodium;
public class CryptographyService : ICryptographyService
{
- private static readonly int MacBytes = Sodium.CryptoBoxMacBytes();
- private static readonly int NonceBytes = Sodium.CryptoBoxNonceBytes();
+ private static readonly int MacBytes = 16;
+ private static readonly int NonceBytes = 24;
public SessionKeyPair CreateClientSessionKeyPair(byte[] clientPublicKey, byte[] serverPrivateKey)
{
@@ -20,7 +18,9 @@ public SessionKeyPair CreateClientSessionKeyPair(byte[] clientPublicKey, byte[]
byte[] serverSecretKeyCurve = PublicKeyAuth.ConvertEd25519SecretKeyToCurve25519SecretKey(serverPrivateKey)!;
byte[] clientPublicKeyCurve = PublicKeyAuth.ConvertEd25519PublicKeyToCurve25519PublicKey(clientPublicKey)!;
- return KeyExchange.CreateClientSessionKeyPair(serverPublicKeyCurve, serverSecretKeyCurve,
+ return KeyExchange.CreateClientSessionKeyPair(
+ serverPublicKeyCurve,
+ serverSecretKeyCurve,
clientPublicKeyCurve);
}
@@ -31,25 +31,19 @@ public SessionKeyPair CreateServerSessionKeyPair(byte[] clientPublicKey, byte[]
byte[] serverSecretKeyCurve = PublicKeyAuth.ConvertEd25519SecretKeyToCurve25519SecretKey(serverPrivateKey)!;
byte[] clientPublicKeyCurve = PublicKeyAuth.ConvertEd25519PublicKeyToCurve25519PublicKey(clientPublicKey)!;
- return KeyExchange.CreateServerSessionKeyPair(serverPublicKeyCurve, serverSecretKeyCurve,
+ return KeyExchange.CreateServerSessionKeyPair(
+ serverPublicKeyCurve,
+ serverSecretKeyCurve,
clientPublicKeyCurve);
}
- public byte[] Hash(byte[] input) => GenericHash.Hash(input, null, input.Length);
+ public byte[] Hash(byte[] input) => GenericHash.Hash(input, input.Length);
- public byte[] Hash(byte[] message, int bufferLength)
- {
- var buffer = new byte[bufferLength];
-
- Sodium.Initialize();
- Sodium.CryptoGenericHash(buffer, bufferLength, message, (ulong)message.Length, Array.Empty(), 0);
-
- return buffer;
- }
+ public byte[] Hash(byte[] message, int resultLength) => GenericHash.Hash(message, resultLength);
public KeyPair GenerateEd25519KeyPair(string seed)
{
- byte[] hash = GenericHash.Hash(seed, (byte[]?)null, 32);
+ byte[] hash = GenericHash.Hash(seed, 32);
return PublicKeyAuth.GenerateKeyPair(hash);
}
@@ -67,14 +61,6 @@ public HexString Encrypt(string input, byte[] key)
return hexPayload;
}
- // public static class ArrayExtensions
- // {
- // public byte this[Range input]
- // {
- // get;
- // set;
- // }
- // }
public string Decrypt(HexString hexInput, byte[] key)
{
byte[] bytes = hexInput.ToByteArray();
@@ -136,7 +122,7 @@ public byte[] GenerateLoginDigest()
long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds() * 1000;
var message = $"login:{now / 1000 / (5 * 60)}";
- return GenericHash.Hash(message, (byte[]?)null, 32);
+ return GenericHash.Hash(message, 32);
}
public string GenerateHexSignature(byte[] loginDigest, byte[] secretKey)
@@ -148,7 +134,7 @@ public string GenerateHexSignature(byte[] loginDigest, byte[] secretKey)
public string GenerateHexId(byte[] publicKey)
{
- byte[] hash = GenericHash.Hash(publicKey, null, publicKey.Length);
+ byte[] hash = GenericHash.Hash(publicKey, publicKey.Length);
return ToHexString(hash);
}
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/GenericHash.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/GenericHash.cs
new file mode 100644
index 0000000..7b8e779
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/GenericHash.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Text;
+
+using Org.BouncyCastle.Crypto.Digests;
+
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography
+{
+ public static partial class GenericHash
+ {
+ private const int BYTES_MIN = 0;
+ private const int BYTES_MAX = 64;
+
+ /// Hashes a message, using the BLAKE2b primitive.
+ /// The message to be hashed.
+ /// The size (in bytes) of the desired result.
+ /// Returns a byte array.
+ ///
+ public static byte[] Hash(string message, int resultLength)
+ {
+ return Hash(Encoding.UTF8.GetBytes(message), resultLength);
+ }
+
+ /// Hashes a message, using the BLAKE2b primitive.
+ /// The message to be hashed.
+ /// The size (in bytes) of the desired result.
+ /// Returns a byte array.
+ ///
+ public static byte[] Hash(byte[] message, int resultLength)
+ {
+ if (resultLength > BYTES_MAX || resultLength < BYTES_MIN)
+ throw new ArgumentOutOfRangeException(nameof(resultLength), resultLength, $"bytes must be between {BYTES_MIN} and {BYTES_MAX} bytes in length.");
+
+ var array = new byte[resultLength];
+
+ var blake2bDigest = new Blake2bDigest(resultLength * 8);
+ blake2bDigest.BlockUpdate(message, 0, message.Length);
+ blake2bDigest.DoFinal(array, 0);
+
+ return array;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/KeyExchange.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/KeyExchange.cs
new file mode 100644
index 0000000..c387e4a
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/KeyExchange.cs
@@ -0,0 +1,94 @@
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography
+{
+ using System;
+ using Org.BouncyCastle.Crypto.Digests;
+ using Org.BouncyCastle.Math.EC.Rfc7748;
+
+ public static class KeyExchange
+ {
+ // crypto_kx_PUBLICKEYBYTES
+ private const int PublicKeyBytes = 32;
+
+ // crypto_kx_SECRETKEYBYTES
+ private const int SecretKeyBytes = 32;
+
+ // crypto_kx_SESSIONKEYBYTES
+ private const int SessionKeyBytes = 32;
+
+ private const int ScalarMultCurve25519Bytes = 32;
+
+ public static SessionKeyPair CreateClientSessionKeyPair(
+ byte[] clientPublicKey,
+ byte[] clientSecretKey,
+ byte[] serverPublicKey)
+ {
+ var rx = new byte[SessionKeyBytes];
+ var tx = new byte[SessionKeyBytes];
+
+ if (clientPublicKey is not { Length: PublicKeyBytes })
+ throw new ArgumentException(
+ $"{nameof(clientPublicKey)} size must be {PublicKeyBytes} bytes in length.");
+
+ if (clientSecretKey is not { Length: SecretKeyBytes })
+ throw new ArgumentException(
+ $"{nameof(clientSecretKey)} size must be {SecretKeyBytes} bytes in length.");
+
+ if (serverPublicKey is not { Length: PublicKeyBytes })
+ throw new ArgumentException(
+ $"{nameof(serverPublicKey)} size must be {PublicKeyBytes} bytes in length.");
+
+ var q = new byte[ScalarMultCurve25519Bytes];
+ X25519.ScalarMult(clientSecretKey, 0, serverPublicKey, 0, q, 0);
+
+ var h = new byte[2 * SessionKeyBytes];
+
+ var blake2bDigest = new Blake2bDigest(h.Length * 8);
+ blake2bDigest.BlockUpdate(q, 0, q.Length);
+ blake2bDigest.BlockUpdate(clientPublicKey, 0, PublicKeyBytes);
+ blake2bDigest.BlockUpdate(serverPublicKey, 0, PublicKeyBytes);
+ blake2bDigest.DoFinal(h, 0);
+
+ Buffer.BlockCopy(h, 0, rx, 0, SessionKeyBytes);
+ Buffer.BlockCopy(h, SessionKeyBytes, tx, 0, SessionKeyBytes);
+
+ return new SessionKeyPair(rx, tx);
+ }
+
+ public static SessionKeyPair CreateServerSessionKeyPair(
+ byte[] serverPublicKey,
+ byte[] serverSecretKey,
+ byte[] clientPublicKey)
+ {
+ var rx = new byte[SessionKeyBytes];
+ var tx = new byte[SessionKeyBytes];
+
+ if (serverPublicKey is not { Length: PublicKeyBytes })
+ throw new ArgumentException(
+ $"{nameof(serverPublicKey)} size must be {PublicKeyBytes} bytes in length.");
+
+ if (serverSecretKey is not { Length: SecretKeyBytes })
+ throw new ArgumentException(
+ $"{nameof(serverSecretKey)} size must be {SecretKeyBytes} bytes in length.");
+
+ if (clientPublicKey is not { Length: PublicKeyBytes })
+ throw new ArgumentException(
+ $"{nameof(clientPublicKey)} size must be {PublicKeyBytes} bytes in length.");
+
+ var q = new byte[ScalarMultCurve25519Bytes];
+ X25519.ScalarMult(serverSecretKey, 0, clientPublicKey, 0, q, 0);
+
+ var h = new byte[2 * SessionKeyBytes];
+
+ var blake2bDigest = new Blake2bDigest(h.Length * 8);
+ blake2bDigest.BlockUpdate(q, 0, q.Length);
+ blake2bDigest.BlockUpdate(clientPublicKey, 0, PublicKeyBytes);
+ blake2bDigest.BlockUpdate(serverPublicKey, 0, PublicKeyBytes);
+ blake2bDigest.DoFinal(h, 0);
+
+ Buffer.BlockCopy(h, 0, tx, 0, SessionKeyBytes);
+ Buffer.BlockCopy(h, SessionKeyBytes, rx, 0, SessionKeyBytes);
+
+ return new SessionKeyPair(rx, tx);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/GenericHash.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/GenericHash.cs
deleted file mode 100644
index 1fdeddc..0000000
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/GenericHash.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System;
-using System.Text;
-
-using Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium;
-
-namespace Beacon.Sdk.Core.Infrastructure.Cryptography
-{
- public static partial class GenericHash
- {
- private const int BYTES_MIN = Sodium.crypto_generichash_blake2b_BYTES_MIN;
- private const int BYTES_MAX = Sodium.crypto_generichash_blake2b_BYTES_MAX;
- private const int KEY_BYTES_MIN = Sodium.crypto_generichash_blake2b_KEYBYTES_MIN;
- private const int KEY_BYTES_MAX = Sodium.crypto_generichash_blake2b_KEYBYTES_MAX;
-
- /// Generates a random 64 byte key.
- /// Returns a byte array with 64 random bytes
- public static byte[] GenerateKey()
- {
- return SecureRandom.GetRandomBytes(KEY_BYTES_MAX);
- }
-
- /// Hashes a message, with an optional key, using the BLAKE2b primitive.
- /// The message to be hashed.
- /// The key; may be null, otherwise between 16 and 64 bytes.
- /// The size (in bytes) of the desired result.
- /// Returns a byte array.
- ///
- ///
- public static byte[] Hash(string message, byte[]? key, int bytes)
- {
- return Hash(Encoding.UTF8.GetBytes(message), key, bytes);
- }
-
- /// Hashes a message, with an optional key, using the BLAKE2b primitive.
- /// The message to be hashed.
- /// The key; may be null, otherwise between 16 and 64 bytes.
- /// The size (in bytes) of the desired result.
- /// Returns a byte array.
- ///
- ///
- public static byte[] Hash(byte[] message, byte[]? key, int bytes)
- {
- if (key == null)
- key = Array.Empty();
- else if (key.Length > KEY_BYTES_MAX || key.Length < KEY_BYTES_MIN)
- throw new ArgumentOutOfRangeException(nameof(key), key?.Length ?? 0, $"key must be between {KEY_BYTES_MIN} and {KEY_BYTES_MAX} bytes in length.");
- if (bytes > BYTES_MAX || bytes < BYTES_MIN)
- throw new ArgumentOutOfRangeException(nameof(bytes), bytes, $"bytes must be between {BYTES_MIN} and {BYTES_MAX} bytes in length.");
-
- var buffer = new byte[bytes];
-
- Sodium.Initialize();
- Sodium.CryptoGenericHashBlake2b(buffer, buffer.Length, message, (ulong)message.Length, key, key.Length);
-
- return buffer;
- }
- }
-}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/ILibsodiumImpl.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/ILibsodiumImpl.cs
deleted file mode 100644
index 663778f..0000000
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/ILibsodiumImpl.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using System;
-
-namespace Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium
-{
- interface ILibsodiumImpl
- {
- int SodiumInit();
- int SodiumSetMisuseHandler(Action handler);
- int SodiumLibraryVersionMajor();
- int SodiumLibraryVersionMinor();
- IntPtr SodiumVersionString();
- int CryptoSignEd25519(
- byte[] sm,
- ref ulong smlen_p,
- byte[] m,
- ulong mlen,
- byte[] sk);
- int CryptoSignEd25519Detached(
- byte[] sig,
- ref ulong siglen_p,
- byte[] m,
- ulong mlen,
- byte[] sk);
- int CryptoSignEd25519KeyPair(
- byte[] pk,
- byte[] sk);
- int CryptoSignEd25519Open(
- byte[] m,
- ref ulong mlen_p,
- byte[] sm,
- ulong smlen,
- byte[] pk);
- int CryptoSignEd25519PkToCurve25519(
- byte[] curve25519_pk,
- byte[] ed25519_pk);
- int CryptoSignEd25519SeedKeyPair(
- byte[] pk,
- byte[] sk,
- byte[] seed);
- int CryptoSignEd25519SkToCurve25519(
- byte[] curve25519_sk,
- byte[] ed25519_sk);
- int CryptoSignEd25519SkToPk(
- byte[] pk,
- byte[] sk);
- int CryptoSignEd25519SkToSeed(
- byte[] seed,
- byte[] sk);
- int CryptoSignEd25519VerifyDetached(
- byte[] sig,
- byte[] m,
- ulong mlen,
- byte[] pk);
- int CryptoGenericHashBlake2b(
- byte[] @out,
- int outlen,
- byte[] @in,
- ulong inlen,
- byte[] key,
- int keylen);
- int CryptoSecretBoxEasy(
- byte[] c,
- byte[] m,
- ulong mlen,
- byte[] n,
- byte[] k);
- int CryptoSecretBoxOpenEasy(
- byte[] m,
- byte[] c,
- ulong clen,
- byte[] n,
- byte[] k);
- int CryptoBoxSeal(
- byte[] c,
- byte[] m,
- ulong mlen,
- byte[] pk);
- int CryptoBoxSealOpen(
- byte[] m,
- byte[] c,
- ulong clen,
- byte[] pk,
- byte[] sk);
- int CryptoKxClientSessionKeys(
- byte[] rx,
- byte[] tx,
- byte[] client_pk,
- byte[] client_sk,
- byte[] server_pk);
- int CryptoKxServerSessionKeys(
- byte[] rx,
- byte[] tx,
- byte[] server_pk,
- byte[] server_sk,
- byte[] client_pk);
- int CryptoBoxMacBytes();
- int CryptoBoxNonceBytes();
- int CryptoGenericHash(
- byte[] buffer,
- int bufferLength,
- byte[] message,
- ulong messageLength,
- byte[] key,
- int keyLength);
- }
-}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/InternalLibsodiumImpl.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/InternalLibsodiumImpl.cs
deleted file mode 100644
index 035fbc9..0000000
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/InternalLibsodiumImpl.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium
-{
- internal class InternalLibsodiumImpl : ILibsodiumImpl
- {
- internal const string Library = "__Internal";
-
- public int CryptoBoxMacBytes() =>
- crypto_box_macbytes();
- public int CryptoBoxNonceBytes() =>
- crypto_box_noncebytes();
- public int CryptoBoxSeal(byte[] c, byte[] m, ulong mlen, byte[] pk) =>
- crypto_box_seal(c, m, mlen, pk);
- public int CryptoBoxSealOpen(byte[] m, byte[] c, ulong clen, byte[] pk, byte[] sk) =>
- crypto_box_seal_open(m, c, clen, pk, sk);
- public int CryptoGenericHash(byte[] buffer, int bufferLength, byte[] message, ulong messageLength, byte[] key, int keyLength) =>
- crypto_generichash(buffer, bufferLength, message, messageLength, key, keyLength);
- public int CryptoGenericHashBlake2b(byte[] @out, int outlen, byte[] @in, ulong inlen, byte[] key, int keylen) =>
- crypto_generichash_blake2b(@out, outlen, @in, inlen, key, keylen);
- public int CryptoKxClientSessionKeys(byte[] rx, byte[] tx, byte[] client_pk, byte[] client_sk, byte[] server_pk) =>
- crypto_kx_client_session_keys(rx, tx, client_pk, client_sk, server_pk);
- public int CryptoKxServerSessionKeys(byte[] rx, byte[] tx, byte[] server_pk, byte[] server_sk, byte[] client_pk) =>
- crypto_kx_server_session_keys(rx, tx, server_pk, server_sk, client_pk);
- public int CryptoSecretBoxEasy(byte[] c, byte[] m, ulong mlen, byte[] n, byte[] k) =>
- crypto_secretbox_easy(c, m, mlen, n, k);
- public int CryptoSecretBoxOpenEasy(byte[] m, byte[] c, ulong clen, byte[] n, byte[] k) =>
- crypto_secretbox_open_easy(m, c, clen, n, k);
- public int CryptoSignEd25519(byte[] sm, ref ulong smlen_p, byte[] m, ulong mlen, byte[] sk) =>
- crypto_sign_ed25519(sm, ref smlen_p, m, mlen, sk);
- public int CryptoSignEd25519Detached(byte[] sig, ref ulong siglen_p, byte[] m, ulong mlen, byte[] sk) =>
- crypto_sign_ed25519_detached(sig, ref siglen_p, m, mlen, sk);
- public int CryptoSignEd25519KeyPair(byte[] pk, byte[] sk) =>
- crypto_sign_ed25519_keypair(pk, sk);
- public int CryptoSignEd25519Open(byte[] m, ref ulong mlen_p, byte[] sm, ulong smlen, byte[] pk) =>
- crypto_sign_ed25519_open(m, ref mlen_p, sm, smlen, pk);
- public int CryptoSignEd25519PkToCurve25519(byte[] curve25519_pk, byte[] ed25519_pk) =>
- crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk);
- public int CryptoSignEd25519SeedKeyPair(byte[] pk, byte[] sk, byte[] seed) =>
- crypto_sign_ed25519_seed_keypair(pk, sk, seed);
- public int CryptoSignEd25519SkToCurve25519(byte[] curve25519_sk, byte[] ed25519_sk) =>
- crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_sk);
- public int CryptoSignEd25519SkToPk(byte[] pk, byte[] sk) =>
- crypto_sign_ed25519_sk_to_pk(pk, sk);
- public int CryptoSignEd25519SkToSeed(byte[] seed, byte[] sk) =>
- crypto_sign_ed25519_sk_to_seed(seed, sk);
- public int CryptoSignEd25519VerifyDetached(byte[] sig, byte[] m, ulong mlen, byte[] pk) =>
- crypto_sign_ed25519_verify_detached(sig, m, mlen, pk);
- public int SodiumInit() =>
- sodium_init();
- public int SodiumLibraryVersionMajor() =>
- sodium_library_version_major();
- public int SodiumLibraryVersionMinor() =>
- sodium_library_version_minor();
- public int SodiumSetMisuseHandler(Action handler) =>
- sodium_set_misuse_handler(handler);
- public IntPtr SodiumVersionString() =>
- sodium_version_string();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int sodium_init();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int sodium_set_misuse_handler(Action handler);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int sodium_library_version_major();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int sodium_library_version_minor();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern IntPtr sodium_version_string();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519(
- byte[] sm,
- ref ulong smlen_p,
- byte[] m,
- ulong mlen,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_detached(
- byte[] sig,
- ref ulong siglen_p,
- byte[] m,
- ulong mlen,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_keypair(
- byte[] pk,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_open(
- byte[] m,
- ref ulong mlen_p,
- byte[] sm,
- ulong smlen,
- byte[] pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_pk_to_curve25519(
- byte[] curve25519_pk,
- byte[] ed25519_pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_seed_keypair(
- byte[] pk,
- byte[] sk,
- byte[] seed);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_sk_to_curve25519(
- byte[] curve25519_sk,
- byte[] ed25519_sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_sk_to_pk(
- byte[] pk,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_sk_to_seed(
- byte[] seed,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_verify_detached(
- byte[] sig,
- byte[] m,
- ulong mlen,
- byte[] pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_generichash_blake2b(
- byte[] @out,
- int outlen,
- byte[] @in,
- ulong inlen,
- byte[] key,
- int keylen);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_secretbox_easy(
- byte[] c,
- byte[] m,
- ulong mlen,
- byte[] n,
- byte[] k);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_secretbox_open_easy(
- byte[] m,
- byte[] c,
- ulong clen,
- byte[] n,
- byte[] k);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_box_seal(
- byte[] c,
- byte[] m,
- ulong mlen,
- byte[] pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_box_seal_open(
- byte[] m,
- byte[] c,
- ulong clen,
- byte[] pk,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_kx_client_session_keys(
- byte[] rx,
- byte[] tx,
- byte[] client_pk,
- byte[] client_sk,
- byte[] server_pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_kx_server_session_keys(
- byte[] rx,
- byte[] tx,
- byte[] server_pk,
- byte[] server_sk,
- byte[] client_pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_box_macbytes();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_box_noncebytes();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_generichash(
- byte[] buffer,
- int bufferLength,
- byte[] message,
- ulong messageLength,
- byte[] key,
- int keyLength);
- }
-}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/KeyExchange.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/KeyExchange.cs
deleted file mode 100644
index d000404..0000000
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/KeyExchange.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-namespace Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium
-{
- using System;
-
- public static class KeyExchange
- {
- // crypto_kx_PUBLICKEYBYTES
- private const int PublicKeyBytes = 32;
-
- // crypto_kx_SECRETKEYBYTES
- private const int SecretKeyBytes = 32;
-
- // crypto_kx_SESSIONKEYBYTES
- private const int SessionKeyBytes = 32;
-
- public static SessionKeyPair CreateClientSessionKeyPair(byte[] serverPublicKey, byte[] serverSecretKey,
- byte[] clientPublicKey)
- {
- var rx = new byte[SessionKeyBytes];
- var tx = new byte[SessionKeyBytes];
-
- if (serverPublicKey is not {Length: PublicKeyBytes})
- throw new ArgumentException(
- $"{nameof(serverPublicKey)} size must be {PublicKeyBytes} bytes in length.");
-
- if (serverSecretKey is not {Length: SecretKeyBytes})
- throw new ArgumentException(
- $"{nameof(serverSecretKey)} size must be {SecretKeyBytes} bytes in length.");
-
- if (clientPublicKey is not {Length: PublicKeyBytes})
- throw new ArgumentException(
- $"{nameof(clientPublicKey)} size must be {PublicKeyBytes} bytes in length.");
-
- if (Sodium.CryptoKxClientSessionKeys(
- rx,
- tx,
- serverPublicKey,
- serverSecretKey,
- clientPublicKey) != 0)
- {
- throw new Exception($"{nameof(Sodium)}: {nameof(KeyExchange)} error.");
- }
-
- return new SessionKeyPair(rx, tx);
- }
-
- public static SessionKeyPair CreateServerSessionKeyPair(byte[] serverPublicKey, byte[] serverSecretKey,
- byte[] clientPublicKey)
- {
- var rx = new byte[SessionKeyBytes];
- var tx = new byte[SessionKeyBytes];
-
- if (serverPublicKey is not {Length: PublicKeyBytes})
- throw new ArgumentException(
- $"{nameof(serverPublicKey)} size must be {PublicKeyBytes} bytes in length.");
-
- if (serverSecretKey is not {Length: SecretKeyBytes})
- throw new ArgumentException(
- $"{nameof(serverSecretKey)} size must be {SecretKeyBytes} bytes in length.");
-
- if (clientPublicKey is not {Length: PublicKeyBytes})
- throw new ArgumentException(
- $"{nameof(clientPublicKey)} size must be {PublicKeyBytes} bytes in length.");
-
- if (Sodium.CryptoKxServerSessionKeys(
- rx,
- tx,
- serverPublicKey,
- serverSecretKey,
- clientPublicKey) != 0)
- {
- throw new Exception($"{nameof(Sodium)}: {nameof(KeyExchange)} error.");
- }
-
- return new SessionKeyPair(rx, tx);
- }
- }
-}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/LibsodiumImpl.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/LibsodiumImpl.cs
deleted file mode 100644
index 7d19162..0000000
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/LibsodiumImpl.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium
-{
- internal class LibsodiumImpl : ILibsodiumImpl
- {
- internal const string Library = "libsodium";
-
- public int CryptoBoxMacBytes() =>
- crypto_box_macbytes();
- public int CryptoBoxNonceBytes() =>
- crypto_box_noncebytes();
- public int CryptoBoxSeal(byte[] c, byte[] m, ulong mlen, byte[] pk) =>
- crypto_box_seal(c, m, mlen, pk);
- public int CryptoBoxSealOpen(byte[] m, byte[] c, ulong clen, byte[] pk, byte[] sk) =>
- crypto_box_seal_open(m, c, clen, pk, sk);
- public int CryptoGenericHash(byte[] buffer, int bufferLength, byte[] message, ulong messageLength, byte[] key, int keyLength) =>
- crypto_generichash(buffer, bufferLength, message, messageLength, key, keyLength);
- public int CryptoGenericHashBlake2b(byte[] @out, int outlen, byte[] @in, ulong inlen, byte[] key, int keylen) =>
- crypto_generichash_blake2b(@out, outlen, @in, inlen, key, keylen);
- public int CryptoKxClientSessionKeys(byte[] rx, byte[] tx, byte[] client_pk, byte[] client_sk, byte[] server_pk) =>
- crypto_kx_client_session_keys(rx, tx, client_pk, client_sk, server_pk);
- public int CryptoKxServerSessionKeys(byte[] rx, byte[] tx, byte[] server_pk, byte[] server_sk, byte[] client_pk) =>
- crypto_kx_server_session_keys(rx, tx, server_pk, server_sk, client_pk);
- public int CryptoSecretBoxEasy(byte[] c, byte[] m, ulong mlen, byte[] n, byte[] k) =>
- crypto_secretbox_easy(c, m, mlen, n, k);
- public int CryptoSecretBoxOpenEasy(byte[] m, byte[] c, ulong clen, byte[] n, byte[] k) =>
- crypto_secretbox_open_easy(m, c, clen, n, k);
- public int CryptoSignEd25519(byte[] sm, ref ulong smlen_p, byte[] m, ulong mlen, byte[] sk) =>
- crypto_sign_ed25519(sm, ref smlen_p, m, mlen, sk);
- public int CryptoSignEd25519Detached(byte[] sig, ref ulong siglen_p, byte[] m, ulong mlen, byte[] sk) =>
- crypto_sign_ed25519_detached(sig, ref siglen_p, m, mlen, sk);
- public int CryptoSignEd25519KeyPair(byte[] pk, byte[] sk) =>
- crypto_sign_ed25519_keypair(pk, sk);
- public int CryptoSignEd25519Open(byte[] m, ref ulong mlen_p, byte[] sm, ulong smlen, byte[] pk) =>
- crypto_sign_ed25519_open(m, ref mlen_p, sm, smlen, pk);
- public int CryptoSignEd25519PkToCurve25519(byte[] curve25519_pk, byte[] ed25519_pk) =>
- crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk);
- public int CryptoSignEd25519SeedKeyPair(byte[] pk, byte[] sk, byte[] seed) =>
- crypto_sign_ed25519_seed_keypair(pk, sk, seed);
- public int CryptoSignEd25519SkToCurve25519(byte[] curve25519_sk, byte[] ed25519_sk) =>
- crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_sk);
- public int CryptoSignEd25519SkToPk(byte[] pk, byte[] sk) =>
- crypto_sign_ed25519_sk_to_pk(pk, sk);
- public int CryptoSignEd25519SkToSeed(byte[] seed, byte[] sk) =>
- crypto_sign_ed25519_sk_to_seed(seed, sk);
- public int CryptoSignEd25519VerifyDetached(byte[] sig, byte[] m, ulong mlen, byte[] pk) =>
- crypto_sign_ed25519_verify_detached(sig, m, mlen, pk);
- public int SodiumInit() =>
- sodium_init();
- public int SodiumLibraryVersionMajor() =>
- sodium_library_version_major();
- public int SodiumLibraryVersionMinor() =>
- sodium_library_version_minor();
- public int SodiumSetMisuseHandler(Action handler) =>
- sodium_set_misuse_handler(handler);
- public IntPtr SodiumVersionString() =>
- sodium_version_string();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int sodium_init();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int sodium_set_misuse_handler(Action handler);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int sodium_library_version_major();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int sodium_library_version_minor();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern IntPtr sodium_version_string();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519(
- byte[] sm,
- ref ulong smlen_p,
- byte[] m,
- ulong mlen,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_detached(
- byte[] sig,
- ref ulong siglen_p,
- byte[] m,
- ulong mlen,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_keypair(
- byte[] pk,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_open(
- byte[] m,
- ref ulong mlen_p,
- byte[] sm,
- ulong smlen,
- byte[] pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_pk_to_curve25519(
- byte[] curve25519_pk,
- byte[] ed25519_pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_seed_keypair(
- byte[] pk,
- byte[] sk,
- byte[] seed);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_sk_to_curve25519(
- byte[] curve25519_sk,
- byte[] ed25519_sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_sk_to_pk(
- byte[] pk,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_sk_to_seed(
- byte[] seed,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_sign_ed25519_verify_detached(
- byte[] sig,
- byte[] m,
- ulong mlen,
- byte[] pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_generichash_blake2b(
- byte[] @out,
- int outlen,
- byte[] @in,
- ulong inlen,
- byte[] key,
- int keylen);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_secretbox_easy(
- byte[] c,
- byte[] m,
- ulong mlen,
- byte[] n,
- byte[] k);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_secretbox_open_easy(
- byte[] m,
- byte[] c,
- ulong clen,
- byte[] n,
- byte[] k);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_box_seal(
- byte[] c,
- byte[] m,
- ulong mlen,
- byte[] pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_box_seal_open(
- byte[] m,
- byte[] c,
- ulong clen,
- byte[] pk,
- byte[] sk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_kx_client_session_keys(
- byte[] rx,
- byte[] tx,
- byte[] client_pk,
- byte[] client_sk,
- byte[] server_pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_kx_server_session_keys(
- byte[] rx,
- byte[] tx,
- byte[] server_pk,
- byte[] server_sk,
- byte[] client_pk);
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_box_macbytes();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_box_noncebytes();
-
- [DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int crypto_generichash(
- byte[] buffer,
- int bufferLength,
- byte[] message,
- ulong messageLength,
- byte[] key,
- int keyLength);
- }
-}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/PublicKeyAuth.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/PublicKeyAuth.cs
deleted file mode 100644
index b23c2f1..0000000
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/PublicKeyAuth.cs
+++ /dev/null
@@ -1,120 +0,0 @@
-using System;
-
-using Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium;
-
-namespace Beacon.Sdk.Core.Infrastructure.Cryptography
-{
- /// Public-key signatures
- public static class PublicKeyAuth
- {
- private const int SECRET_KEY_BYTES = Sodium.crypto_sign_ed25519_SECRETKEYBYTES;
- private const int PUBLIC_KEY_BYTES = Sodium.crypto_sign_ed25519_PUBLICKEYBYTES;
- private const int BYTES = Sodium.crypto_sign_ed25519_BYTES;
- private const int SEED_BYTES = Sodium.crypto_sign_ed25519_SEEDBYTES;
-
- public static int SecretKeyBytes { get; } = SECRET_KEY_BYTES;
- public static int PublicKeyBytes { get; } = PUBLIC_KEY_BYTES;
- public static int SignatureBytes { get; } = BYTES;
- public static int SeedBytes { get; } = SEED_BYTES;
-
- /// Creates a new key pair based on the provided seed.
- /// The seed.
- /// A KeyPair.
- ///
- public static KeyPair GenerateKeyPair(byte[] seed)
- {
- if (seed == null || seed.Length != SEED_BYTES)
- throw new ArgumentOutOfRangeException(nameof(seed), seed?.Length ?? 0, $"seed must be {SEED_BYTES} bytes in length.");
-
- var publicKey = new byte[PUBLIC_KEY_BYTES];
- var privateKey = new byte[SECRET_KEY_BYTES];
-
- Sodium.Initialize();
- Sodium.CryptoSignEd25519SeedKeyPair(publicKey, privateKey, seed);
-
- return new KeyPair(publicKey, privateKey);
- }
-
- /// Signs a message with Ed25519.
- /// The message.
- /// The 64 byte private key.
- /// Signed message.
- ///
- public static byte[] Sign(byte[] message, byte[] key)
- {
- if (key == null || key.Length != SECRET_KEY_BYTES)
- throw new ArgumentOutOfRangeException(nameof(key), key?.Length ?? 0, $"key must be {SECRET_KEY_BYTES} bytes in length.");
-
- var buffer = new byte[message.Length + BYTES];
- ulong bufferLength = 0;
-
- Sodium.Initialize();
- Sodium.CryptoSignEd25519(buffer, ref bufferLength, message, (ulong)message.Length, key);
-
- Array.Resize(ref buffer, (int)bufferLength);
- return buffer;
- }
-
- /// Signs a message with Ed25519.
- /// The message.
- /// The 64 byte private key.
- /// The signature.
- ///
- public static byte[] SignDetached(byte[] message, byte[] key)
- {
- if (key == null || key.Length != SECRET_KEY_BYTES)
- throw new ArgumentOutOfRangeException(nameof(key), key?.Length ?? 0, $"key must be {SECRET_KEY_BYTES} bytes in length.");
-
- var signature = new byte[BYTES];
- ulong signatureLength = 0;
-
- Sodium.Initialize();
- Sodium.CryptoSignEd25519Detached(signature, ref signatureLength, message, (ulong)message.Length, key);
-
- return signature;
- }
-
- /// Converts the ed25519 public key to curve25519 public key.
- /// Ed25519 public key.
- /// The curve25519 public key.
- ///
- ///
- public static byte[] ConvertEd25519PublicKeyToCurve25519PublicKey(byte[] ed25519PublicKey)
- {
- if (ed25519PublicKey == null || ed25519PublicKey.Length != PUBLIC_KEY_BYTES)
- throw new ArgumentOutOfRangeException(nameof(ed25519PublicKey), ed25519PublicKey?.Length ?? 0, $"ed25519PublicKey must be {PUBLIC_KEY_BYTES} bytes in length.");
-
- var buffer = new byte[Sodium.crypto_scalarmult_curve25519_BYTES];
-
- Sodium.Initialize();
- var ret = Sodium.CryptoSignEd25519PkToCurve25519(buffer, ed25519PublicKey);
-
- if (ret != 0)
- throw new Exception("Failed to convert public key.");
-
- return buffer;
- }
-
- /// Converts the ed25519 secret key to curve25519 secret key.
- /// Ed25519 secret key.
- /// The curve25519 secret key.
- ///
- ///
- public static byte[] ConvertEd25519SecretKeyToCurve25519SecretKey(byte[] ed25519SecretKey)
- {
- // key can be appended with the public key or not (both are allowed)
- if (ed25519SecretKey == null || (ed25519SecretKey.Length != PUBLIC_KEY_BYTES && ed25519SecretKey.Length != SECRET_KEY_BYTES))
- throw new ArgumentOutOfRangeException(nameof(ed25519SecretKey), ed25519SecretKey?.Length ?? 0, $"ed25519SecretKey must be either {PUBLIC_KEY_BYTES} or {SECRET_KEY_BYTES} bytes in length.");
-
- var buffer = new byte[Sodium.crypto_scalarmult_curve25519_SCALARBYTES];
-
- Sodium.Initialize();
- var ret = Sodium.CryptoSignEd25519SkToCurve25519(buffer, ed25519SecretKey);
-
- if (ret != 0)
- throw new Exception("Failed to convert secret key.");
-
- return buffer;
- }
- }
-}
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/Sodium.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/Sodium.cs
deleted file mode 100644
index bc90dbc..0000000
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/Sodium.cs
+++ /dev/null
@@ -1,247 +0,0 @@
-// ReSharper disable InconsistentNaming
-
-namespace Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium
-{
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Threading;
-
- public enum SodiumLibraryType
- {
- ///
- /// Default dynamic libraries
- ///
- ///
- /// Library name: libsodium.dll for Windows, libsodium.so for Linux/Android, libsodium.dylib for macOS
- ///
- Dynamic,
- ///
- /// Static library (default for iOS)
- ///
- ///
- /// Library name: libsodium.a, actual used name: "__Internal"
- ///
- StaticInternal
- }
-
- public static class Sodium
- {
- internal const int SODIUM_LIBRARY_VERSION_MAJOR = 10;
- internal const int SODIUM_LIBRARY_VERSION_MINOR = 3;
- internal const string SODIUM_VERSION_STRING = "1.0.18";
- internal const int crypto_sign_ed25519_BYTES = 64;
- internal const int crypto_sign_ed25519_PUBLICKEYBYTES = 32;
- internal const int crypto_sign_ed25519_SECRETKEYBYTES = 32 + 32;
- internal const int crypto_sign_ed25519_SEEDBYTES = 32;
- internal const int crypto_scalarmult_curve25519_BYTES = 32;
- internal const int crypto_scalarmult_curve25519_SCALARBYTES = 32;
- internal const int crypto_generichash_blake2b_BYTES_MAX = 64;
- internal const int crypto_generichash_blake2b_BYTES_MIN = 16;
- internal const int crypto_generichash_blake2b_KEYBYTES_MAX = 64;
- internal const int crypto_generichash_blake2b_KEYBYTES_MIN = 16;
- internal const int crypto_secretbox_xsalsa20poly1305_KEYBYTES = 32;
- internal const int crypto_secretbox_xsalsa20poly1305_MACBYTES = 16;
- internal const int crypto_secretbox_xsalsa20poly1305_NONCEBYTES = 24;
- internal const int crypto_box_curve25519xsalsa20poly1305_MACBYTES = 16;
- internal const int crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32;
- internal const int crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32;
-
- static ILibsodiumImpl _impl = new LibsodiumImpl();
-
- public static void SetLibraryType(SodiumLibraryType type)
- {
- _impl = type switch
- {
- SodiumLibraryType.Dynamic => new LibsodiumImpl(),
- SodiumLibraryType.StaticInternal => new InternalLibsodiumImpl(),
- _ => new LibsodiumImpl(),
- };
- }
-
- private static readonly Action s_misuseHandler = new(InternalError);
-
- private static int s_initialized;
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void Initialize()
- {
- if (s_initialized == 0)
- {
- InitializeCore();
- }
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void InitializeCore()
- {
- try
- {
- if (SodiumLibraryVersionMajor() != SODIUM_LIBRARY_VERSION_MAJOR ||
- SodiumLibraryVersionMinor() != SODIUM_LIBRARY_VERSION_MINOR)
- {
- string? version = Marshal.PtrToStringAnsi(SodiumVersionString());
- throw (version != null && version != SODIUM_VERSION_STRING)
- ? new NotSupportedException($"An error occurred while initializing cryptographic primitives. (Expected libsodium {SODIUM_VERSION_STRING} but found {version}.)")
- : new NotSupportedException("An error occurred while initializing cryptographic primitives.");
- }
-
- if (SodiumSetMisuseHandler(s_misuseHandler) != 0)
- {
- throw new NotSupportedException("An error occurred while initializing cryptographic primitives.");
- }
-
- // sodium_init() returns 0 on success, -1 on failure, and 1 if the library had already been initialized.
- if (SodiumInit() < 0)
- {
- throw new NotSupportedException("An error occurred while initializing cryptographic primitives.");
- }
- }
- catch (DllNotFoundException e)
- {
- throw new PlatformNotSupportedException("Could not initialize platform-specific components. libsodium-core may not be supported on this platform. See https://github.com/ektrah/libsodium-core/blob/master/INSTALL.md for more information.", e);
- }
- catch (BadImageFormatException e)
- {
- throw new PlatformNotSupportedException("Could not initialize platform-specific components. libsodium-core may not be supported on this platform. See https://github.com/ektrah/libsodium-core/blob/master/INSTALL.md for more information.", e);
- }
-
- Interlocked.Exchange(ref s_initialized, 1);
- }
-
- private static void InternalError()
- {
- throw new NotSupportedException("An internal error occurred.");
- }
-
- internal static int SodiumInit() =>
- _impl.SodiumInit();
-
- internal static int SodiumSetMisuseHandler(Action handler) =>
- _impl.SodiumSetMisuseHandler(handler);
-
- internal static int SodiumLibraryVersionMajor() =>
- _impl.SodiumLibraryVersionMajor();
-
- internal static int SodiumLibraryVersionMinor() =>
- _impl.SodiumLibraryVersionMinor();
-
- internal static IntPtr SodiumVersionString() =>
- _impl.SodiumVersionString();
-
- internal static int CryptoSignEd25519(
- byte[] sm,
- ref ulong smlen_p,
- byte[] m,
- ulong mlen,
- byte[] sk) => _impl.CryptoSignEd25519(sm, ref smlen_p, m, mlen, sk);
-
- internal static int CryptoSignEd25519Detached(
- byte[] sig,
- ref ulong siglen_p,
- byte[] m,
- ulong mlen,
- byte[] sk) => _impl.CryptoSignEd25519Detached(sig, ref siglen_p, m, mlen, sk);
-
- internal static int CryptoSignEd25519KeyPair(
- byte[] pk,
- byte[] sk) => _impl.CryptoSignEd25519KeyPair(pk, sk);
-
- internal static int CryptoSignEd25519Open(
- byte[] m,
- ref ulong mlen_p,
- byte[] sm,
- ulong smlen,
- byte[] pk) => _impl.CryptoSignEd25519Open(m, ref mlen_p, sm, smlen, pk);
-
- internal static int CryptoSignEd25519PkToCurve25519(
- byte[] curve25519_pk,
- byte[] ed25519_pk) => _impl.CryptoSignEd25519PkToCurve25519(curve25519_pk, ed25519_pk);
-
- internal static int CryptoSignEd25519SeedKeyPair(
- byte[] pk,
- byte[] sk,
- byte[] seed) => _impl.CryptoSignEd25519SeedKeyPair(pk, sk, seed);
-
- internal static int CryptoSignEd25519SkToCurve25519(
- byte[] curve25519_sk,
- byte[] ed25519_sk) => _impl.CryptoSignEd25519SkToCurve25519(curve25519_sk, ed25519_sk);
-
- internal static int CryptoSignEd25519SkToPk(
- byte[] pk,
- byte[] sk) => _impl.CryptoSignEd25519SkToPk(pk, sk);
-
- internal static int CryptoSignEd25519SkToSeed(
- byte[] seed,
- byte[] sk) => _impl.CryptoSignEd25519SkToSeed(seed, sk);
-
- internal static int CryptoSignEd25519VerifyDetached(
- byte[] sig,
- byte[] m,
- ulong mlen,
- byte[] pk) => _impl.CryptoSignEd25519VerifyDetached(sig, m, mlen, pk);
-
- internal static int CryptoGenericHashBlake2b(
- byte[] @out,
- int outlen,
- byte[] @in,
- ulong inlen,
- byte[] key,
- int keylen) => _impl.CryptoGenericHashBlake2b(@out, outlen, @in, inlen, key, keylen);
-
- internal static int CryptoSecretBoxEasy(
- byte[] c,
- byte[] m,
- ulong mlen,
- byte[] n,
- byte[] k) => _impl.CryptoSecretBoxEasy(c, m, mlen, n, k);
-
- internal static int CryptoSecretBoxOpenEasy(
- byte[] m,
- byte[] c,
- ulong clen,
- byte[] n,
- byte[] k) => _impl.CryptoSecretBoxOpenEasy(m, c, clen, n, k);
-
- internal static int CryptoBoxSeal(
- byte[] c,
- byte[] m,
- ulong mlen,
- byte[] pk) => _impl.CryptoBoxSeal(c, m, mlen, pk);
-
- internal static int CryptoBoxSealOpen(
- byte[] m,
- byte[] c,
- ulong clen,
- byte[] pk,
- byte[] sk) => _impl.CryptoBoxSealOpen(m, c, clen, pk, sk);
-
- internal static int CryptoKxClientSessionKeys(
- byte[] rx,
- byte[] tx,
- byte[] client_pk,
- byte[] client_sk,
- byte[] server_pk) => _impl.CryptoKxClientSessionKeys(rx, tx, client_pk, client_sk, server_pk);
-
- internal static int CryptoKxServerSessionKeys(
- byte[] rx,
- byte[] tx,
- byte[] server_pk,
- byte[] server_sk,
- byte[] client_pk) => _impl.CryptoKxServerSessionKeys(rx, tx, server_pk, server_sk, client_pk);
-
- internal static int CryptoBoxMacBytes() =>
- _impl.CryptoBoxMacBytes();
-
- internal static int CryptoBoxNonceBytes() =>
- _impl.CryptoBoxNonceBytes();
-
- internal static int CryptoGenericHash(
- byte[] buffer,
- int bufferLength,
- byte[] message,
- ulong messageLength,
- byte[] key,
- int keyLength) => _impl.CryptoGenericHash(buffer, bufferLength, message, messageLength, key, keyLength);
- }
-}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/FieldElement.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/FieldElement.cs
new file mode 100644
index 0000000..6004cdc
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/FieldElement.cs
@@ -0,0 +1,38 @@
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography.NaCl.Internal.Ed25519Ref10
+{
+ using System;
+
+ internal struct FieldElement
+ {
+ internal int x0;
+ internal int x1;
+ internal int x2;
+ internal int x3;
+ internal int x4;
+ internal int x5;
+ internal int x6;
+ internal int x7;
+ internal int x8;
+ internal int x9;
+
+ //public static readonly FieldElement Zero = new FieldElement();
+ //public static readonly FieldElement One = new FieldElement() { x0 = 1 };
+
+ internal FieldElement(params int[] elements)
+ {
+ if (elements.Length != 10)
+ throw new InvalidOperationException("An assertion in Chaos.Crypto failed: elements.Length != 10");
+
+ x0 = elements[0];
+ x1 = elements[1];
+ x2 = elements[2];
+ x3 = elements[3];
+ x4 = elements[4];
+ x5 = elements[5];
+ x6 = elements[6];
+ x7 = elements[7];
+ x8 = elements[8];
+ x9 = elements[9];
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_1.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_1.cs
new file mode 100644
index 0000000..0c5818e
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_1.cs
@@ -0,0 +1,11 @@
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography.NaCl.Internal.Ed25519Ref10
+{
+ internal static partial class FieldOperations
+ {
+ public static void fe_1(out FieldElement h)
+ {
+ h = default(FieldElement);
+ h.x0 = 1;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_add.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_add.cs
new file mode 100644
index 0000000..2a57229
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_add.cs
@@ -0,0 +1,63 @@
+using System;
+
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography.NaCl.Internal.Ed25519Ref10
+{
+ internal static partial class FieldOperations
+ {
+ /*
+ h = f + g
+ Can overlap h with f or g.
+
+ Preconditions:
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+
+ Postconditions:
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ */
+ //void fe_add(fe h,const fe f,const fe g)
+ internal static void fe_add(out FieldElement h, ref FieldElement f, ref FieldElement g)
+ {
+ Int32 f0 = f.x0;
+ Int32 f1 = f.x1;
+ Int32 f2 = f.x2;
+ Int32 f3 = f.x3;
+ Int32 f4 = f.x4;
+ Int32 f5 = f.x5;
+ Int32 f6 = f.x6;
+ Int32 f7 = f.x7;
+ Int32 f8 = f.x8;
+ Int32 f9 = f.x9;
+ Int32 g0 = g.x0;
+ Int32 g1 = g.x1;
+ Int32 g2 = g.x2;
+ Int32 g3 = g.x3;
+ Int32 g4 = g.x4;
+ Int32 g5 = g.x5;
+ Int32 g6 = g.x6;
+ Int32 g7 = g.x7;
+ Int32 g8 = g.x8;
+ Int32 g9 = g.x9;
+ Int32 h0 = f0 + g0;
+ Int32 h1 = f1 + g1;
+ Int32 h2 = f2 + g2;
+ Int32 h3 = f3 + g3;
+ Int32 h4 = f4 + g4;
+ Int32 h5 = f5 + g5;
+ Int32 h6 = f6 + g6;
+ Int32 h7 = f7 + g7;
+ Int32 h8 = f8 + g8;
+ Int32 h9 = f9 + g9;
+ h.x0 = h0;
+ h.x1 = h1;
+ h.x2 = h2;
+ h.x3 = h3;
+ h.x4 = h4;
+ h.x5 = h5;
+ h.x6 = h6;
+ h.x7 = h7;
+ h.x8 = h8;
+ h.x9 = h9;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_frombytes.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_frombytes.cs
new file mode 100644
index 0000000..51f55d7
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_frombytes.cs
@@ -0,0 +1,162 @@
+using System;
+
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography.NaCl.Internal.Ed25519Ref10
+{
+ internal static partial class FieldOperations
+ {
+ private static Int64 load_3(byte[] data, int offset)
+ {
+ uint result;
+ result = (uint)data[offset + 0];
+ result |= (uint)data[offset + 1] << 8;
+ result |= (uint)data[offset + 2] << 16;
+ return (Int64)(UInt64)result;
+ }
+
+ private static Int64 load_4(byte[] data, int offset)
+ {
+ uint result;
+ result = (uint)data[offset + 0];
+ result |= (uint)data[offset + 1] << 8;
+ result |= (uint)data[offset + 2] << 16;
+ result |= (uint)data[offset + 3] << 24;
+ return (Int64)(UInt64)result;
+ }
+
+ // Ignores top bit of h.
+ internal static void fe_frombytes(out FieldElement h, byte[] data, int offset)
+ {
+ Int64 h0 = load_4(data, offset);
+ Int64 h1 = load_3(data, offset + 4) << 6;
+ Int64 h2 = load_3(data, offset + 7) << 5;
+ Int64 h3 = load_3(data, offset + 10) << 3;
+ Int64 h4 = load_3(data, offset + 13) << 2;
+ Int64 h5 = load_4(data, offset + 16);
+ Int64 h6 = load_3(data, offset + 20) << 7;
+ Int64 h7 = load_3(data, offset + 23) << 5;
+ Int64 h8 = load_3(data, offset + 26) << 4;
+ Int64 h9 = (load_3(data, offset + 29) & 8388607) << 2;
+ Int64 carry0;
+ Int64 carry1;
+ Int64 carry2;
+ Int64 carry3;
+ Int64 carry4;
+ Int64 carry5;
+ Int64 carry6;
+ Int64 carry7;
+ Int64 carry8;
+ Int64 carry9;
+
+ carry9 = (h9 + (Int64)(1 << 24)) >> 25;
+ h0 += carry9 * 19;
+ h9 -= carry9 << 25;
+ carry1 = (h1 + (Int64)(1 << 24)) >> 25;
+ h2 += carry1;
+ h1 -= carry1 << 25;
+ carry3 = (h3 + (Int64)(1 << 24)) >> 25;
+ h4 += carry3;
+ h3 -= carry3 << 25;
+ carry5 = (h5 + (Int64)(1 << 24)) >> 25;
+ h6 += carry5;
+ h5 -= carry5 << 25;
+ carry7 = (h7 + (Int64)(1 << 24)) >> 25;
+ h8 += carry7;
+ h7 -= carry7 << 25;
+
+ carry0 = (h0 + (Int64)(1 << 25)) >> 26;
+ h1 += carry0;
+ h0 -= carry0 << 26;
+ carry2 = (h2 + (Int64)(1 << 25)) >> 26;
+ h3 += carry2;
+ h2 -= carry2 << 26;
+ carry4 = (h4 + (Int64)(1 << 25)) >> 26;
+ h5 += carry4;
+ h4 -= carry4 << 26;
+ carry6 = (h6 + (Int64)(1 << 25)) >> 26;
+ h7 += carry6;
+ h6 -= carry6 << 26;
+ carry8 = (h8 + (Int64)(1 << 25)) >> 26;
+ h9 += carry8;
+ h8 -= carry8 << 26;
+
+ h.x0 = (int)h0;
+ h.x1 = (int)h1;
+ h.x2 = (int)h2;
+ h.x3 = (int)h3;
+ h.x4 = (int)h4;
+ h.x5 = (int)h5;
+ h.x6 = (int)h6;
+ h.x7 = (int)h7;
+ h.x8 = (int)h8;
+ h.x9 = (int)h9;
+ }
+
+ // does NOT ignore top bit
+ internal static void fe_frombytes2(out FieldElement h, byte[] data, int offset)
+ {
+ Int64 h0 = load_4(data, offset);
+ Int64 h1 = load_3(data, offset + 4) << 6;
+ Int64 h2 = load_3(data, offset + 7) << 5;
+ Int64 h3 = load_3(data, offset + 10) << 3;
+ Int64 h4 = load_3(data, offset + 13) << 2;
+ Int64 h5 = load_4(data, offset + 16);
+ Int64 h6 = load_3(data, offset + 20) << 7;
+ Int64 h7 = load_3(data, offset + 23) << 5;
+ Int64 h8 = load_3(data, offset + 26) << 4;
+ Int64 h9 = load_3(data, offset + 29) << 2;
+ Int64 carry0;
+ Int64 carry1;
+ Int64 carry2;
+ Int64 carry3;
+ Int64 carry4;
+ Int64 carry5;
+ Int64 carry6;
+ Int64 carry7;
+ Int64 carry8;
+ Int64 carry9;
+
+ carry9 = (h9 + (Int64)(1 << 24)) >> 25;
+ h0 += carry9 * 19;
+ h9 -= carry9 << 25;
+ carry1 = (h1 + (Int64)(1 << 24)) >> 25;
+ h2 += carry1;
+ h1 -= carry1 << 25;
+ carry3 = (h3 + (Int64)(1 << 24)) >> 25;
+ h4 += carry3;
+ h3 -= carry3 << 25;
+ carry5 = (h5 + (Int64)(1 << 24)) >> 25;
+ h6 += carry5;
+ h5 -= carry5 << 25;
+ carry7 = (h7 + (Int64)(1 << 24)) >> 25;
+ h8 += carry7;
+ h7 -= carry7 << 25;
+
+ carry0 = (h0 + (Int64)(1 << 25)) >> 26;
+ h1 += carry0;
+ h0 -= carry0 << 26;
+ carry2 = (h2 + (Int64)(1 << 25)) >> 26;
+ h3 += carry2;
+ h2 -= carry2 << 26;
+ carry4 = (h4 + (Int64)(1 << 25)) >> 26;
+ h5 += carry4;
+ h4 -= carry4 << 26;
+ carry6 = (h6 + (Int64)(1 << 25)) >> 26;
+ h7 += carry6;
+ h6 -= carry6 << 26;
+ carry8 = (h8 + (Int64)(1 << 25)) >> 26;
+ h9 += carry8;
+ h8 -= carry8 << 26;
+
+ h.x0 = (int)h0;
+ h.x1 = (int)h1;
+ h.x2 = (int)h2;
+ h.x3 = (int)h3;
+ h.x4 = (int)h4;
+ h.x5 = (int)h5;
+ h.x6 = (int)h6;
+ h.x7 = (int)h7;
+ h.x8 = (int)h8;
+ h.x9 = (int)h9;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_invert.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_invert.cs
new file mode 100644
index 0000000..ff37e17
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_invert.cs
@@ -0,0 +1,179 @@
+using System;
+
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography.NaCl.Internal.Ed25519Ref10
+{
+ internal static partial class FieldOperations
+ {
+ internal static void fe_invert(out FieldElement result, ref FieldElement z)
+ {
+ FieldElement t0;
+ FieldElement t1;
+ FieldElement t2;
+ FieldElement t3;
+ int i;
+
+ /* qhasm: fe z1 */
+
+ /* qhasm: fe z2 */
+
+ /* qhasm: fe z8 */
+
+ /* qhasm: fe z9 */
+
+ /* qhasm: fe z11 */
+
+ /* qhasm: fe z22 */
+
+ /* qhasm: fe z_5_0 */
+
+ /* qhasm: fe z_10_5 */
+
+ /* qhasm: fe z_10_0 */
+
+ /* qhasm: fe z_20_10 */
+
+ /* qhasm: fe z_20_0 */
+
+ /* qhasm: fe z_40_20 */
+
+ /* qhasm: fe z_40_0 */
+
+ /* qhasm: fe z_50_10 */
+
+ /* qhasm: fe z_50_0 */
+
+ /* qhasm: fe z_100_50 */
+
+ /* qhasm: fe z_100_0 */
+
+ /* qhasm: fe z_200_100 */
+
+ /* qhasm: fe z_200_0 */
+
+ /* qhasm: fe z_250_50 */
+
+ /* qhasm: fe z_250_0 */
+
+ /* qhasm: fe z_255_5 */
+
+ /* qhasm: fe z_255_21 */
+
+ /* qhasm: enter pow225521 */
+
+ /* qhasm: z2 = z1^2^1 */
+ /* asm 1: fe_sq(>z2=fe#1,z2=fe#1,>z2=fe#1); */
+ /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */
+ fe_sq(out t0, ref z); //for (i = 1; i < 1; ++i) fe_sq(out t0, ref t0);
+
+ /* qhasm: z8 = z2^2^2 */
+ /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */
+ /* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */
+ fe_sq(out t1, ref t0); for (i = 1; i < 2; ++i) fe_sq(out t1, ref t1);
+
+ /* qhasm: z9 = z1*z8 */
+ /* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#3,z22=fe#3,>z22=fe#3); */
+ /* asm 2: fe_sq(>z22=t2,z22=t2,>z22=t2); */
+ fe_sq(out t2, ref t0); //for (i = 1; i < 1; ++i) fe_sq(out t2, ref t2);
+
+ /* qhasm: z_5_0 = z9*z22 */
+ /* asm 1: fe_mul(>z_5_0=fe#2,z_5_0=t1,z_10_5=fe#3,z_10_5=fe#3,>z_10_5=fe#3); */
+ /* asm 2: fe_sq(>z_10_5=t2,z_10_5=t2,>z_10_5=t2); */
+ fe_sq(out t2, ref t1); for (i = 1; i < 5; ++i) fe_sq(out t2, ref t2);
+
+ /* qhasm: z_10_0 = z_10_5*z_5_0 */
+ /* asm 1: fe_mul(>z_10_0=fe#2,z_10_0=t1,z_20_10=fe#3,z_20_10=fe#3,>z_20_10=fe#3); */
+ /* asm 2: fe_sq(>z_20_10=t2,z_20_10=t2,>z_20_10=t2); */
+ fe_sq(out t2, ref t1); for (i = 1; i < 10; ++i) fe_sq(out t2, ref t2);
+
+ /* qhasm: z_20_0 = z_20_10*z_10_0 */
+ /* asm 1: fe_mul(>z_20_0=fe#3,z_20_0=t2,z_40_20=fe#4,z_40_20=fe#4,>z_40_20=fe#4); */
+ /* asm 2: fe_sq(>z_40_20=t3,z_40_20=t3,>z_40_20=t3); */
+ fe_sq(out t3, ref t2); for (i = 1; i < 20; ++i) fe_sq(out t3, ref t3);
+
+ /* qhasm: z_40_0 = z_40_20*z_20_0 */
+ /* asm 1: fe_mul(>z_40_0=fe#3,z_40_0=t2,z_50_10=fe#3,z_50_10=fe#3,>z_50_10=fe#3); */
+ /* asm 2: fe_sq(>z_50_10=t2,z_50_10=t2,>z_50_10=t2); */
+ fe_sq(out t2, ref t2); for (i = 1; i < 10; ++i) fe_sq(out t2, ref t2);
+
+ /* qhasm: z_50_0 = z_50_10*z_10_0 */
+ /* asm 1: fe_mul(>z_50_0=fe#2,z_50_0=t1,z_100_50=fe#3,z_100_50=fe#3,>z_100_50=fe#3); */
+ /* asm 2: fe_sq(>z_100_50=t2,z_100_50=t2,>z_100_50=t2); */
+ fe_sq(out t2, ref t1); for (i = 1; i < 50; ++i) fe_sq(out t2, ref t2);
+
+ /* qhasm: z_100_0 = z_100_50*z_50_0 */
+ /* asm 1: fe_mul(>z_100_0=fe#3,z_100_0=t2,z_200_100=fe#4,z_200_100=fe#4,>z_200_100=fe#4); */
+ /* asm 2: fe_sq(>z_200_100=t3,z_200_100=t3,>z_200_100=t3); */
+ fe_sq(out t3, ref t2); for (i = 1; i < 100; ++i) fe_sq(out t3, ref t3);
+
+ /* qhasm: z_200_0 = z_200_100*z_100_0 */
+ /* asm 1: fe_mul(>z_200_0=fe#3,z_200_0=t2,z_250_50=fe#3,z_250_50=fe#3,>z_250_50=fe#3); */
+ /* asm 2: fe_sq(>z_250_50=t2,z_250_50=t2,>z_250_50=t2); */
+ fe_sq(out t2, ref t2); for (i = 1; i < 50; ++i) fe_sq(out t2, ref t2);
+
+ /* qhasm: z_250_0 = z_250_50*z_50_0 */
+ /* asm 1: fe_mul(>z_250_0=fe#2,z_250_0=t1,z_255_5=fe#2,z_255_5=fe#2,>z_255_5=fe#2); */
+ /* asm 2: fe_sq(>z_255_5=t1,z_255_5=t1,>z_255_5=t1); */
+ fe_sq(out t1, ref t1); for (i = 1; i < 5; ++i) fe_sq(out t1, ref t1);
+
+ /* qhasm: z_255_21 = z_255_5*z11 */
+ /* asm 1: fe_mul(>z_255_21=fe#12,z_255_21=out,> 26; h1 += carry0; h0 -= carry0 << 26;
+ carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+ /* |h0| <= 2^25 */
+ /* |h4| <= 2^25 */
+ /* |h1| <= 1.71*2^59 */
+ /* |h5| <= 1.71*2^59 */
+
+ carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
+ carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+ /* |h1| <= 2^24; from now on fits into int32 */
+ /* |h5| <= 2^24; from now on fits into int32 */
+ /* |h2| <= 1.41*2^60 */
+ /* |h6| <= 1.41*2^60 */
+
+ carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
+ carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+ /* |h2| <= 2^25; from now on fits into int32 unchanged */
+ /* |h6| <= 2^25; from now on fits into int32 unchanged */
+ /* |h3| <= 1.71*2^59 */
+ /* |h7| <= 1.71*2^59 */
+
+ carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
+ carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+ /* |h3| <= 2^24; from now on fits into int32 unchanged */
+ /* |h7| <= 2^24; from now on fits into int32 unchanged */
+ /* |h4| <= 1.72*2^34 */
+ /* |h8| <= 1.41*2^60 */
+
+ carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+ carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+ /* |h4| <= 2^25; from now on fits into int32 unchanged */
+ /* |h8| <= 2^25; from now on fits into int32 unchanged */
+ /* |h5| <= 1.01*2^24 */
+ /* |h9| <= 1.71*2^59 */
+
+ carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+ /* |h9| <= 2^24; from now on fits into int32 unchanged */
+ /* |h0| <= 1.1*2^39 */
+
+ carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+ /* |h0| <= 2^25; from now on fits into int32 unchanged */
+ /* |h1| <= 1.01*2^24 */
+
+ h.x0 = (Int32)h0;
+ h.x1 = (Int32)h1;
+ h.x2 = (Int32)h2;
+ h.x3 = (Int32)h3;
+ h.x4 = (Int32)h4;
+ h.x5 = (Int32)h5;
+ h.x6 = (Int32)h6;
+ h.x7 = (Int32)h7;
+ h.x8 = (Int32)h8;
+ h.x9 = (Int32)h9;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_sq.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_sq.cs
new file mode 100644
index 0000000..6557b73
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_sq.cs
@@ -0,0 +1,153 @@
+using System;
+
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography.NaCl.Internal.Ed25519Ref10
+{
+ internal static partial class FieldOperations
+ {
+ /*
+ h = f * f
+ Can overlap h with f.
+
+ Preconditions:
+ |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+
+ Postconditions:
+ |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+ */
+
+ /*
+ See fe_mul.c for discussion of implementation strategy.
+ */
+ internal static void fe_sq(out FieldElement h, ref FieldElement f)
+ {
+ Int32 f0 = f.x0;
+ Int32 f1 = f.x1;
+ Int32 f2 = f.x2;
+ Int32 f3 = f.x3;
+ Int32 f4 = f.x4;
+ Int32 f5 = f.x5;
+ Int32 f6 = f.x6;
+ Int32 f7 = f.x7;
+ Int32 f8 = f.x8;
+ Int32 f9 = f.x9;
+ Int32 f0_2 = 2 * f0;
+ Int32 f1_2 = 2 * f1;
+ Int32 f2_2 = 2 * f2;
+ Int32 f3_2 = 2 * f3;
+ Int32 f4_2 = 2 * f4;
+ Int32 f5_2 = 2 * f5;
+ Int32 f6_2 = 2 * f6;
+ Int32 f7_2 = 2 * f7;
+ Int32 f5_38 = 38 * f5; /* 1.959375*2^30 */
+ Int32 f6_19 = 19 * f6; /* 1.959375*2^30 */
+ Int32 f7_38 = 38 * f7; /* 1.959375*2^30 */
+ Int32 f8_19 = 19 * f8; /* 1.959375*2^30 */
+ Int32 f9_38 = 38 * f9; /* 1.959375*2^30 */
+ Int64 f0f0 = f0 * (Int64)f0;
+ Int64 f0f1_2 = f0_2 * (Int64)f1;
+ Int64 f0f2_2 = f0_2 * (Int64)f2;
+ Int64 f0f3_2 = f0_2 * (Int64)f3;
+ Int64 f0f4_2 = f0_2 * (Int64)f4;
+ Int64 f0f5_2 = f0_2 * (Int64)f5;
+ Int64 f0f6_2 = f0_2 * (Int64)f6;
+ Int64 f0f7_2 = f0_2 * (Int64)f7;
+ Int64 f0f8_2 = f0_2 * (Int64)f8;
+ Int64 f0f9_2 = f0_2 * (Int64)f9;
+ Int64 f1f1_2 = f1_2 * (Int64)f1;
+ Int64 f1f2_2 = f1_2 * (Int64)f2;
+ Int64 f1f3_4 = f1_2 * (Int64)f3_2;
+ Int64 f1f4_2 = f1_2 * (Int64)f4;
+ Int64 f1f5_4 = f1_2 * (Int64)f5_2;
+ Int64 f1f6_2 = f1_2 * (Int64)f6;
+ Int64 f1f7_4 = f1_2 * (Int64)f7_2;
+ Int64 f1f8_2 = f1_2 * (Int64)f8;
+ Int64 f1f9_76 = f1_2 * (Int64)f9_38;
+ Int64 f2f2 = f2 * (Int64)f2;
+ Int64 f2f3_2 = f2_2 * (Int64)f3;
+ Int64 f2f4_2 = f2_2 * (Int64)f4;
+ Int64 f2f5_2 = f2_2 * (Int64)f5;
+ Int64 f2f6_2 = f2_2 * (Int64)f6;
+ Int64 f2f7_2 = f2_2 * (Int64)f7;
+ Int64 f2f8_38 = f2_2 * (Int64)f8_19;
+ Int64 f2f9_38 = f2 * (Int64)f9_38;
+ Int64 f3f3_2 = f3_2 * (Int64)f3;
+ Int64 f3f4_2 = f3_2 * (Int64)f4;
+ Int64 f3f5_4 = f3_2 * (Int64)f5_2;
+ Int64 f3f6_2 = f3_2 * (Int64)f6;
+ Int64 f3f7_76 = f3_2 * (Int64)f7_38;
+ Int64 f3f8_38 = f3_2 * (Int64)f8_19;
+ Int64 f3f9_76 = f3_2 * (Int64)f9_38;
+ Int64 f4f4 = f4 * (Int64)f4;
+ Int64 f4f5_2 = f4_2 * (Int64)f5;
+ Int64 f4f6_38 = f4_2 * (Int64)f6_19;
+ Int64 f4f7_38 = f4 * (Int64)f7_38;
+ Int64 f4f8_38 = f4_2 * (Int64)f8_19;
+ Int64 f4f9_38 = f4 * (Int64)f9_38;
+ Int64 f5f5_38 = f5 * (Int64)f5_38;
+ Int64 f5f6_38 = f5_2 * (Int64)f6_19;
+ Int64 f5f7_76 = f5_2 * (Int64)f7_38;
+ Int64 f5f8_38 = f5_2 * (Int64)f8_19;
+ Int64 f5f9_76 = f5_2 * (Int64)f9_38;
+ Int64 f6f6_19 = f6 * (Int64)f6_19;
+ Int64 f6f7_38 = f6 * (Int64)f7_38;
+ Int64 f6f8_38 = f6_2 * (Int64)f8_19;
+ Int64 f6f9_38 = f6 * (Int64)f9_38;
+ Int64 f7f7_38 = f7 * (Int64)f7_38;
+ Int64 f7f8_38 = f7_2 * (Int64)f8_19;
+ Int64 f7f9_76 = f7_2 * (Int64)f9_38;
+ Int64 f8f8_19 = f8 * (Int64)f8_19;
+ Int64 f8f9_38 = f8 * (Int64)f9_38;
+ Int64 f9f9_38 = f9 * (Int64)f9_38;
+ Int64 h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
+ Int64 h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
+ Int64 h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
+ Int64 h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
+ Int64 h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
+ Int64 h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
+ Int64 h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
+ Int64 h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
+ Int64 h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
+ Int64 h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
+ Int64 carry0;
+ Int64 carry1;
+ Int64 carry2;
+ Int64 carry3;
+ Int64 carry4;
+ Int64 carry5;
+ Int64 carry6;
+ Int64 carry7;
+ Int64 carry8;
+ Int64 carry9;
+
+ carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+ carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+
+ carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
+ carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+
+ carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
+ carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+
+ carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
+ carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+
+ carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+ carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+
+ carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+
+ carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+
+ h.x0 = (Int32)h0;
+ h.x1 = (Int32)h1;
+ h.x2 = (Int32)h2;
+ h.x3 = (Int32)h3;
+ h.x4 = (Int32)h4;
+ h.x5 = (Int32)h5;
+ h.x6 = (Int32)h6;
+ h.x7 = (Int32)h7;
+ h.x8 = (Int32)h8;
+ h.x9 = (Int32)h9;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_sub.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_sub.cs
new file mode 100644
index 0000000..9a5b374
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_sub.cs
@@ -0,0 +1,63 @@
+using System;
+
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography.NaCl.Internal.Ed25519Ref10
+{
+ internal static partial class FieldOperations
+ {
+ /*
+ h = f - g
+ Can overlap h with f or g.
+
+ Preconditions:
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+
+ Postconditions:
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ */
+
+ internal static void fe_sub(out FieldElement h, ref FieldElement f, ref FieldElement g)
+ {
+ Int32 f0 = f.x0;
+ Int32 f1 = f.x1;
+ Int32 f2 = f.x2;
+ Int32 f3 = f.x3;
+ Int32 f4 = f.x4;
+ Int32 f5 = f.x5;
+ Int32 f6 = f.x6;
+ Int32 f7 = f.x7;
+ Int32 f8 = f.x8;
+ Int32 f9 = f.x9;
+ Int32 g0 = g.x0;
+ Int32 g1 = g.x1;
+ Int32 g2 = g.x2;
+ Int32 g3 = g.x3;
+ Int32 g4 = g.x4;
+ Int32 g5 = g.x5;
+ Int32 g6 = g.x6;
+ Int32 g7 = g.x7;
+ Int32 g8 = g.x8;
+ Int32 g9 = g.x9;
+ Int32 h0 = f0 - g0;
+ Int32 h1 = f1 - g1;
+ Int32 h2 = f2 - g2;
+ Int32 h3 = f3 - g3;
+ Int32 h4 = f4 - g4;
+ Int32 h5 = f5 - g5;
+ Int32 h6 = f6 - g6;
+ Int32 h7 = f7 - g7;
+ Int32 h8 = f8 - g8;
+ Int32 h9 = f9 - g9;
+ h.x0 = h0;
+ h.x1 = h1;
+ h.x2 = h2;
+ h.x3 = h3;
+ h.x4 = h4;
+ h.x5 = h5;
+ h.x6 = h6;
+ h.x7 = h7;
+ h.x8 = h8;
+ h.x9 = h9;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_tobytes.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_tobytes.cs
new file mode 100644
index 0000000..40f7b53
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/Internal/Ed25519Ref10/fe_tobytes.cs
@@ -0,0 +1,173 @@
+using System;
+
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography.NaCl.Internal.Ed25519Ref10
+{
+ internal static partial class FieldOperations
+ {
+ /*
+ Preconditions:
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+
+ Write p=2^255-19; q=floor(h/p).
+ Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
+
+ Proof:
+ Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
+ Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
+
+ Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
+ Then 0> 0);
+ s[offset + 1] = (byte)(h0 >> 8);
+ s[offset + 2] = (byte)(h0 >> 16);
+ s[offset + 3] = (byte)((h0 >> 24) | (h1 << 2));
+ s[offset + 4] = (byte)(h1 >> 6);
+ s[offset + 5] = (byte)(h1 >> 14);
+ s[offset + 6] = (byte)((h1 >> 22) | (h2 << 3));
+ s[offset + 7] = (byte)(h2 >> 5);
+ s[offset + 8] = (byte)(h2 >> 13);
+ s[offset + 9] = (byte)((h2 >> 21) | (h3 << 5));
+ s[offset + 10] = (byte)(h3 >> 3);
+ s[offset + 11] = (byte)(h3 >> 11);
+ s[offset + 12] = (byte)((h3 >> 19) | (h4 << 6));
+ s[offset + 13] = (byte)(h4 >> 2);
+ s[offset + 14] = (byte)(h4 >> 10);
+ s[offset + 15] = (byte)(h4 >> 18);
+ s[offset + 16] = (byte)(h5 >> 0);
+ s[offset + 17] = (byte)(h5 >> 8);
+ s[offset + 18] = (byte)(h5 >> 16);
+ s[offset + 19] = (byte)((h5 >> 24) | (h6 << 1));
+ s[offset + 20] = (byte)(h6 >> 7);
+ s[offset + 21] = (byte)(h6 >> 15);
+ s[offset + 22] = (byte)((h6 >> 23) | (h7 << 3));
+ s[offset + 23] = (byte)(h7 >> 5);
+ s[offset + 24] = (byte)(h7 >> 13);
+ s[offset + 25] = (byte)((h7 >> 21) | (h8 << 4));
+ s[offset + 26] = (byte)(h8 >> 4);
+ s[offset + 27] = (byte)(h8 >> 12);
+ s[offset + 28] = (byte)((h8 >> 20) | (h9 << 6));
+ s[offset + 29] = (byte)(h9 >> 2);
+ s[offset + 30] = (byte)(h9 >> 10);
+ s[offset + 31] = (byte)(h9 >> 18);
+ }
+ }
+
+ internal static void fe_reduce(out FieldElement hr, ref FieldElement h)
+ {
+ Int32 h0 = h.x0;
+ Int32 h1 = h.x1;
+ Int32 h2 = h.x2;
+ Int32 h3 = h.x3;
+ Int32 h4 = h.x4;
+ Int32 h5 = h.x5;
+ Int32 h6 = h.x6;
+ Int32 h7 = h.x7;
+ Int32 h8 = h.x8;
+ Int32 h9 = h.x9;
+ Int32 q;
+ Int32 carry0;
+ Int32 carry1;
+ Int32 carry2;
+ Int32 carry3;
+ Int32 carry4;
+ Int32 carry5;
+ Int32 carry6;
+ Int32 carry7;
+ Int32 carry8;
+ Int32 carry9;
+
+ q = (19 * h9 + (((Int32)1) << 24)) >> 25;
+ q = (h0 + q) >> 26;
+ q = (h1 + q) >> 25;
+ q = (h2 + q) >> 26;
+ q = (h3 + q) >> 25;
+ q = (h4 + q) >> 26;
+ q = (h5 + q) >> 25;
+ q = (h6 + q) >> 26;
+ q = (h7 + q) >> 25;
+ q = (h8 + q) >> 26;
+ q = (h9 + q) >> 25;
+
+ /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
+ h0 += 19 * q;
+ /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
+
+ carry0 = h0 >> 26;
+ h1 += carry0;
+ h0 -= carry0 << 26;
+ carry1 = h1 >> 25;
+ h2 += carry1;
+ h1 -= carry1 << 25;
+ carry2 = h2 >> 26;
+ h3 += carry2;
+ h2 -= carry2 << 26;
+ carry3 = h3 >> 25;
+ h4 += carry3;
+ h3 -= carry3 << 25;
+ carry4 = h4 >> 26;
+ h5 += carry4;
+ h4 -= carry4 << 26;
+ carry5 = h5 >> 25;
+ h6 += carry5;
+ h5 -= carry5 << 25;
+ carry6 = h6 >> 26;
+ h7 += carry6;
+ h6 -= carry6 << 26;
+ carry7 = h7 >> 25;
+ h8 += carry7;
+ h7 -= carry7 << 25;
+ carry8 = h8 >> 26;
+ h9 += carry8;
+ h8 -= carry8 << 26;
+ carry9 = h9 >> 25;
+ h9 -= carry9 << 25;
+ /* h10 = carry9 */
+
+ hr.x0 = h0;
+ hr.x1 = h1;
+ hr.x2 = h2;
+ hr.x3 = h3;
+ hr.x4 = h4;
+ hr.x5 = h5;
+ hr.x6 = h6;
+ hr.x7 = h7;
+ hr.x8 = h8;
+ hr.x9 = h9;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/MontgomeryCurve25519.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/MontgomeryCurve25519.cs
new file mode 100644
index 0000000..51e453f
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/NaCl/MontgomeryCurve25519.cs
@@ -0,0 +1,31 @@
+using System;
+
+
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography.NaCl
+{
+ using Internal.Ed25519Ref10;
+
+ public static class MontgomeryCurve25519
+ {
+ public static void EdwardsToMontgomery(ArraySegment montgomery, ArraySegment edwards)
+ {
+ FieldElement edwardsY, edwardsZ, montgomeryX;
+ FieldOperations.fe_frombytes(out edwardsY, edwards.Array, edwards.Offset);
+ FieldOperations.fe_1(out edwardsZ);
+ EdwardsToMontgomeryX(out montgomeryX, ref edwardsY, ref edwardsZ);
+ FieldOperations.fe_tobytes(montgomery.Array, montgomery.Offset, ref montgomeryX);
+ montgomery.Array[montgomery.Offset + 31] |= (byte)(edwards.Array[edwards.Offset + 31] & 0x80); // copy sign
+ }
+
+ private static void EdwardsToMontgomeryX(out FieldElement montgomeryX, ref FieldElement edwardsY,
+ ref FieldElement edwardsZ)
+ {
+ // montgomeryX = (edwardsZ + edwardsY) / (edwardsZ - edwardsY)
+ FieldElement tempX, tempZ;
+ FieldOperations.fe_add(out tempX, ref edwardsZ, ref edwardsY);
+ FieldOperations.fe_sub(out tempZ, ref edwardsZ, ref edwardsY);
+ FieldOperations.fe_invert(out tempZ, ref tempZ);
+ FieldOperations.fe_mul(out montgomeryX, ref tempX, ref tempZ);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/PublicKeyAuth.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/PublicKeyAuth.cs
new file mode 100644
index 0000000..99a3895
--- /dev/null
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/PublicKeyAuth.cs
@@ -0,0 +1,76 @@
+using System;
+
+using Beacon.Sdk.Core.Infrastructure.Cryptography.BouncyCastle;
+using Org.BouncyCastle.Math.EC.Rfc8032;
+
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography
+{
+ /// Public-key signatures
+ public static class PublicKeyAuth
+ {
+ private const int SECRET_KEY_BYTES = 32 + 32;
+ private const int PUBLIC_KEY_BYTES = 32;
+ private const int BYTES = 64;
+ private const int SEED_BYTES = 32;
+
+ public static int SecretKeyBytes { get; } = SECRET_KEY_BYTES;
+ public static int PublicKeyBytes { get; } = PUBLIC_KEY_BYTES;
+ public static int SignatureBytes { get; } = BYTES;
+ public static int SeedBytes { get; } = SEED_BYTES;
+
+ /// Creates a new key pair based on the provided seed.
+ /// The seed.
+ /// A KeyPair.
+ ///
+ public static KeyPair GenerateKeyPair(byte[] seed)
+ {
+ if (seed == null || seed.Length != SEED_BYTES)
+ throw new ArgumentOutOfRangeException(nameof(seed), seed?.Length ?? 0, $"seed must be {SEED_BYTES} bytes in length.");
+
+ var publicKey = new byte[PUBLIC_KEY_BYTES];
+ var privateKey = new byte[SECRET_KEY_BYTES];
+
+ Ed25519.GeneratePublicKey(seed, 0, publicKey, 0);
+
+ Buffer.BlockCopy(seed, 0, privateKey, 0, SEED_BYTES);
+ Buffer.BlockCopy(publicKey, 0, privateKey, SEED_BYTES, PUBLIC_KEY_BYTES);
+
+ return new KeyPair(publicKey, privateKey);
+ }
+
+ /// Signs a message with Ed25519.
+ /// The message.
+ /// The 64 byte private key.
+ /// The signature.
+ ///
+ public static byte[] SignDetached(byte[] message, byte[] key)
+ {
+ if (key == null || key.Length != SECRET_KEY_BYTES)
+ throw new ArgumentOutOfRangeException(nameof(key), key?.Length ?? 0, $"key must be {SECRET_KEY_BYTES} bytes in length.");
+
+ var signature = new byte[BYTES];
+
+ Ed25519.Sign(key, 0, message, 0, message.Length, signature, 0);
+
+ return signature;
+ }
+
+ /// Converts the ed25519 public key to curve25519 public key.
+ /// Ed25519 public key.
+ /// The curve25519 public key.
+ ///
+ public static byte[] ConvertEd25519PublicKeyToCurve25519PublicKey(byte[] ed25519PublicKey)
+ {
+ return Ed25519Extensions.ConvertEd25519PublicKeyToCurve25519PublicKey(ed25519PublicKey);
+ }
+
+ /// Converts the ed25519 secret key to curve25519 secret key.
+ /// Ed25519 secret key.
+ /// The curve25519 secret key.
+ ///
+ public static byte[] ConvertEd25519SecretKeyToCurve25519SecretKey(byte[] ed25519SecretKey)
+ {
+ return Ed25519Extensions.ConvertEd25519SecretKeyToCurve25519SecretKey(ed25519SecretKey);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/SealedPublicKeyBox.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/SealedPublicKeyBox.cs
similarity index 53%
rename from Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/SealedPublicKeyBox.cs
rename to Beacon.Sdk/Core/Infrastructure/Cryptography/SealedPublicKeyBox.cs
index 758a27c..657c6c3 100644
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/SealedPublicKeyBox.cs
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/SealedPublicKeyBox.cs
@@ -1,16 +1,19 @@
using System;
using System.Text;
-using Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium;
+using NaCl;
+using Org.BouncyCastle.Crypto.Digests;
namespace Beacon.Sdk.Core.Infrastructure.Cryptography
{
/// Create and Open SealedPublicKeyBoxes.
public static class SealedPublicKeyBox
{
- public const int RecipientPublicKeyBytes = Sodium.crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES;
- public const int RecipientSecretKeyBytes = Sodium.crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES;
- private const int CryptoBoxSealbytes = Sodium.crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES + Sodium.crypto_box_curve25519xsalsa20poly1305_MACBYTES;
+ public const int RecipientPublicKeyBytes = 32;
+ public const int RecipientSecretKeyBytes = 32;
+ private const int PublicKeyBytes = 32;
+ private const int MacBytes = 16;
+ private const int NonceBytes = 24;
/// Creates a SealedPublicKeyBox
/// The message.
@@ -34,17 +37,29 @@ public static byte[] Create(byte[] message, byte[] recipientPublicKey)
if (recipientPublicKey == null || recipientPublicKey.Length != RecipientPublicKeyBytes)
throw new ArgumentOutOfRangeException(nameof(recipientPublicKey), recipientPublicKey?.Length ?? 0, $"recipientPublicKey must be {RecipientPublicKeyBytes} bytes in length.");
- var buffer = new byte[message.Length + CryptoBoxSealbytes];
+ var buffer = new byte[message.Length + PublicKeyBytes + MacBytes];
- Sodium.Initialize();
- var ret = Sodium.CryptoBoxSeal(
- buffer,
- message,
- (ulong)message.Length,
- recipientPublicKey);
+ Curve25519XSalsa20Poly1305.KeyPair(out var esk, out var epk);
- if (ret != 0)
- throw new Exception("Failed to create SealedBox");
+ var secretBoxSeal = new Curve25519XSalsa20Poly1305(esk, recipientPublicKey);
+
+ var nonce = GetSealNonce(epk, recipientPublicKey);
+
+ secretBoxSeal.Encrypt(
+ cipher: new Span(buffer)[PublicKeyBytes..], // skip first 32 bytes for public key
+ message: message,
+ nonce: nonce);
+
+ Buffer.BlockCopy(epk, 0, buffer, 0, PublicKeyBytes);
+
+ //var ret = Sodium.CryptoBoxSeal(
+ // buffer,
+ // message,
+ // (ulong)message.Length,
+ // recipientPublicKey);
+
+ //if (ret != 0)
+ // throw new Exception("Failed to create SealedBox");
return buffer;
}
@@ -54,8 +69,7 @@ public static byte[] Create(byte[] message, byte[] recipientPublicKey)
/// The recipient's secret key.
/// The recipient's public key.
/// The decrypted message.
- ///
- ///
+ ///
public static byte[] Open(byte[] cipherText, byte[] recipientSecretKey, byte[] recipientPublicKey)
{
if (recipientSecretKey == null || recipientSecretKey.Length != RecipientSecretKeyBytes)
@@ -63,23 +77,46 @@ public static byte[] Open(byte[] cipherText, byte[] recipientSecretKey, byte[] r
if (recipientPublicKey == null || recipientPublicKey.Length != RecipientPublicKeyBytes)
throw new ArgumentOutOfRangeException(nameof(recipientPublicKey), recipientPublicKey?.Length ?? 0, $"recipientPublicKey must be {RecipientPublicKeyBytes} bytes in length.");
- if (cipherText.Length < CryptoBoxSealbytes)
+ if (cipherText.Length < PublicKeyBytes + MacBytes)
throw new Exception("Failed to open SealedBox");
- var buffer = new byte[cipherText.Length - CryptoBoxSealbytes];
+ var buffer = new byte[cipherText.Length - (PublicKeyBytes + MacBytes)];
+
+ var nonce = GetSealNonce(cipherText, recipientPublicKey);
- Sodium.Initialize();
- var ret = Sodium.CryptoBoxSealOpen(
- buffer,
- cipherText,
- (ulong)cipherText.Length,
- recipientPublicKey,
- recipientSecretKey);
+ var secretBoxSeal = new Curve25519XSalsa20Poly1305(recipientSecretKey, new ReadOnlySpan(cipherText)[..PublicKeyBytes]);
- if (ret != 0)
+ if (!secretBoxSeal.TryDecrypt(
+ message: buffer,
+ cipher: new ReadOnlySpan(cipherText)[PublicKeyBytes..],
+ nonce: nonce))
+ {
throw new Exception("Failed to open SealedBox");
+ }
+
+ //var ret = Sodium.CryptoBoxSealOpen(
+ // buffer,
+ // cipherText,
+ // (ulong)cipherText.Length,
+ // recipientPublicKey,
+ // recipientSecretKey);
+
+ //if (ret != 0)
+ // throw new Exception("Failed to open SealedBox");
return buffer;
}
+
+ private static byte[] GetSealNonce(byte[] pk1, byte[] pk2)
+ {
+ var nonce = new byte[NonceBytes];
+
+ var blake2bDigest = new Blake2bDigest(NonceBytes * 8);
+ blake2bDigest.BlockUpdate(pk1, 0, PublicKeyBytes);
+ blake2bDigest.BlockUpdate(pk2, 0, PublicKeyBytes);
+ blake2bDigest.DoFinal(nonce, 0);
+
+ return nonce;
+ }
}
}
\ No newline at end of file
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/SecretBox.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/SecretBox.cs
similarity index 76%
rename from Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/SecretBox.cs
rename to Beacon.Sdk/Core/Infrastructure/Cryptography/SecretBox.cs
index 4e8ad7a..6c246a2 100644
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/SecretBox.cs
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/SecretBox.cs
@@ -1,16 +1,16 @@
using System;
using System.Text;
-using Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium;
+using NaCl;
namespace Beacon.Sdk.Core.Infrastructure.Cryptography
{
/// Create and Open Secret Boxes.
public static class SecretBox
{
- private const int KEY_BYTES = Sodium.crypto_secretbox_xsalsa20poly1305_KEYBYTES;
- private const int NONCE_BYTES = Sodium.crypto_secretbox_xsalsa20poly1305_NONCEBYTES;
- private const int MAC_BYTES = Sodium.crypto_secretbox_xsalsa20poly1305_MACBYTES;
+ private const int KEY_BYTES = 32;
+ private const int NONCE_BYTES = 24;
+ private const int MAC_BYTES = 16;
/// Creates a Secret Box
/// Hex-encoded string to be encrypted.
@@ -30,9 +30,7 @@ public static byte[] Create(string message, byte[] nonce, byte[] key)
/// The 24 byte nonce.
/// The 32 byte key.
/// The encrypted message.
- ///
- ///
- ///
+ ///
public static byte[] Create(byte[] message, byte[] nonce, byte[] key)
{
if (key == null || key.Length != KEY_BYTES)
@@ -42,11 +40,20 @@ public static byte[] Create(byte[] message, byte[] nonce, byte[] key)
var buffer = new byte[message.Length + MAC_BYTES];
- Sodium.Initialize();
- var ret = Sodium.CryptoSecretBoxEasy(buffer, message, (ulong)message.Length, nonce, key);
+ // todo: change to BouncyCastle?
+ var secretBox = new XSalsa20Poly1305(key);
- if (ret != 0)
- throw new Exception("Failed to create SecretBox");
+ secretBox.Encrypt(
+ cipher: buffer,
+ message: message,
+ nonce: nonce);
+
+ //var ret = Sodium.CryptoSecretBoxEasy(
+ // buffer,
+ // message,
+ // (ulong)message.Length,
+ // nonce,
+ // key);
return buffer;
}
@@ -56,9 +63,7 @@ public static byte[] Create(byte[] message, byte[] nonce, byte[] key)
/// The 24 byte nonce.
/// The 32 byte nonce.
/// The decrypted text.
- ///
- ///
- ///
+ ///
public static byte[] Open(byte[] cipherText, byte[] nonce, byte[] key)
{
if (key == null || key.Length != KEY_BYTES)
@@ -96,11 +101,22 @@ public static byte[] Open(byte[] cipherText, byte[] nonce, byte[] key)
var buffer = new byte[cipherText.Length - MAC_BYTES];
- Sodium.Initialize();
- var ret = Sodium.CryptoSecretBoxOpenEasy(buffer, cipherText, (ulong)cipherText.Length, nonce, key);
+ var secretBox = new XSalsa20Poly1305(key);
- if (ret != 0)
+ if (!secretBox.TryDecrypt(
+ message: buffer,
+ cipher: cipherText,
+ nonce: nonce))
+ {
throw new Exception("Failed to open SecretBox");
+ }
+
+ //var ret = Sodium.CryptoSecretBoxOpenEasy(
+ // buffer,
+ // cipherText,
+ // (ulong)cipherText.Length,
+ // nonce,
+ // key);
return buffer;
}
diff --git a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/SessionKeyPair.cs b/Beacon.Sdk/Core/Infrastructure/Cryptography/SessionKeyPair.cs
similarity index 78%
rename from Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/SessionKeyPair.cs
rename to Beacon.Sdk/Core/Infrastructure/Cryptography/SessionKeyPair.cs
index 6977b40..ef8cbdf 100644
--- a/Beacon.Sdk/Core/Infrastructure/Cryptography/Libsodium/SessionKeyPair.cs
+++ b/Beacon.Sdk/Core/Infrastructure/Cryptography/SessionKeyPair.cs
@@ -1,4 +1,4 @@
-namespace Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium
+namespace Beacon.Sdk.Core.Infrastructure.Cryptography
{
public struct SessionKeyPair
{
diff --git a/Beacon.Sdk/Core/Infrastructure/Repositories/InMemorySessionKeyPairRepository.cs b/Beacon.Sdk/Core/Infrastructure/Repositories/InMemorySessionKeyPairRepository.cs
index 57eb4fe..e6ff4df 100644
--- a/Beacon.Sdk/Core/Infrastructure/Repositories/InMemorySessionKeyPairRepository.cs
+++ b/Beacon.Sdk/Core/Infrastructure/Repositories/InMemorySessionKeyPairRepository.cs
@@ -3,7 +3,6 @@
namespace Beacon.Sdk.Core.Infrastructure.Repositories
{
using System.Collections.Concurrent;
- using Cryptography.Libsodium;
using Domain.Interfaces;
using Domain.Interfaces.Data;
using Utils;
diff --git a/README.md b/README.md
index 2a18c45..3f41433 100644
--- a/README.md
+++ b/README.md
@@ -18,53 +18,6 @@ Beacon .NET SDK is [available on NuGet](https://www.nuget.org/packages/Beacon.Sd
dotnet add package Beacon.Sdk
```
-### Libsodium library runtime dependencies
-
-Beacon.Sdk uses the [libsodium](https://doc.libsodium.org/) cryptographic library. Some platforms may require additional runtime or static binaries:
-
-#### Windows/Linux/MacOS
-
-All runtime binaries already included. Nothing to do...
-
-#### Android
-
-`libsodium.so` library files for different architectures must be included in project resources:
-```
-Project
-└── Resources
- └── lib
- └── arm64-v8a
- └── libsodium.so
- └── armeabi-v7a
- └── libsodium.so
- └── x86_64
- └── libsodium.so
-```
-
-#### iOS static linking
-
-`libsodium.a` static library files must be compiled for all required architectures (arm64, armv7, i386 e.t.c).
-
-Binaries for all architectures must be concatenated to universal (fat) binary file:
-```
-lipo -create -output libsodium.a libsodium-i386.a libsodium-arm64.a libsodium-armv7.a
-```
-
-The resulting `libsodium.a` file must be added to iOS project with the `Build Action` property set to `None`.
-
-The next step is to specify iOS extra build arguments:
-
-```
--gcc_flags "-L${ProjectDir} -lsodium -force_load ${ProjectDir}/libsodium.a"
-```
-
-And the last step is to specify how the library will be used by your application at startup:
-```Csharp
-using Beacon.Sdk.Core.Infrastructure.Cryptography.Libsodium;
-
-Sodium.SetLibraryType(SodiumLibraryType.StaticInternal);
-```
-
## Usage
For a complete example, refer