Skip to content

Commit 22cd7fd

Browse files
committed
feat(crypto): ✨ add Sha256 and X25519 APIs, and use Span based APIs
1 parent 2d4a515 commit 22cd7fd

27 files changed

+380
-46
lines changed
Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using Algorand.Unity.LowLevel;
2-
using Unity.Collections;
3-
using Unity.Collections.LowLevel.Unsafe;
1+
using System;
42

53
namespace Algorand.Unity.Crypto
64
{
@@ -9,31 +7,39 @@ public static partial class ChaCha20Poly1305
97
public enum DecryptionError
108
{
119
None = 0,
12-
VerificationFailed = -1
10+
VerificationFailed = -1,
11+
InvalidMessageLength = 1
1312
}
1413

15-
public static unsafe DecryptionError Decrypt<TCipher>(
16-
NativeList<byte> message,
17-
TCipher cipher,
14+
public static unsafe DecryptionError Decrypt(
15+
Span<byte> message,
16+
ReadOnlySpan<byte> cipher,
1817
Key key,
1918
Nonce nonce
2019
)
21-
where TCipher : struct, IByteArray
2220
{
23-
message.Length = cipher.Length - AuthTag.Size;
24-
var errorCode = sodium.crypto_aead_chacha20poly1305_ietf_decrypt(
25-
message.GetUnsafePtr(),
26-
out var messageLength,
27-
null,
28-
cipher.GetUnsafePtr(),
29-
(ulong)cipher.Length,
30-
null,
31-
0,
32-
nonce.GetUnsafePtr(),
33-
key.GetUnsafePtr()
34-
);
35-
message.Length = (int)messageLength;
21+
if (message.Length != cipher.Length - AuthTag.Size)
22+
{
23+
return DecryptionError.InvalidMessageLength;
24+
}
25+
26+
var errorCode = 0;
27+
fixed (byte* m = &message[0])
28+
fixed (byte* c = &cipher[0])
29+
{
30+
errorCode = sodium.crypto_aead_chacha20poly1305_ietf_decrypt(
31+
m,
32+
out _,
33+
null,
34+
c,
35+
(ulong)cipher.Length,
36+
null,
37+
0,
38+
nonce.GetUnsafePtr(),
39+
key.GetUnsafePtr()
40+
);
41+
}
3642
return (DecryptionError)errorCode;
3743
}
3844
}
39-
}
45+
}
Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,53 @@
1-
using Algorand.Unity.LowLevel;
2-
using Unity.Collections;
3-
using Unity.Collections.LowLevel.Unsafe;
1+
using System;
42

53
namespace Algorand.Unity.Crypto
64
{
75
public static partial class ChaCha20Poly1305
86
{
97
public enum EncryptionError
108
{
11-
None = 0
9+
None = 0,
10+
CipherInvalidSize = 1,
1211
}
1312

14-
public static unsafe EncryptionError Encrypt<TMessage>(
15-
NativeList<byte> cipher,
16-
TMessage message,
13+
/// <summary>
14+
/// Encrypt a message using the ChaCha20Poly1305 algorithm.
15+
/// </summary>
16+
/// <param name="cipher">The encrypted message.</param>
17+
/// <param name="message">The message to encrypt.</param>
18+
/// <param name="key">The symmetric key to encrypt with.</param>
19+
/// <param name="nonce">The 12 byte iv to use to encrypt.</param>
20+
/// <returns></returns>
21+
public static unsafe EncryptionError Encrypt(
22+
Span<byte> cipher,
23+
ReadOnlySpan<byte> message,
1724
Key key,
1825
Nonce nonce
1926
)
20-
where TMessage : struct, IByteArray
2127
{
22-
cipher.Length = message.Length + AuthTag.Size;
23-
var errorCode = sodium.crypto_aead_chacha20poly1305_ietf_encrypt(
24-
cipher.GetUnsafePtr(),
25-
out var cipherLength,
26-
message.GetUnsafePtr(),
27-
(ulong)message.Length,
28-
null,
29-
0,
30-
null,
31-
nonce.GetUnsafePtr(),
32-
key.GetUnsafePtr()
33-
);
34-
cipher.Length = (int)cipherLength;
35-
nonce += 1;
28+
var cipherLength = message.Length + AuthTag.Size;
29+
if (cipher.Length != cipherLength)
30+
{
31+
return EncryptionError.CipherInvalidSize;
32+
}
33+
var errorCode = default(int);
34+
35+
fixed (byte* c = &cipher[0])
36+
fixed (byte* m = &message[0])
37+
{
38+
errorCode = sodium.crypto_aead_chacha20poly1305_ietf_encrypt(
39+
c,
40+
out _,
41+
m,
42+
(ulong)message.Length,
43+
null,
44+
0,
45+
null,
46+
nonce.GetUnsafePtr(),
47+
key.GetUnsafePtr()
48+
);
49+
}
3650
return (EncryptionError)errorCode;
3751
}
3852
}
39-
}
53+
}

Runtime/Algorand.Unity.Crypto/Ed25519/Ed25519+SecretKeyHandle.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,22 @@ public readonly unsafe Signature Sign<TMessage>(TMessage message)
5656
Ptr);
5757
return signature;
5858
}
59+
60+
public readonly unsafe Signature Sign(ReadOnlySpan<byte> message)
61+
{
62+
var signature = new Signature();
63+
fixed (byte* mPtr = &message.GetPinnableReference())
64+
{
65+
crypto_sign_ed25519_detached(
66+
&signature,
67+
out _,
68+
mPtr,
69+
(ulong)message.Length,
70+
Ptr);
71+
}
72+
73+
return signature;
74+
}
5975
}
6076
}
6177
}

Runtime/Algorand.Unity.Crypto/Ed25519/Ed25519+Signature.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,23 @@ public bool Verify<TMessage>(TMessage message, PublicKey pk)
5555
}
5656
}
5757

58+
public bool Verify(ReadOnlySpan<byte> message, PublicKey pk)
59+
{
60+
unsafe
61+
{
62+
fixed (byte* m = message)
63+
fixed (Signature* s = &this)
64+
{
65+
var error = crypto_sign_ed25519_verify_detached(
66+
s,
67+
m,
68+
(ulong)message.Length,
69+
&pk);
70+
return error == 0;
71+
}
72+
}
73+
}
74+
5875
public override bool Equals(object obj)
5976
{
6077
return ByteArray.Equals(this, obj);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Runtime.InteropServices;
2+
3+
namespace Algorand.Unity.Crypto
4+
{
5+
internal static unsafe partial class sodium
6+
{
7+
internal const ulong crypto_box_PUBLICKEYBYTES = 32U;
8+
internal const ulong crypto_box_SECRETKEYBYTES = 32U;
9+
internal const ulong crypto_box_NONCEBYTES = 24U;
10+
11+
[DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
12+
internal static extern int crypto_box_keypair(
13+
void* pk,
14+
void* sk);
15+
16+
[DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
17+
internal static extern int crypto_box_seed_keypair(
18+
void* pk,
19+
void* sk,
20+
void* seed);
21+
22+
[DllImport(Library, CallingConvention = CallingConvention.Cdecl)]
23+
internal static extern int crypto_box_easy(
24+
void* c,
25+
void* m,
26+
ulong mlen,
27+
void* n,
28+
void* pk,
29+
void* sk);
30+
}
31+
}

Runtime/Algorand.Unity.Crypto/Interop/sodium/sodium+CryptoBox.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)