private byte[] BuildSecretAppend(string?apuS, string?apvS) { byte[]? apuToReturn = null; byte[]? apvToReturn = null; byte[] secretAppend; try { int apuLength = apuS == null ? 0 : Utf8.GetMaxByteCount(apuS.Length); Span <byte> apu = apuLength <= Constants.MaxStackallocBytes ? stackalloc byte[apuLength] : (apuToReturn = ArrayPool <byte> .Shared.Rent(apuLength)); if (apuS != null) { apuLength = Utf8.GetBytes(apuS, apu); apu = apu.Slice(0, apuLength); } int apvLength = apvS == null ? 0 : Utf8.GetMaxByteCount(apvS.Length); Span <byte> apv = apvLength <= Constants.MaxStackallocBytes ? stackalloc byte[apvLength] : (apvToReturn = ArrayPool <byte> .Shared.Rent(apvLength)); if (apvS != null) { apvLength = Utf8.GetBytes(apvS, apv); apv = apv.Slice(0, apvLength); } apuLength = Base64Url.GetArraySizeRequiredToDecode(apuLength); apvLength = Base64Url.GetArraySizeRequiredToDecode(apvLength); int algorithmLength = sizeof(int) + _algorithmNameLength; int partyUInfoLength = sizeof(int) + apuLength; int partyVInfoLength = sizeof(int) + apvLength; const int suppPubInfoLength = sizeof(int); int secretAppendLength = algorithmLength + partyUInfoLength + partyVInfoLength + suppPubInfoLength; secretAppend = new byte[secretAppendLength]; var secretAppendSpan = secretAppend.AsSpan(); WriteAlgorithmId(secretAppendSpan); secretAppendSpan = secretAppendSpan.Slice(algorithmLength); WritePartyInfo(apu, apuLength, secretAppendSpan); secretAppendSpan = secretAppendSpan.Slice(partyUInfoLength); WritePartyInfo(apv, apvLength, secretAppendSpan); secretAppendSpan = secretAppendSpan.Slice(partyVInfoLength); BinaryPrimitives.WriteInt32BigEndian(secretAppendSpan, _keySizeInBytes << 3); } finally { if (apuToReturn != null) { ArrayPool <byte> .Shared.Return(apuToReturn); } if (apvToReturn != null) { ArrayPool <byte> .Shared.Return(apvToReturn); } } return(secretAppend); }