Public Key Cryptography _Authenticated Encryption - Chewhern/ASodium GitHub Wiki

For detail documentation, kindly refer to official libsodium.

Key Pair Generation

There're 2 types of key pair in this wrapper library.

For details about the structure of different key pair types, kindly refer to these 2 links.

(https://github.com/Chewhern/ASodium/blob/main/Source/KeyPair.cs)

(https://github.com/Chewhern/ASodium/blob/main/Source/RevampedKeyPair.cs)

Revamped Key Pair Generation (Closest to the maintenance mode libsodium-core binding's keypair)

Initial Functions

public static RevampedKeyPair GenerateRevampedKeyPair()

Example Code

RevampedKeyPair MyRevampedKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
//Uses libsodium secure memory to clear  the sensitive key materials
MyRevampedKeyPair.Clear();

Key Pair Generation (New Object which uses both C#'s IntPtr and Sodium Guarded Heap Allocations)

I am kinda an amateur when I first created my own binding.., the Key Pair structure which originally resides in libsodium-core has a memory protect function/method in which I couldn't recreate due to different environments and languages..

The libsodium's guarded heap allocations is not an immediate fix to the issue I faced but at the least.., it is better than having no protections on sensitive cryptography data..

Initial Functions

public static KeyPair GenerateKeyPair()

Example Code

SodiumInit.Init();
KeyPair MyKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
IntPtr PrivateKeyIntPtr = MyKeyPair.GetPrivateKey();
Byte[] PrivateKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
Marshal.Copy(PrivateKeyIntPtr, PrivateKey, 0, 32);
MyKeyPair.ProtectPrivateKey();
MyKeyPair.Clear();

Generate Public Key Given Private Key

Helper Function

public static Byte[] GeneratePublicKey(Byte[] SecretKey,Boolean ClearKey = false)

Example Code

Byte[] PrivateKey = SodiumRNG.GetRandomBytes(SodiumPublicKeyBox.GetSecretKeyBytesLength());
Byte[] PublicKey = SodiumPublicKeyBox.GeneratePublicKey(PrivateKey);

Generate shared shared from 2 different key pairs

Helper Function

public static Byte[] GenerateSharedSecret(Byte[] CurrentUserSecretKey,Byte[] OtherUserPublicKey,Boolean ClearKey = false)

Example Code

//==RevampedKeyPair==
RevampedKeyPair AliceKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
RevampedKeyPair BobKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
Byte[] RandomMessage = SodiumRNG.GetRandomBytes(128);
Byte[] Nonce = SodiumPublicKeyBox.GenerateNonce();
Byte[] SharedSecret1 = SodiumPublicKeyBox.GenerateSharedSecret(BobKeyPair.PublicKey,AliceKeyPair.PrivateKey);
Byte[] SharedSecret2 = SodiumPublicKeyBox.GenerateSharedSecret(AliceKeyPair.PublicKey, BobKeyPair.PrivateKey);
//==KeyPair==
//Please call sodium_init() or SodiumInit.Init() before using sodium guarded heap allocations
KeyPair AliceNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
KeyPair BobNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
IntPtr AliceSecretKeyIntPtr = AliceNewKeyPair.GetPrivateKey();
Byte[] AliceSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
IntPtr BobSecretKeyIntPtr = BobNewKeyPair.GetPrivateKey();
Byte[] BobSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
Marshal.Copy(AliceSecretKeyIntPtr, AliceSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
Marshal.Copy(BobSecretKeyIntPtr, BobSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
Byte[] SharedSecretAlice = SodiumPublicKeyBox.GenerateSharedSecret(BobNewKeyPair.GetPublicKey(), AliceSecretKey);
Byte[] SharedSecretBob = SodiumPublicKeyBox.GenerateSharedSecret(AliceNewKeyPair.GetPublicKey(), BobSecretKey);

Combined encryption and decryption

Initial Functions

public static Byte[] Create(Byte[] Message, Byte[] Nonce, Byte[] CurrentUserSecretKey, Byte[] OtherUserPublicKey,Boolean ClearKey=false)
public static Byte[] Open(Byte[] CipherText, Byte[] Nonce, Byte[] CurrentUserSecretKey, Byte[] OtherUserPublicKey,Boolean ClearKey=false)

Example Code

//RevampedKeyPair
RevampedKeyPair AliceKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
RevampedKeyPair BobKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
Byte[] RandomMessage = SodiumRNG.GetRandomBytes(128);
Byte[] Nonce = SodiumPublicKeyBox.GenerateNonce();
Byte[] CipherText = SodiumPublicKeyBox.Create(RandomMessage, Nonce, AliceKeyPair.PrivateKey, BobKeyPair.PublicKey);
Byte[] PlainText = SodiumPublicKeyBox.Open(CipherText, Nonce, BobKeyPair.PrivateKey, AliceKeyPair.PublicKey);
AliceKeyPair.Clear();
BobKeyPair.Clear();
//KeyPair
KeyPair AliceNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
KeyPair BobNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
IntPtr AliceSecretKeyIntPtr = AliceNewKeyPair.GetPrivateKey();
Byte[] AliceSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
IntPtr BobSecretKeyIntPtr = BobNewKeyPair.GetPrivateKey();
Byte[] BobSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
Marshal.Copy(AliceSecretKeyIntPtr, AliceSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
Marshal.Copy(BobSecretKeyIntPtr, BobSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
CipherText = SodiumPublicKeyBox.Create(RandomMessage, Nonce, AliceSecretKey, BobNewKeyPair.GetPublicKey());
PlainText = SodiumPublicKeyBox.Open(CipherText, Nonce, BobSecretKey, AliceNewKeyPair.GetPublicKey());
AliceNewKeyPair.ProtectPrivateKey();
BobNewKeyPair.ProtectPrivateKey();
AliceNewKeyPair.Clear();
BobNewKeyPair.Clear();

Detached encryption and decryption

Initial Functions

public static PublicKeyBoxDetachedBox CreateDetached(Byte[] Message, Byte[] Nonce, Byte[] CurrentUserSecretKey, Byte[] OtherUserPublicKey, Boolean ClearKey = false)
public static byte[] OpenDetached(Byte[] CipherText, Byte[] MAC, Byte[] Nonce, Byte[] CurrentUserSecretKey, Byte[] OtherUserPublicKey,Boolean ClearKey=false)

Example Code

//==RevampedKeyPair==
RevampedKeyPair AliceKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
RevampedKeyPair BobKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
Byte[] RandomMessage = SodiumRNG.GetRandomBytes(128);
Byte[] Nonce = SodiumPublicKeyBox.GenerateNonce();
PublicKeyBoxDetachedBox MyDetachedBox = SodiumPublicKeyBox.CreateDetached(RandomMessage, Nonce, AliceKeyPair.PrivateKey, BobKeyPair.PublicKey);
Byte[] PlainText = SodiumPublicKeyBox.OpenDetached(MyDetachedBox.CipherText,MyDetachedBox.MAC, Nonce, BobKeyPair.PrivateKey, AliceKeyPair.PublicKey);
AliceKeyPair.Clear();
BobKeyPair.Clear();
//==KeyPair==
KeyPair AliceNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
KeyPair BobNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
IntPtr AliceSecretKeyIntPtr = AliceNewKeyPair.GetPrivateKey();
Byte[] AliceSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
IntPtr BobSecretKeyIntPtr = BobNewKeyPair.GetPrivateKey();
Byte[] BobSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
Marshal.Copy(AliceSecretKeyIntPtr, AliceSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
Marshal.Copy(BobSecretKeyIntPtr, BobSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
MyDetachedBox = SodiumPublicKeyBox.CreateDetached(RandomMessage, Nonce, AliceSecretKey, BobNewKeyPair.GetPublicKey());
PlainText = SodiumPublicKeyBox.OpenDetached(MyDetachedBox.CipherText, MyDetachedBox.MAC, Nonce, BobSecretKey, AliceNewKeyPair.GetPublicKey());
AliceNewKeyPair.ProtectPrivateKey();
BobNewKeyPair.ProtectPrivateKey();
AliceNewKeyPair.Clear();
BobNewKeyPair.Clear();

Pre-Calculation Interface

This section of the wiki describes about Pre-Calculation Interface

Generate Shared Secret

Initial Functions

public static Byte[] CalculateSharedSecret(Byte[] OtherUserPublicKey,Byte[] CurrentUserPrivateKey,Boolean ClearKey=false)

Example Code

//==RevampedKeyPair==
RevampedKeyPair AliceKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
RevampedKeyPair BobKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
Byte[] RandomMessage = SodiumRNG.GetRandomBytes(128);
Byte[] Nonce = SodiumPublicKeyBox.GenerateNonce();
Byte[] SharedSecret1 = SodiumPublicKeyBoxPCI.CalculateSharedSecret(BobKeyPair.PublicKey,AliceKeyPair.PrivateKey);
Byte[] SharedSecret2 = SodiumPublicKeyBoxPCI.CalculateSharedSecret(AliceKeyPair.PublicKey, BobKeyPair.PrivateKey);
//==KeyPair==
//Please call sodium_init() or SodiumInit.Init() before using sodium guarded heap allocations
KeyPair AliceNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
KeyPair BobNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
IntPtr AliceSecretKeyIntPtr = AliceNewKeyPair.GetPrivateKey();
Byte[] AliceSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
IntPtr BobSecretKeyIntPtr = BobNewKeyPair.GetPrivateKey();
Byte[] BobSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
Marshal.Copy(AliceSecretKeyIntPtr, AliceSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
Marshal.Copy(BobSecretKeyIntPtr, BobSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
Byte[] SharedSecretAlice = SodiumPublicKeyBoxPCI.CalculateSharedSecret(BobNewKeyPair.GetPublicKey(), AliceSecretKey);
Byte[] SharedSecretBob = SodiumPublicKeyBoxPCI.CalculateSharedSecret(AliceNewKeyPair.GetPublicKey(), BobSecretKey);

Combined encryption and decryption

Initial Functions

public static Byte[] Create(Byte[] Message, Byte[] Nonce, Byte[] SharedSecret,Boolean ClearKey=false)
public static Byte[] Open(Byte[] CipherText, Byte[] Nonce, Byte[] SharedSecret, Boolean ClearKey = false)

Example Code

//==RevampedKeyPair==
RevampedKeyPair AliceKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
RevampedKeyPair BobKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
Byte[] RandomMessage = SodiumRNG.GetRandomBytes(128);
Byte[] Nonce = SodiumPublicKeyBox.GenerateNonce();
Byte[] SharedSecret1 = SodiumPublicKeyBoxPCI.CalculateSharedSecret(BobKeyPair.PublicKey,AliceKeyPair.PrivateKey);
Byte[] SharedSecret2 = SodiumPublicKeyBoxPCI.CalculateSharedSecret(AliceKeyPair.PublicKey, BobKeyPair.PrivateKey);
Byte[] AliceCipherText = SodiumPublicKeyBoxPCI.Create(RandomMessage, Nonce, SharedSecret1);
Byte[] BobReceivedPlainText = SodiumPublicKeyBoxPCI.Open(AliceCipherText, Nonce, SharedSecret2);
AliceKeyPair.Clear();
BobKeyPair.Clear();
//==KeyPair==
KeyPair AliceNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
KeyPair BobNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
IntPtr AliceSecretKeyIntPtr = AliceNewKeyPair.GetPrivateKey();
Byte[] AliceSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
IntPtr BobSecretKeyIntPtr = BobNewKeyPair.GetPrivateKey();
Byte[] BobSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
Marshal.Copy(AliceSecretKeyIntPtr, AliceSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
Marshal.Copy(BobSecretKeyIntPtr, BobSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
Byte[] SharedSecretAlice = SodiumPublicKeyBoxPCI.CalculateSharedSecret(BobNewKeyPair.GetPublicKey(), AliceSecretKey);
Byte[] SharedSecretBob = SodiumPublicKeyBoxPCI.CalculateSharedSecret(AliceNewKeyPair.GetPublicKey(), BobSecretKey);
AliceCipherText = SodiumPublicKeyBoxPCI.Create(RandomMessage, Nonce, SharedSecretAlice);
BobReceivedPlainText = SodiumPublicKeyBoxPCI.Open(AliceCipherText, Nonce, SharedSecretBob);
AliceNewKeyPair.ProtectPrivateKey();
BobNewKeyPair.ProtectPrivateKey();
AliceNewKeyPair.Clear();
BobNewKeyPair.Clear();

Detached Encryption and Decryption

Initial Functions

public static PublicKeyBoxDetachedBox CreateDetached(Byte[] Message, Byte[] Nonce, Byte[] SharedSecret, Boolean ClearKey = false)
public static byte[] OpenDetached(Byte[] CipherText, Byte[] MAC, Byte[] Nonce, Byte[] SharedSecret,Boolean ClearKey=false)

Example Code

//==RevampedKeyPair==
RevampedKeyPair AliceKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
RevampedKeyPair BobKeyPair = SodiumPublicKeyBox.GenerateRevampedKeyPair();
Byte[] RandomMessage = SodiumRNG.GetRandomBytes(128);
Byte[] Nonce = SodiumPublicKeyBox.GenerateNonce();
Byte[] SharedSecret1 = SodiumPublicKeyBoxPCI.CalculateSharedSecret(BobKeyPair.PublicKey, AliceKeyPair.PrivateKey);
Byte[] SharedSecret2 = SodiumPublicKeyBoxPCI.CalculateSharedSecret(AliceKeyPair.PublicKey, BobKeyPair.PrivateKey);
PublicKeyBoxDetachedBox MyDetachedBox = SodiumPublicKeyBoxPCI.CreateDetached(RandomMessage, Nonce, SharedSecret1);
Byte[] BobReceivedPlainText = SodiumPublicKeyBoxPCI.OpenDetached(MyDetachedBox.CipherText, MyDetachedBox.MAC, Nonce, SharedSecret2);
AliceKeyPair.Clear();
BobKeyPair.Clear();
//==KeyPair==
KeyPair AliceNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
KeyPair BobNewKeyPair = SodiumPublicKeyBox.GenerateKeyPair();
IntPtr AliceSecretKeyIntPtr = AliceNewKeyPair.GetPrivateKey();
Byte[] AliceSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
IntPtr BobSecretKeyIntPtr = BobNewKeyPair.GetPrivateKey();
Byte[] BobSecretKey = new Byte[SodiumPublicKeyBox.GetSecretKeyBytesLength()];
Marshal.Copy(AliceSecretKeyIntPtr, AliceSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
Marshal.Copy(BobSecretKeyIntPtr, BobSecretKey, 0, SodiumPublicKeyBox.GetSecretKeyBytesLength());
Byte[] SharedSecretAlice = SodiumPublicKeyBoxPCI.CalculateSharedSecret(BobNewKeyPair.GetPublicKey(), AliceSecretKey);
Byte[] SharedSecretBob = SodiumPublicKeyBoxPCI.CalculateSharedSecret(AliceNewKeyPair.GetPublicKey(), BobSecretKey);
MyDetachedBox = SodiumPublicKeyBoxPCI.CreateDetached(RandomMessage, Nonce, SharedSecretAlice);
BobReceivedPlainText = SodiumPublicKeyBoxPCI.OpenDetached(MyDetachedBox.CipherText, MyDetachedBox.MAC, Nonce, SharedSecretBob);
AliceNewKeyPair.ProtectPrivateKey();
BobNewKeyPair.ProtectPrivateKey();
AliceNewKeyPair.Clear();
BobNewKeyPair.Clear();