1
+ using System ;
2
+ using System . Runtime . InteropServices ;
3
+
4
+ namespace NetMQSecurityFactory
5
+ {
6
+ [ EncryptionPriority ]
7
+ public class LibSodium : ICurveEncrypt
8
+ {
9
+ private byte [ ] SharedSecretKey = new byte [ 32 ] ;
10
+ const string DllName = "libsodium.dll" ;
11
+
12
+ //crypto_secretbox_easy
13
+ [ DllImport ( DllName , CallingConvention = CallingConvention . Cdecl ) ]
14
+ internal static extern int crypto_secretbox_easy ( ref byte buffer , byte [ ] message , long messageLength , byte [ ] nonce , byte [ ] key ) ;
15
+
16
+ [ DllImport ( DllName , CallingConvention = CallingConvention . Cdecl ) ]
17
+ internal static extern int crypto_box_beforenm ( byte [ ] shared_key , byte [ ] public_key , byte [ ] secret_key ) ;
18
+
19
+ //crypto_secretbox_open_easy
20
+ [ DllImport ( DllName , CallingConvention = CallingConvention . Cdecl ) ]
21
+ internal static extern int crypto_secretbox_open_easy ( ref byte buffer , byte [ ] cipherText , long cipherTextLength , byte [ ] nonce , byte [ ] key ) ;
22
+
23
+ //sodium_version_string
24
+ [ DllImport ( DllName , CallingConvention = CallingConvention . Cdecl ) ]
25
+ internal static extern IntPtr sodium_version_string ( ) ;
26
+
27
+ public LibSodium ( )
28
+ {
29
+ var ptr = LibSodium . sodium_version_string ( ) ;
30
+ Marshal . PtrToStringAnsi ( ptr ) ;
31
+ }
32
+
33
+ public void Dispose ( )
34
+ {
35
+ }
36
+
37
+ public void SetKey ( ReadOnlySpan < byte > secretKey , ReadOnlySpan < byte > publicKey )
38
+ {
39
+ crypto_box_beforenm ( SharedSecretKey , publicKey . ToArray ( ) , secretKey . ToArray ( ) ) ;
40
+ }
41
+
42
+ public void Encrypt ( Span < byte > cipher , Span < byte > mac , ReadOnlySpan < byte > message , ReadOnlySpan < byte > nonce )
43
+ {
44
+ var complete = new Span < byte > ( new byte [ mac . Length + cipher . Length ] ) ;
45
+
46
+ LibSodium . crypto_secretbox_easy ( ref cipher . GetPinnableReference ( ) , complete . ToArray ( ) , complete . Length , nonce . ToArray ( ) , SharedSecretKey ) ;
47
+
48
+ complete . Slice ( 0 , mac . Length ) . CopyTo ( mac ) ;
49
+ complete . Slice ( mac . Length ) . CopyTo ( cipher ) ;
50
+ }
51
+
52
+ public void Encrypt ( Span < byte > cipher , ReadOnlySpan < byte > message , ReadOnlySpan < byte > nonce )
53
+ {
54
+ LibSodium . crypto_secretbox_easy ( ref cipher . GetPinnableReference ( ) , message . ToArray ( ) , message . Length , nonce . ToArray ( ) , SharedSecretKey ) ;
55
+ }
56
+
57
+ public bool TryDecrypt ( Span < byte > message , ReadOnlySpan < byte > cipher , ReadOnlySpan < byte > nonce )
58
+ {
59
+ return LibSodium . crypto_secretbox_open_easy ( ref message . GetPinnableReference ( ) , cipher . ToArray ( ) , cipher . Length , nonce . ToArray ( ) , SharedSecretKey ) == 0 ;
60
+ }
61
+
62
+ public bool TryDecrypt ( Span < byte > message , ReadOnlySpan < byte > cipher , ReadOnlySpan < byte > mac , ReadOnlySpan < byte > nonce )
63
+ {
64
+ var complete = new Span < byte > ( new byte [ mac . Length + cipher . Length ] ) ;
65
+ mac . CopyTo ( complete ) ;
66
+
67
+ cipher . CopyTo ( complete . Slice ( mac . Length ) ) ;
68
+
69
+ return LibSodium . crypto_secretbox_open_easy ( ref message . GetPinnableReference ( ) , complete . ToArray ( ) , complete . Length , nonce . ToArray ( ) , SharedSecretKey ) == 0 ;
70
+ }
71
+ }
72
+ }
0 commit comments