/// <summary>
        /// Compute the segment HoD.
        /// </summary>
        /// <param name="kp">The Kp data</param>
        /// <param name="hod">The segment HoD</param>
        /// <param name="hashAlgo">The HoHoDk hash algorithm.</param>
        /// <returns>The HoHoDk data</returns>
        public static byte[] GetHoHoDkBytes(byte[] kp, byte[] hod, dwHashAlgoV2_Values hashAlgo)
        {
            HMAC        hohodkAlgo = null;
            List <byte> tempList   = new List <byte>();

            switch (hashAlgo)
            {
            case dwHashAlgoV2_Values.TRUNCATED_SHA512:
                hohodkAlgo = HMAC.Create(ALGOHMACSHA512);
                break;

            default:
                throw new NotImplementedException();
            }

            hohodkAlgo.Key = kp;
            tempList.AddRange(hod);
            tempList.AddRange(Encoding.Unicode.GetBytes(HOHODKAPPENDSTRING));
            var hash = hohodkAlgo.ComputeHash(tempList.ToArray());

            if (hashAlgo == dwHashAlgoV2_Values.TRUNCATED_SHA512)
            {
                hash = hash.Take(32).ToArray();
            }

            return(hash);
        }
 /// <summary>
 /// Get the hash algorithm and hmac algorithm for V2.
 /// </summary>
 /// <param name="hashAlgo">The hash algorithm value</param>
 /// <returns>The hash algorithm and hmac algorithm</returns>
 public static void GetHashAlgorithm(dwHashAlgoV2_Values hashAlgo, out HashAlgorithm hashAlgorithm, out HMAC hmacAlgorithm)
 {
     switch (hashAlgo)
     {
         case dwHashAlgoV2_Values.TRUNCATED_SHA512:
             hashAlgorithm = HashAlgorithm.Create("SHA512");
             hmacAlgorithm = HMAC.Create("HMACSHA512");
             break;
         default:
             throw new NotImplementedException();
     }
 }
        /// <summary>
        /// Get the hash algorithm and hmac algorithm for V2.
        /// </summary>
        /// <param name="hashAlgo">The hash algorithm value</param>
        /// <returns>The hash algorithm and hmac algorithm</returns>
        public static void GetHashAlgorithm(dwHashAlgoV2_Values hashAlgo, out HashAlgorithm hashAlgorithm, out HMAC hmacAlgorithm)
        {
            switch (hashAlgo)
            {
            case dwHashAlgoV2_Values.TRUNCATED_SHA512:
                hashAlgorithm = HashAlgorithm.Create("SHA512");
                hmacAlgorithm = HMAC.Create("HMACSHA512");
                break;

            default:
                throw new NotImplementedException();
            }
        }
        public void VerifyHashGenerationV2(byte[] content, Content_Information_Data_Structure_V2 contentInfoV2)
        {
            dwHashAlgoV2_Values hashAlgo = contentInfoV2.dwHashAlgo;

            HashAlgorithm hashAlgorithm;
            HMAC          hmacAlgorithm;

            PccrcUtility.GetHashAlgorithm(hashAlgo, out hashAlgorithm, out hmacAlgorithm);
            hmacAlgorithm.Key = hashAlgorithm.ComputeHash(testConfig.ServerSecret).Take(32).ToArray();

            // Local calculate SegmentHashOfData and SegmentSecret
            ChunkDescription[] chunkDescription = contentInfoV2.chunks;
            int chunkCount    = contentInfoV2.chunks.Length;
            int segmentOffset = 0;

            for (int chunkIndex = 0; chunkIndex < chunkCount; chunkIndex++)
            {
                SegmentDescriptionV2[] segmentDescription = chunkDescription[chunkIndex].chunkData;
                int segmentCount = segmentDescription.Length;

                for (int segmentIndex = 0; segmentIndex < segmentCount; ++segmentIndex)
                {
                    var segment = content.Skip(segmentOffset).Take((int)(segmentDescription[segmentIndex].cbSegment)).ToArray();

                    segmentOffset += (int)(segmentDescription[segmentIndex].cbSegment);

                    //TRANCATED_SHA_512
                    byte[] hod = hashAlgorithm.ComputeHash(segment).Take(32).ToArray();

                    testSite.Assert.IsTrue(
                        hod.SequenceEqual((chunkDescription[chunkIndex].chunkData)[segmentIndex].SegmentHashOfData),
                        "The local calculated Hod should cosistent with the received value.");

                    byte[] kp = hmacAlgorithm.ComputeHash(hod).Take(32).ToArray();

                    testSite.Assert.IsTrue(
                        kp.SequenceEqual((chunkDescription[chunkIndex].chunkData)[segmentIndex].SegmentSecret),
                        "The local calculated Kp should be consistent with the received value.");
                }
            }
        }
        /// <summary>
        /// Compute the segment HoD.
        /// </summary>
        /// <param name="kp">The Kp data</param>
        /// <param name="hod">The segment HoD</param>
        /// <param name="hashAlgo">The HoHoDk hash algorithm.</param>
        /// <returns>The HoHoDk data</returns>
        public static byte[] GetHoHoDkBytes(byte[] kp, byte[] hod, dwHashAlgoV2_Values hashAlgo)
        {
            HMAC hohodkAlgo = null;
            List<byte> tempList = new List<byte>();
            switch (hashAlgo)
            {
                case dwHashAlgoV2_Values.TRUNCATED_SHA512:
                    hohodkAlgo = HMAC.Create(ALGOHMACSHA512);
                    break;
                default:
                    throw new NotImplementedException();
            }

            hohodkAlgo.Key = kp;
            tempList.AddRange(hod);
            tempList.AddRange(Encoding.Unicode.GetBytes(HOHODKAPPENDSTRING));
            var hash = hohodkAlgo.ComputeHash(tempList.ToArray());

            if (hashAlgo == dwHashAlgoV2_Values.TRUNCATED_SHA512)
                hash = hash.Take(32).ToArray();

            return hash;
        }