public static byte[] DeriveFromKey(byte[] masterKey, int subKeyLength, ulong subKeyId, byte[] context) { var key = new byte[32]; key.Initialize(); Array.Copy(masterKey, 0, key, 0, masterKey.Length > 32 ? 32 : masterKey.Length); var ctx = new byte[8]; ctx.Initialize(); Array.Copy(context, 0, ctx, 0, context.Length > 8 ? 8 : context.Length); var subkey = new byte[subKeyLength]; var bin = Marshal.AllocHGlobal(subkey.Length); var ret = SodiumLibrary.crypto_kdf_derive_from_key(bin, new UIntPtr((uint)subKeyLength), subKeyId, ctx, key); if (ret != 0) { throw new InvalidOperationException($"Error derive sub key from master key. ({ret})"); } Marshal.Copy(bin, subkey, 0, subKeyLength); Marshal.FreeHGlobal(bin); return(subkey); }