Repository: dotnet/aspnetcore
File: src/DataProtection/DataProtection/src/KeyManagement/KeyRingBasedDataProtector.cs (C#)

Code before:
            // Clone since we're about to make modifications.
            // If this is an encryption operation, we only ever encrypt to the default key,
            // so we should replace the existing template. This could occur after the protector
            // has already been created, such as when the underlying key ring has been modified.
            byte[] newTemplate = (byte[])existingTemplate.Clone();
            fixed (byte* pNewTemplate = newTemplate)
            {
                WriteGuid(&pNewTemplate[sizeof(uint)], keyId);
                if (isProtecting)
                {
                    Volatile.Write(ref _aadTemplate, newTemplate);
                }
                return newTemplate;
            }
        }

#if NET10_0_OR_GREATER
        public AdditionalAuthenticatedDataTemplate(string[] purposes)
        {
            // additionalAuthenticatedData := { magicHeader (32-bit) || keyId || purposeCount (32-bit) || (purpose)* }
            // purpose := { utf8ByteCount (7-bit encoded) || utf8Text }

            var keySize = sizeof(Guid);
            int totalPurposeLen = 4 + keySize + 4;

            var purposeLengthsPool = ArrayPool<int>.Shared.Rent(purposes.Length);
            for (int i = 0; i < purposes.Length; i++)
            {
                string purpose = purposes[i];

                int purposeLength = EncodingUtil.SecureUtf8Encoding.GetByteCount(purpose);
                purposeLengthsPool[i] = purposeLength;

                var encoded7BitUIntLength = Measure7BitEncodedUIntLength((uint)purposeLength);
                totalPurposeLen += purposeLength /* length of actual string */ + encoded7BitUIntLength /* length of 'string length' 7-bit encoded int */;
            }

            byte[] targetArr = new byte[totalPurposeLen];
            var targetSpan = targetArr.AsSpan();

            // index 0: magic header
            BinaryPrimitives.WriteUInt32BigEndian(targetSpan.Slice(0), MAGIC_HEADER_V0);
            // index 4: key (skipped for now, will be populated in `GetAadForKey()`)
            // index 4 + keySize: purposeCount
            BinaryPrimitives.WriteInt32BigEndian(targetSpan.Slice(4 + keySize), purposes.Length);

            int index = 4 + keySize + 4; // starting from first purpose
            for (int i = 0; i < purposes.Length; i++)
            {
                string purpose = purposes[i];


Review comment (suggestion):
Did you measure if it was worth renting an array only to prevent an extra call to `SecureUtf8Encoding.GetByteCount` and `Measure7BitEncodedUIntLength`

Code after:
                if (ReadGuid(&pExistingTemplate[sizeof(uint)]) == keyId)
                {
                    return existingTemplate;
                }
            }

            // Clone since we're about to make modifications.
            // If this is an encryption operation, we only ever encrypt to the default key,
            // so we should replace the existing template. This could occur after the protector
            // has already been created, such as when the underlying key ring has been modified.
            byte[] newTemplate = (byte[])existingTemplate.Clone();
            fixed (byte* pNewTemplate = newTemplate)
            {
                WriteGuid(&pNewTemplate[sizeof(uint)], keyId);
                if (isProtecting)
                {
                    Volatile.Write(ref _aadTemplate, newTemplate);
                }
                return newTemplate;
            }
        }

        internal static byte[] BuildAadTemplateBytes(string[] purposes)
        {
            // additionalAuthenticatedData := { magicHeader (32-bit) || keyId || purposeCount (32-bit) || (purpose)* }
            // purpose := { utf8ByteCount (7-bit encoded) || utf8Text }

            var keySize = sizeof(Guid);
            int totalPurposeLen = 4 + keySize + 4;

            int[]? lease = null;
            var targetLength = purposes.Length;
            Span<int> purposeLengthsPool = targetLength <= 32 ? stackalloc int[targetLength] : (lease = ArrayPool<int>.Shared.Rent(targetLength)).AsSpan(0, targetLength);
            for (int i = 0; i < targetLength; i++)
            {
                string purpose = purposes[i];

                int purposeLength = EncodingUtil.SecureUtf8Encoding.GetByteCount(purpose);
                purposeLengthsPool[i] = purposeLength;

                var encoded7BitUIntLength = purposeLength.Measure7BitEncodedUIntLength();
                totalPurposeLen += purposeLength /* length of actual string */ + encoded7BitUIntLength /* length of 'string length' 7-bit encoded int */;
            }

            byte[] targetArr = new byte[totalPurposeLen];
            var targetSpan = targetArr.AsSpan();

            // index 0: magic header
            BinaryPrimitives.WriteUInt32BigEndian(targetSpan.Slice(0), MAGIC_HEADER_V0);
            // index 4: key (skipped for now, will be populated in `GetAadForKey()`)
            // index 4 + keySize: purposeCount