public AdditionalAuthenticatedDataTemplate(IEnumerable <string> purposes)
            {
                const int MEMORYSTREAM_DEFAULT_CAPACITY = 0x100; // matches MemoryStream.EnsureCapacity
                var       ms = new MemoryStream(MEMORYSTREAM_DEFAULT_CAPACITY);

                // additionalAuthenticatedData := { magicHeader (32-bit) || keyId || purposeCount (32-bit) || (purpose)* }
                // purpose := { utf8ByteCount (7-bit encoded) || utf8Text }

                using (var writer = new PurposeBinaryWriter(ms))
                {
                    writer.WriteBigEndian(MAGIC_HEADER_V0);
                    Debug.Assert(ms.Position == sizeof(uint));
                    long posPurposeCount = writer.Seek(sizeof(Guid), SeekOrigin.Current); // skip over where the key id will be stored; we'll fill it in later
                    writer.Seek(sizeof(uint), SeekOrigin.Current);                        // skip over where the purposeCount will be stored; we'll fill it in later

                    uint purposeCount = 0;
                    foreach (string purpose in purposes)
                    {
                        Debug.Assert(purpose != null);
                        writer.Write(purpose); // prepends length as a 7-bit encoded integer
                        purposeCount++;
                    }

                    // Once we have written all the purposes, go back and fill in 'purposeCount'
                    writer.Seek(checked ((int)posPurposeCount), SeekOrigin.Begin);
                    writer.WriteBigEndian(purposeCount);
                }

                _aadTemplate = ms.ToArray();
            }
        private static byte[] GenerateAdditionalAuthenticatedDataTemplateFromPurposes(string[] purposes)
        {
            const int MEMORYSTREAM_DEFAULT_CAPACITY = 0x100; // matches MemoryStream.EnsureCapacity
            var       ms = new MemoryStream(MEMORYSTREAM_DEFAULT_CAPACITY);

            // additionalAuthenticatedData := { magicHeader || encryptor-GUID || purposeCount || (purpose)* }
            // purpose := { utf8ByteCount || utf8Text }
            using (var writer = new PurposeBinaryWriter(ms))
            {
                writer.WriteBigEndian(MAGIC_HEADER_V0);
                Debug.Assert(ms.Position == sizeof(uint));
                writer.Seek(sizeof(Guid), SeekOrigin.Current); // skip over where the encryptor GUID will be stored; we'll fill it in later
                if (purposes != null)
                {
                    writer.Write7BitEncodedInt(purposes.Length);
                    foreach (var purpose in purposes)
                    {
                        if (String.IsNullOrEmpty(purpose))
                        {
                            writer.Write7BitEncodedInt(0); // blank purpose
                        }
                        else
                        {
                            writer.Write(purpose);
                        }
                    }
                }
                else
                {
                    writer.Write7BitEncodedInt(0); // empty purposes array
                }
            }

            return(ms.ToArray());
        }
            public AdditionalAuthenticatedDataTemplate(IEnumerable<string> purposes)
            {
                const int MEMORYSTREAM_DEFAULT_CAPACITY = 0x100; // matches MemoryStream.EnsureCapacity
                var ms = new MemoryStream(MEMORYSTREAM_DEFAULT_CAPACITY);

                // additionalAuthenticatedData := { magicHeader (32-bit) || keyId || purposeCount (32-bit) || (purpose)* }
                // purpose := { utf8ByteCount (7-bit encoded) || utf8Text }

                using (var writer = new PurposeBinaryWriter(ms))
                {
                    writer.WriteBigEndian(MAGIC_HEADER_V0);
                    Debug.Assert(ms.Position == sizeof(uint));
                    long posPurposeCount = writer.Seek(sizeof(Guid), SeekOrigin.Current); // skip over where the key id will be stored; we'll fill it in later
                    writer.Seek(sizeof(uint), SeekOrigin.Current); // skip over where the purposeCount will be stored; we'll fill it in later

                    uint purposeCount = 0;
                    foreach (string purpose in purposes)
                    {
                        Debug.Assert(purpose != null);
                        writer.Write(purpose); // prepends length as a 7-bit encoded integer
                        purposeCount++;
                    }

                    // Once we have written all the purposes, go back and fill in 'purposeCount'
                    writer.Seek(checked((int)posPurposeCount), SeekOrigin.Begin);
                    writer.WriteBigEndian(purposeCount);
                }

                _aadTemplate = ms.ToArray();
            }