<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc2629 version  -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
]>


<rfc ipr="noDerivativesTrust200902" docName="draft-josefsson-xxhash-00" category="info" submissionType="independent" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="xxHash">xxHash fast digest algorithm</title>

    <author fullname="Yann Collet">
      <organization>Meta</organization>
      <address>
        <email>cyan@meta.com</email>
      </address>
    </author>
    <author fullname="Simon Josefsson" role="editor">
      <organization></organization>
      <address>
        <email>simon@josefsson.org</email>
      </address>
    </author>

    <date year="2025" month="October" day="11"/>

    
    
    <keyword>xxHash</keyword> <keyword>XXH</keyword> <keyword>hash</keyword>

    <abstract>


<t>Description of the xxHash fast digest algorithm.</t>



    </abstract>

    <note title="About This Document" removeInRFC="true">
      <t>
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-josefsson-xxhash/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://gitlab.com/jas/ietf-xxhash"/>.</t>
    </note>


  </front>

  <middle>


<section anchor="introduction"><name>Introduction</name>

<t>This document describes the xxHash digest algorithm for both 32-bit and 64-bit variants, named <spanx style="verb">XXH32</spanx> and <spanx style="verb">XXH64</spanx>. The algorithm takes an input a message of arbitrary length and an optional seed value, then produces an output of 32 or 64-bit as "fingerprint" or "digest".</t>

<t>xxHash is primarily designed for speed. It is labeled non-cryptographic, and is not meant to avoid intentional collisions (same digest for 2 different messages), or to prevent producing a message with a predefined digest.</t>

<t>XXH32 is designed to be fast on 32-bit machines.
XXH64 is designed to be fast on 64-bit machines.
Both variants produce different output.
However, a given variant shall produce exactly the same output, irrespective of the cpu / os used. In particular, the result remains identical whatever the endianness and width of the cpu is.</t>

<section anchor="operation-notations"><name>Operation notations</name>

<t>All operations are performed modulo {32,64} bits. Arithmetic overflows are expected.
<spanx style="verb">XXH32</spanx> uses 32-bit modular operations.
<spanx style="verb">XXH64</spanx> and <spanx style="verb">XXH3</spanx> use 64-bit modular operations.
When an operation ingests input or secret as multi-bytes values, it reads it using little-endian convention.</t>

<t><list style="symbols">
  <t><spanx style="verb">+</spanx>: denotes modular addition</t>
  <t><spanx style="verb">-</spanx>: denotes modular subtraction</t>
  <t><spanx style="verb">*</spanx>: denotes modular multiplication
  <list style="symbols">
      <t><strong>Exception:</strong> In <spanx style="verb">XXH3</spanx>, if it is in the form <spanx style="verb">(u128)x * (u128)y</spanx>, it denotes 64-bit by 64-bit normal multiplication into a full 128-bit result.</t>
    </list></t>
  <t><spanx style="verb">X &lt;&lt;&lt; s</spanx>: denotes the value obtained by circularly shifting (rotating) <spanx style="verb">X</spanx> left by <spanx style="verb">s</spanx> bit positions.</t>
  <t><spanx style="verb">X &gt;&gt; s</spanx>: denotes the value obtained by shifting <spanx style="verb">X</spanx> right by s bit positions. Upper <spanx style="verb">s</spanx> bits become <spanx style="verb">0</spanx>.</t>
  <t><spanx style="verb">X &lt;&lt; s</spanx>: denotes the value obtained by shifting <spanx style="verb">X</spanx> left by s bit positions. Lower <spanx style="verb">s</spanx> bits become <spanx style="verb">0</spanx>.</t>
  <t><spanx style="verb">X xor Y</spanx>: denotes the bit-wise XOR of <spanx style="verb">X</spanx> and <spanx style="verb">Y</spanx> (same width).</t>
  <t><spanx style="verb">X | Y</spanx>: denotes the bit-wise OR of <spanx style="verb">X</spanx> and <spanx style="verb">Y</spanx> (same width).</t>
  <t><spanx style="verb">~X</spanx>: denotes the bit-wise negation of <spanx style="verb">X</spanx>.</t>
</list></t>

</section>
</section>
<section anchor="xxh32-algorithm-description"><name>XXH32 Algorithm Description</name>

<section anchor="overview"><name>Overview</name>

<t>We begin by supposing that we have a message of any length <spanx style="verb">L</spanx> as input, and that we wish to find its digest. Here <spanx style="verb">L</spanx> is an arbitrary nonnegative integer; <spanx style="verb">L</spanx> may be zero. The following steps are performed to compute the digest of the message.</t>

<t>The algorithm collect and transform input in <em>stripes</em> of 16 bytes. The transforms are stored inside 4 "accumulators", each one storing an unsigned 32-bit value. Each accumulator can be processed independently in parallel, speeding up processing for cpu with multiple execution units.</t>

<t>The algorithm uses 32-bits addition, multiplication, rotate, shift and xor operations. Many operations require some 32-bits prime number constants, all defined below:</t>

<figure><sourcecode type="c"><![CDATA[
  // 0b10011110001101110111100110110001
  static const u32 PRIME32_1 = 0x9E3779B1U;
  // 0b10000101111010111100101001110111
  static const u32 PRIME32_2 = 0x85EBCA77U;
  // 0b11000010101100101010111000111101
  static const u32 PRIME32_3 = 0xC2B2AE3DU;
  // 0b00100111110101001110101100101111
  static const u32 PRIME32_4 = 0x27D4EB2FU;
  // 0b00010110010101100110011110110001
  static const u32 PRIME32_5 = 0x165667B1U;
]]></sourcecode></figure>

<t>These constants are prime numbers, and feature a good mix of bits 1 and 0, neither too regular, nor too dissymmetric. These properties help dispersion capabilities.</t>

<section anchor="step-1-initialize-internal-accumulators"><name>Step 1. Initialize internal accumulators</name>

<t>Each accumulator gets an initial value based on optional <spanx style="verb">seed</spanx> input. Since the <spanx style="verb">seed</spanx> is optional, it can be <spanx style="verb">0</spanx>.</t>

<figure><sourcecode type="c"><![CDATA[
  u32 acc1 = seed + PRIME32_1 + PRIME32_2;
  u32 acc2 = seed + PRIME32_2;
  u32 acc3 = seed + 0;
  u32 acc4 = seed - PRIME32_1;
]]></sourcecode></figure>

<section anchor="special-case-input-is-less-than-16-bytes"><name>Special case: input is less than 16 bytes</name>

<t>When the input is too small (&lt; 16 bytes), the algorithm will not process any stripes. Consequently, it will not make use of parallel accumulators.</t>

<t>In this case, a simplified initialization is performed, using a single accumulator:</t>

<figure><sourcecode type="c"><![CDATA[
  u32 acc  = seed + PRIME32_5;
]]></sourcecode></figure>

<t>The algorithm then proceeds directly to step 4.</t>

</section>
</section>
<section anchor="step-2-process-stripes"><name>Step 2. Process stripes</name>

<t>A stripe is a contiguous segment of 16 bytes.
It is evenly divided into 4 <em>lanes</em>, of 4 bytes each.
The first lane is used to update accumulator 1, the second lane is used to update accumulator 2, and so on.</t>

<t>Each lane read its associated 32-bit value using <strong>little-endian</strong> convention.</t>

<t>For each {lane, accumulator}, the update process is called a <em>round</em>, and applies the following formula:</t>

<figure><sourcecode type="c"><![CDATA[
  accN = accN + (laneN * PRIME32_2);
  accN = accN <<< 13;
  accN = accN * PRIME32_1;
]]></sourcecode></figure>

<t>This shuffles the bits so that any bit from input <em>lane</em> impacts several bits in output <em>accumulator</em>. All operations are performed modulo 2^32.</t>

<t>Input is consumed one full stripe at a time. Step 2 is looped as many times as necessary to consume the whole input, except for the last remaining bytes which cannot form a stripe (&lt; 16 bytes).
When that happens, move to step 3.</t>

</section>
<section anchor="step-3-accumulator-convergence"><name>Step 3. Accumulator convergence</name>

<t>All 4 lane accumulators from the previous steps are merged to produce a single remaining accumulator of the same width (32-bit). The associated formula is as follows:</t>

<figure><sourcecode type="c"><![CDATA[
  acc = (acc1 <<< 1) + (acc2 <<< 7) + (acc3 <<< 12) + (acc4 <<< 18);
]]></sourcecode></figure>

</section>
<section anchor="step-4-add-input-length"><name>Step 4. Add input length</name>

<t>The input total length is presumed known at this stage. This step is just about adding the length to accumulator, so that it participates to final mixing.</t>

<figure><sourcecode type="c"><![CDATA[
  acc = acc + (u32)inputLength;
]]></sourcecode></figure>

<t>Note that, if input length is so large that it requires more than 32-bits, only the lower 32-bits are added to the accumulator.</t>

</section>
<section anchor="step-5-consume-remaining-input"><name>Step 5. Consume remaining input</name>

<t>There may be up to 15 bytes remaining to consume from the input.
The final stage will digest them according to following pseudo-code:</t>

<figure><sourcecode type="c"><![CDATA[
  while (remainingLength >= 4) {
      lane = read_32bit_little_endian(input_ptr);
      acc = acc + lane * PRIME32_3;
      acc = (acc <<< 17) * PRIME32_4;
      input_ptr += 4; remainingLength -= 4;
  }

  while (remainingLength >= 1) {
      lane = read_byte(input_ptr);
      acc = acc + lane * PRIME32_5;
      acc = (acc <<< 11) * PRIME32_1;
      input_ptr += 1; remainingLength -= 1;
  }
]]></sourcecode></figure>

<t>This process ensures that all input bytes are present in the final mix.</t>

</section>
<section anchor="step-6-final-mix-avalanche"><name>Step 6. Final mix (avalanche)</name>

<t>The final mix ensures that all input bits have a chance to impact any bit in the output digest, resulting in an unbiased distribution. This is also called avalanche effect.</t>

<figure><sourcecode type="c"><![CDATA[
  acc = acc xor (acc >> 15);
  acc = acc * PRIME32_2;
  acc = acc xor (acc >> 13);
  acc = acc * PRIME32_3;
  acc = acc xor (acc >> 16);
]]></sourcecode></figure>

</section>
<section anchor="step-7-output"><name>Step 7. Output</name>

<t>The <spanx style="verb">XXH32()</spanx> function produces an unsigned 32-bit value as output.</t>

<t>For systems which require to store and/or display the result in binary or hexadecimal format, the canonical format is defined to reproduce the same value as the natural decimal format, hence follows <strong>big-endian</strong> convention (most significant byte first).</t>

</section>
</section>
</section>
<section anchor="xxh64-algorithm-description"><name>XXH64 Algorithm Description</name>

<section anchor="overview-1"><name>Overview</name>

<t><spanx style="verb">XXH64</spanx>'s algorithm structure is very similar to <spanx style="verb">XXH32</spanx> one. The major difference is that <spanx style="verb">XXH64</spanx> uses 64-bit arithmetic, speeding up memory transfer for 64-bit compliant systems, but also relying on cpu capability to efficiently perform 64-bit operations.</t>

<t>The algorithm collects and transforms input in <em>stripes</em> of 32 bytes. The transforms are stored inside 4 "accumulators", each one storing an unsigned 64-bit value. Each accumulator can be processed independently in parallel, speeding up processing for cpu with multiple execution units.</t>

<t>The algorithm uses 64-bit addition, multiplication, rotate, shift and xor operations. Many operations require some 64-bit prime number constants, all defined below:</t>

<figure><sourcecode type="c"><![CDATA[
  // 0b1001111000110111011110011011000110000101111010111100101010000111
  static const u64 PRIME64_1 = 0x9E3779B185EBCA87ULL;
  // 0b1100001010110010101011100011110100100111110101001110101101001111
  static const u64 PRIME64_2 = 0xC2B2AE3D27D4EB4FULL;
  // 0b0001011001010110011001111011000110011110001101110111100111111001
  static const u64 PRIME64_3 = 0x165667B19E3779F9ULL;
  // 0b1000010111101011110010100111011111000010101100101010111001100011
  static const u64 PRIME64_4 = 0x85EBCA77C2B2AE63ULL;
  // 0b0010011111010100111010110010111100010110010101100110011111000101
  static const u64 PRIME64_5 = 0x27D4EB2F165667C5ULL;
]]></sourcecode></figure>

<t>These constants are prime numbers, and feature a good mix of bits 1 and 0, neither too regular, nor too dissymmetric. These properties help dispersion capabilities.</t>

<section anchor="step-1-initialize-internal-accumulators-1"><name>Step 1. Initialize internal accumulators</name>

<t>Each accumulator gets an initial value based on optional <spanx style="verb">seed</spanx> input. Since the <spanx style="verb">seed</spanx> is optional, it can be <spanx style="verb">0</spanx>.</t>

<figure><sourcecode type="c"><![CDATA[
  u64 acc1 = seed + PRIME64_1 + PRIME64_2;
  u64 acc2 = seed + PRIME64_2;
  u64 acc3 = seed + 0;
  u64 acc4 = seed - PRIME64_1;
]]></sourcecode></figure>

<section anchor="special-case-input-is-less-than-32-bytes"><name>Special case: input is less than 32 bytes</name>

<t>When the input is too small (&lt; 32 bytes), the algorithm will not process any stripes. Consequently, it will not make use of parallel accumulators.</t>

<t>In this case, a simplified initialization is performed, using a single accumulator:</t>

<figure><sourcecode type="c"><![CDATA[
  u64 acc  = seed + PRIME64_5;
]]></sourcecode></figure>

<t>The algorithm then proceeds directly to step 4.</t>

</section>
</section>
<section anchor="step-2-process-stripes-1"><name>Step 2. Process stripes</name>

<t>A stripe is a contiguous segment of 32 bytes.
It is evenly divided into 4 <em>lanes</em>, of 8 bytes each.
The first lane is used to update accumulator 1, the second lane is used to update accumulator 2, and so on.</t>

<t>Each lane read its associated 64-bit value using <strong>little-endian</strong> convention.</t>

<t>For each {lane, accumulator}, the update process is called a <em>round</em>, and applies the following formula:</t>

<figure><sourcecode type="c"><![CDATA[
round(accN,laneN):
  accN = accN + (laneN * PRIME64_2);
  accN = accN <<< 31;
  return accN * PRIME64_1;
]]></sourcecode></figure>

<t>This shuffles the bits so that any bit from input <em>lane</em> impacts several bits in output <em>accumulator</em>. All operations are performed modulo 2^64.</t>

<t>Input is consumed one full stripe at a time. Step 2 is looped as many times as necessary to consume the whole input, except for the last remaining bytes which cannot form a stripe (&lt; 32 bytes).
When that happens, move to step 3.</t>

</section>
<section anchor="step-3-accumulator-convergence-1"><name>Step 3. Accumulator convergence</name>

<t>All 4 lane accumulators from previous steps are merged to produce a single remaining accumulator of same width (64-bit). The associated formula is as follows.</t>

<t>Note that accumulator convergence is more complex than 32-bit variant, and requires to define another function called <em>mergeAccumulator()</em>:</t>

<figure><sourcecode type="c"><![CDATA[
mergeAccumulator(acc,accN):
  acc  = acc xor round(0, accN);
  acc  = acc * PRIME64_1;
  return acc + PRIME64_4;
]]></sourcecode></figure>

<t>which is then used in the convergence formula:</t>

<figure><sourcecode type="c"><![CDATA[
  acc = (acc1 <<< 1) + (acc2 <<< 7) + (acc3 <<< 12) + (acc4 <<< 18);
  acc = mergeAccumulator(acc, acc1);
  acc = mergeAccumulator(acc, acc2);
  acc = mergeAccumulator(acc, acc3);
  acc = mergeAccumulator(acc, acc4);
]]></sourcecode></figure>

</section>
<section anchor="step-4-add-input-length-1"><name>Step 4. Add input length</name>

<t>The input total length is presumed known at this stage. This step is just about adding the length to accumulator, so that it participates to final mixing.</t>

<figure><sourcecode type="c"><![CDATA[
  acc = acc + inputLength;
]]></sourcecode></figure>

</section>
<section anchor="step-5-consume-remaining-input-1"><name>Step 5. Consume remaining input</name>

<t>There may be up to 31 bytes remaining to consume from the input.
The final stage will digest them according to following pseudo-code:</t>

<figure><sourcecode type="c"><![CDATA[
  while (remainingLength >= 8) {
      lane = read_64bit_little_endian(input_ptr);
      acc = acc xor round(0, lane);
      acc = (acc <<< 27) * PRIME64_1;
      acc = acc + PRIME64_4;
      input_ptr += 8; remainingLength -= 8;
  }

  if (remainingLength >= 4) {
      lane = read_32bit_little_endian(input_ptr);
      acc = acc xor (lane * PRIME64_1);
      acc = (acc <<< 23) * PRIME64_2;
      acc = acc + PRIME64_3;
      input_ptr += 4; remainingLength -= 4;
  }

  while (remainingLength >= 1) {
      lane = read_byte(input_ptr);
      acc = acc xor (lane * PRIME64_5);
      acc = (acc <<< 11) * PRIME64_1;
      input_ptr += 1; remainingLength -= 1;
  }
]]></sourcecode></figure>

<t>This process ensures that all input bytes are present in the final mix.</t>

</section>
<section anchor="step-6-final-mix-avalanche-1"><name>Step 6. Final mix (avalanche)</name>

<t>The final mix ensures that all input bits have a chance to impact any bit in the output digest, resulting in an unbiased distribution. This is also called avalanche effect.</t>

<figure><sourcecode type="c"><![CDATA[
  acc = acc xor (acc >> 33);
  acc = acc * PRIME64_2;
  acc = acc xor (acc >> 29);
  acc = acc * PRIME64_3;
  acc = acc xor (acc >> 32);
]]></sourcecode></figure>

</section>
<section anchor="step-7-output-1"><name>Step 7. Output</name>

<t>The <spanx style="verb">XXH64()</spanx> function produces an unsigned 64-bit value as output.</t>

<t>For systems which require to store and/or display the result in binary or hexadecimal format, the canonical format is defined to reproduce the same value as the natural decimal format, hence follows <strong>big-endian</strong> convention (most significant byte first).</t>

</section>
</section>
</section>
<section anchor="xxh3-algorithm-overview"><name>XXH3 Algorithm Overview</name>

<t>XXH3 comes in two different versions: XXH3-64 and XXH3-128 (or XXH128), producing 64 and 128 bits of output, respectively.</t>

<t>XXH3 uses different algorithms for small (0-16 bytes), medium (17-240 bytes), and large (241+ bytes) inputs. The algorithms for small and medium inputs are optimized for performance. The three algorithms are described in the following sections.</t>

<t>Many operations require some 64-bit prime number constants, which are mostly the same constants used in XXH32 and XXH64, all defined below:</t>

<figure><sourcecode type="c"><![CDATA[
// 0b10011110001101110111100110110001
static const u64 PRIME32_1 = 0x9E3779B1U;
// 0b10000101111010111100101001110111
static const u64 PRIME32_2 = 0x85EBCA77U;
// 0b11000010101100101010111000111101
static const u64 PRIME32_3 = 0xC2B2AE3DU;
// 0b1001111000110111011110011011000110000101111010111100101010000111
static const u64 PRIME64_1 = 0x9E3779B185EBCA87ULL;
// 0b1100001010110010101011100011110100100111110101001110101101001111
static const u64 PRIME64_2 = 0xC2B2AE3D27D4EB4FULL;
// 0b0001011001010110011001111011000110011110001101110111100111111001
static const u64 PRIME64_3 = 0x165667B19E3779F9ULL;
// 0b1000010111101011110010100111011111000010101100101010111001100011
static const u64 PRIME64_4 = 0x85EBCA77C2B2AE63ULL;
// 0b0010011111010100111010110010111100010110010101100110011111000101
static const u64 PRIME64_5 = 0x27D4EB2F165667C5ULL;
// 0b0001011001010110011001111001000110011110001101110111100111111001
static const u64 PRIME_MX1 = 0x165667919E3779F9ULL;
// 0b1001111110110010000111000110010100011110100110001101111100100101
static const u64 PRIME_MX2 = 0x9FB21C651E98DF25ULL;
]]></sourcecode></figure>

<t>The <spanx style="verb">XXH3_64bits()</spanx> function produces an unsigned 64-bit value.
The <spanx style="verb">XXH3_128bits()</spanx> function produces a <spanx style="verb">XXH128_hash_t</spanx> struct containing <spanx style="verb">low64</spanx> and <spanx style="verb">high64</spanx> - the lower and higher 64-bit half values of the result, respectively.</t>

<t>For systems requiring storing and/or displaying the result in binary or hexadecimal format, the canonical format is defined to reproduce the same value as the natural decimal format, hence following <strong>big-endian</strong> convention (most significant byte first).</t>

<section anchor="seed-and-secret"><name>Seed and Secret</name>

<t>XXH3 provides seeded hashing by introducing two configurable constants used in the hashing process: the seed and the secret. The seed is an unsigned 64-bit value, and the secret is an array of bytes that is at least 136 bytes in size. The default seed is 0, and the default secret is the following 192-byte value:</t>

<figure><sourcecode type="c"><![CDATA[
static const u8 defaultSecret[192] = {
  0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe,
  0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,
  0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb,
  0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,
  0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78,
  0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21,
  0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e,
  0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c,
  0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb,
  0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3,
  0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e,
  0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8,
  0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f,
  0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d,
  0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31,
  0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64,
  0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3,
  0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb,
  0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49,
  0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e,
  0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc,
  0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce,
  0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28,
  0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
};
]]></sourcecode></figure>

<t>The seed and the secret can be optionally specified using the <spanx style="verb">*_withSecret</spanx> and <spanx style="verb">*_withSeed</spanx> versions of the hash function.</t>

<t>The seed and the secret cannot be specified simultaneously (<spanx style="verb">*_withSecretAndSeed</spanx> is actually <spanx style="verb">*_withSeed</spanx> for short and medium inputs &lt;= 240 bytes, and <spanx style="verb">*_withSecret</spanx> for large inputs). When one is specified, the other one uses the default value.
There is one exception though: when input is large (&gt; 240 bytes) and a seed is given, a secret is derived from the seed value and the default secret using the following procedure:</t>

<figure><sourcecode type="c"><![CDATA[
deriveSecret(u64 seed):
  u64 derivedSecret[24] = defaultSecret[0:192];
  for (i = 0; i < 12; i++) {
    derivedSecret[i*2] += seed;
    derivedSecret[i*2+1] -= seed;
  }
  return derivedSecret; // convert to u8[192] (little-endian)
]]></sourcecode></figure>

<t>The derivation treats the secrets as 24 64-bit values. In XXH3 algorithms, the secret is always read similarly by treating a contiguous segment of the array as one or more 32-bit or 64-bit values. <strong>The secret values are always read using little-endian convention</strong>.</t>

<section anchor="final-mixing-step-avalanche"><name>Final Mixing Step (avalanche)</name>

<t>To make sure that all input bits have a chance to impact any bit in the output digest (avalanche effect), the final step of the XXH3 algorithm is usually one of the two fixed operations that mix the bits in a 64-bit value. These operations are denoted <spanx style="verb">avalanche()</spanx> and <spanx style="verb">avalanche_XXH64()</spanx> in the following XXH3 description.</t>

<figure><sourcecode type="c"><![CDATA[
avalanche(u64 x):
  x = x xor (x >> 37);
  x = x * PRIME_MX1;
  x = x xor (x >> 32);
  return x;

avalanche_XXH64(u64 x):
  x = x xor (x >> 33);
  x = x * PRIME64_2;
  x = x xor (x >> 29);
  x = x * PRIME64_3;
  x = x xor (x >> 32);
  return x;
]]></sourcecode></figure>

</section>
</section>
</section>
<section anchor="xxh3-algorithm-description-for-small-inputs"><name>XXH3 Algorithm Description (for small inputs)</name>

<t>The algorithm for small inputs (0-16 bytes of input) is further divided into 4 cases: empty, 1-3 bytes, 4-8 bytes, and 9-16 bytes of input.</t>

<t>The algorithm uses byte-swap operations. The byte-swap operation reverses the byte order in a 32-bit or 64-bit value. It is denoted <spanx style="verb">bswap32</spanx> and <spanx style="verb">bswap64</spanx> for its 32-bit and 64-bit versions, respectively.</t>

<section anchor="empty-input"><name>Empty input</name>

<t>The hash of empty input is calculated from the seed and a segment of the secret:</t>

<figure><sourcecode type="c"><![CDATA[
XXH3_64_empty():
  u64 secretWords[2] = secret[56:72];
  return avalanche_XXH64(seed xor secretWords[0] xor secretWords[1]);

XXH3_128_empty():
  u64 secretWords[4] = secret[64:96];
  return {avalanche_XXH64(seed xor secretWords[0] xor secretWords[1]), // lower half
          avalanche_XXH64(seed xor secretWords[2] xor secretWords[3])}; // higher half
]]></sourcecode></figure>

<section anchor="bytes-of-input"><name>1-3 bytes of input</name>

<t>The algorithm starts from a single 32-bit value combining the input bytes and its length:</t>

<figure><sourcecode type="c"><![CDATA[
u32 combined = (u32)input[inputLength-1] | ((u32)inputLength << 8) |
               ((u32)input[0] << 16) | ((u32)input[inputLength>>1] << 24);
// LSB          8       16           24                    MSB
//  | last byte | length | first byte | middle-or-last byte |
]]></sourcecode></figure>

<t>Then the final output is calculated from the value and the first 8 bytes (XXH3-64) or 16 bytes (XXH3-128) of the secret to produce the final result. The secret here is read as 32-bit values instead of the usual 64-bit values.</t>

<figure><sourcecode type="c"><![CDATA[
XXH3_64_1to3():
  u32 secretWords[2] = secret[0:8];
  u64 value = ((u64)(secretWords[0] xor secretWords[1]) + seed) xor (u64)combined;
  return avalanche_XXH64(value);

XXH3_128_1to3():
  u32 secretWords[4] = secret[0:16];
  u64 low = ((u64)(secretWords[0] xor secretWords[1]) + seed) xor (u64)combined;
  u64 high = ((u64)(secretWords[2] xor secretWords[3]) - seed) xor (u64)(bswap32(combined) <<< 13);
  // note that the bswap32(combined) <<< 13 above is 32-bit rotate
  return {avalanche_XXH64(low), // lower half
          avalanche_XXH64(high)}; // higher half
]]></sourcecode></figure>

<t>Note that the XXH3-64 result is the lower half of XXH3-128 result.</t>

</section>
<section anchor="bytes-of-input-1"><name>4-8 bytes of input</name>

<t>The algorithm starts from reading the first and last 4 bytes of the input as little-endian 32-bit values, and a modified seed:</t>

<figure><sourcecode type="c"><![CDATA[
u32 inputFirst = input[0:4];
u32 inputLast = input[inputLength-4:inputLength];
u64 modifiedSeed = seed xor ((u64)bswap32((u32)lowerHalf(seed)) << 32);
]]></sourcecode></figure>

<t>Again, these values are combined with a segment of the secret to produce the final value.</t>

<figure><sourcecode type="c"><![CDATA[
XXH3_64_4to8():
  u64 secretWords[2] = secret[8:24];
  u64 combined = (u64)inputLast | ((u64)inputFirst << 32);
  u64 value = ((secretWords[0] xor secretWords[1]) - modifiedSeed) xor combined;
  value = value xor (value <<< 49) xor (value <<< 24);
  value = value * PRIME_MX2;
  value = value xor ((value >> 35) + inputLength);
  value = value * PRIME_MX2;
  value = value xor (value >> 28);
  return value;

XXH3_128_4to8():
  u64 secretWords[2] = secret[16:32];
  u64 combined = (u64)inputFirst | ((u64)inputLast << 32);
  u64 value = ((secretWords[0] xor secretWords[1]) + modifiedSeed) xor combined;
  u128 mulResult = (u128)value * (u128)(PRIME64_1 + (inputLength << 2));
  u64 high = higherHalf(mulResult); // mulResult >> 64
  u64 low = lowerHalf(mulResult); // mulResult & 0xFFFFFFFFFFFFFFFF
  high = high + (low << 1);
  low = low xor (high >> 3);
  low = low xor (low >> 35);
  low = low * PRIME_MX2;
  low = low xor (low >> 28);
  high = avalanche(high);
  return {low, high};
]]></sourcecode></figure>

</section>
<section anchor="bytes-of-input-2"><name>9-16 bytes of input</name>

<t>The algorithm starts from reading the first and last 8 bytes of the input as little-endian 64-bit values:</t>

<figure><sourcecode type="c"><![CDATA[
u64 inputFirst = input[0:8];
u64 inputLast = input[inputLength-8:inputLength];
]]></sourcecode></figure>

<t>Once again, these values are combined with a segment of the secret to produce the final value.</t>

<figure><sourcecode type="c"><![CDATA[
XXH3_64_9to16():
  u64 secretWords[4] = secret[24:56];
  u64 low = ((secretWords[0] xor secretWords[1]) + seed) xor inputFirst;
  u64 high = ((secretWords[2] xor secretWords[3]) - seed) xor inputLast;
  u128 mulResult = (u128)low * (u128)high;
  u64 value = inputLength + bswap64(low) + high + (u64)(lowerHalf(mulResult) xor higherHalf(mulResult));
  return avalanche(value);

XXH3_128_9to16():
  u64 secretWords[4] = secret[32:64];
  u64 val1 = ((secretWords[0] xor secretWords[1]) - seed) xor inputFirst xor inputLast;
  u64 val2 = ((secretWords[2] xor secretWords[3]) + seed) xor inputLast;
  u128 mulResult = (u128)val1 * (u128)PRIME64_1;
  u64 low = lowerHalf(mulResult) + ((u64)(inputLength - 1) << 54);
  u64 high = higherHalf(mulResult) + ((u64)higherHalf(val2) << 32) + (u64)lowerHalf(val2) * PRIME32_2;
  // the above line can also be simplified to higherHalf(mulResult) + val2 + (u64)lowerHalf(val2) * (PRIME32_2 - 1);
  low = low xor bswap64(high);
  // the following three lines are in fact a 128x64 -> 128 multiplication ({low,high} = (u128){low,high} * PRIME64_2)
  u128 mulResult2 = (u128)low * (u128)PRIME64_2;
  low = lowerHalf(mulResult2);
  high = higherHalf(mulResult2) + high * PRIME64_2;
  return {avalanche(low), // lower half
          avalanche(high)}; // higher half
]]></sourcecode></figure>

</section>
</section>
</section>
<section anchor="xxh3-algorithm-description-for-medium-inputs"><name>XXH3 Algorithm Description (for medium inputs)</name>

<t>This algorithm is used for medium inputs (17-240 bytes of input). Its internal hash state is stored inside 1 (XXH3-64) or 2 (XXH3-128) "accumulators", each storing an unsigned 64-bit value.</t>

<section anchor="step-1-initialize-internal-accumulators-2"><name>Step 1. Initialize internal accumulators</name>

<t>The accumulator(s) are initialized based on the input length.</t>

<figure><sourcecode type="c"><![CDATA[
// For XXH3-64
u64 acc = inputLength * PRIME64_1;

// For XXH3-128
u64 acc[2] = {inputLength * PRIME64_1, 0};
]]></sourcecode></figure>

</section>
<section anchor="step-2-process-the-input"><name>Step 2. Process the input</name>

<t>This step is further divided into two cases: one for 17-128 bytes of input, and one for 129-240 bytes of input.</t>

<section anchor="mixing-operation"><name>Mixing operation</name>

<t>This step uses a mixing operation that mixes a 16-byte segment of data, a 16-byte segment of secret and the seed into a 64-bit value as a building block. This operation treat the segment of data and secret as little-endian 64-bit values.</t>

<figure><sourcecode type="c"><![CDATA[
mixStep(u8 data[16], size secretOffset, u64 seed):
  u64 dataWords[2] = data[0:16];
  u64 secretWords[2] = secret[secretOffset:secretOffset+16];
  u128 mulResult = (u128)(dataWords[0] xor (secretWords[0] + seed)) *
                   (u128)(dataWords[1] xor (secretWords[1] - seed));
  return lowerHalf(mulResult) xor higherHalf(mulResult);
]]></sourcecode></figure>

<t>The mixing operation is always invoked in groups of two in XXH3-128, where two 16-byte segments of data are mixed with a 32-byte segment of secret, and the accumulators are updated accordingly.</t>

<figure><sourcecode type="c"><![CDATA[
mixTwoChunks(u8 data1[16], u8 data2[16], size secretOffset, u64 seed):
  u64 dataWords1[2] = data1[0:16]; // again, little-endian conversion
  u64 dataWords2[2] = data2[0:16];
  acc[0] = acc[0] + mixStep(data1, secretOffset, seed);
  acc[1] = acc[1] + mixStep(data2, secretOffset + 16, seed);
  acc[0] = acc[0] xor (dataWords2[0] + dataWords2[1]);
  acc[1] = acc[1] xor (dataWords1[0] + dataWords1[1]);
]]></sourcecode></figure>

<t>The input is split into several 16-byte chunks and mixed, and the result is added to the accumulator(s).</t>

</section>
<section anchor="bytes-of-input-3"><name>17-128 bytes of input</name>

<t>The input is read as <em>N</em> 16-byte chunks starting from the beginning and <em>N</em> chunks starting from the end, where <em>N</em> is the smallest number that these 2<em>N</em> chunks cover the whole input. These chunks are paired up and mixed, and the results are accumulated to the accumulator(s).</t>

<figure><sourcecode type="c"><![CDATA[
// the loop variable `i` should be signed to avoid underflow in implementation
processInput_XXH3_64_17to128():
  u64 numRounds = ((inputLength - 1) >> 5) + 1;
  for (i = numRounds - 1; i >= 0; i--) {
    size offsetStart = i*16;
    size offsetEnd = inputLength - i*16 - 16;
    acc += mixStep(input[offsetStart:offsetStart+16], i*32, seed);
    acc += mixStep(input[offsetEnd:offsetEnd+16], i*32+16, seed);
  }

processInput_XXH3_128_17to128():
  u64 numRounds = ((inputLength - 1) >> 5) + 1;
  for (i = numRounds - 1; i >= 0; i--) {
    size offsetStart = i*16;
    size offsetEnd = inputLength - i*16 - 16;
    mixTwoChunks(input[offsetStart:offsetStart+16], input[offsetEnd:offsetEnd+16], i*32, seed);
  }
]]></sourcecode></figure>

</section>
<section anchor="bytes-of-input-4"><name>129-240 bytes of input</name>

<t>The input is split into 16-byte (XXH3-64) or 32-byte (XXH3-128) chunks. The first 128 bytes are first mixed chunk by chunk, followed by an intermediate avalanche operation. Then the remaining full chunks are processed, and finally the last 16/32 bytes are treated as a chunk to process.</t>

<figure><sourcecode type="c"><![CDATA[
processInput_XXH3_64_129to240():
  u64 numChunks = inputLength >> 4;
  for (i = 0; i < 8; i++) {
    acc += mixStep(input[i*16:i*16+16], i*16, seed);
  }
  acc = avalanche(acc);
  for (i = 8; i < numChunks; i++) {
    acc += mixStep(input[i*16:i*16+16], (i-8)*16 + 3, seed);
  }
  acc += mixStep(input[inputLength-16:inputLength], 119, seed);

processInput_XXH3_128_129to240():
  u64 numChunks = inputLength >> 5;
  for (i = 0; i < 4; i++) {
    mixTwoChunks(input[i*32:i*32+16], input[i*32+16:i*32+32], i*32, seed);
  }
  acc[0] = avalanche(acc[0]);
  acc[1] = avalanche(acc[1]);
  for (i = 4; i < numChunks; i++) {
    mixTwoChunks(input[i*32:i*32+16], input[i*32+16:i*32+32], (i-4)*32 + 3, seed);
  }
  // note that the half-chunk order and the seed is different here
  mixTwoChunks(input[inputLength-16:inputLength], input[inputLength-32:inputLength-16], 103, (u64)0 - seed);
]]></sourcecode></figure>

</section>
</section>
<section anchor="step-3-finalization"><name>Step 3. Finalization</name>

<t>The final result is extracted from the accumulator(s).</t>

<figure><sourcecode type="c"><![CDATA[
XXH3_64_17to240():
  return avalanche(acc);

XXH3_128_17to240():
  u64 low = acc[0] + acc[1];
  u64 high = (acc[0] * PRIME64_1) + (acc[1] * PRIME64_4) + (((u64)inputLength - seed) * PRIME64_2);
  return {avalanche(low), // lower half
          (u64)0 - avalanche(high)}; // higher half
]]></sourcecode></figure>

</section>
</section>
<section anchor="xxh3-algorithm-description-for-large-inputs"><name>XXH3 Algorithm Description (for large inputs)</name>

<t>This algorithm is used for inputs larger than 240 bytes. The internal hash state is stored inside 8 "accumulators", each one storing an unsigned 64-bit value.</t>

<section anchor="step-1-initialize-internal-accumulators-3"><name>Step 1. Initialize internal accumulators</name>

<t>The accumulators are initialized to fixed constants:</t>

<figure><sourcecode type="c"><![CDATA[
u64 acc[8] = {
  PRIME32_3, PRIME64_1, PRIME64_2, PRIME64_3,
  PRIME64_4, PRIME32_2, PRIME64_5, PRIME32_1};
]]></sourcecode></figure>

</section>
<section anchor="step-2-process-blocks"><name>Step 2. Process blocks</name>

<t>The input is consumed and processed one full block at a time. The size of the block depends on the length of the secret. Specifically, a block consists of several 64-byte stripes. The number of stripes per block is <spanx style="verb">floor((secretLength-64)/8)</spanx> . For the default 192-byte secret, there are 16 stripes in a block, and thus the block size is 1024 bytes.</t>

<figure><sourcecode type="c"><![CDATA[
secretLength = lengthInBytes(secret);    // default 192; at least 136
stripesPerBlock = (secretLength-64) / 8; // default 16; at least 9
blockSize = 64 * stripesPerBlock;        // default 1024; at least 576
]]></sourcecode></figure>

<t>The process of processing a full block is called a <em>round</em>. It consists of the following two sub-steps:</t>

<section anchor="step-2-1-process-stripes-in-the-block"><name>Step 2-1. Process stripes in the block</name>

<t>A stripe is evenly divided into 8 lanes, of 8 bytes each. In an accumulation step, one stripe and a 64-byte contiguous segment of the secret are used to update the accumulators. Each lane reads its associated 64-bit value using little-endian convention.</t>

<t>The accumulation step applies the following procedure:</t>

<figure><sourcecode type="c"><![CDATA[
accumulate(u64 stripe[8], size secretOffset):
  u64 secretWords[8] = secret[secretOffset:secretOffset+64];
  for (i = 0; i < 8; i++) {
    u64 value = stripe[i] xor secretWords[i];
    acc[i xor 1] = acc[i xor 1] + stripe[i];
    acc[i] = acc[i] + (u64)lowerHalf(value) * (u64)higherHalf(value);
                      // (value and 0xFFFFFFFF) * (value >> 32)
  }
]]></sourcecode></figure>

<t>The accumulation step is repeated for all stripes in a block, using different segments of the secret, starting from the first 64 bytes for the first stripe, and offset by 8 bytes for each following round:</t>

<figure><sourcecode type="c"><![CDATA[
round_accumulate(u8 block[blockSize]):
  for (n = 0; n < stripesPerBlock; n++) {
    u64 stripe[8] = block[n*64:n*64+64]; // 64 bytes = 8 u64s
    accumulate(stripe, n*8);
  }
]]></sourcecode></figure>

</section>
<section anchor="step-2-2-scramble-accumulators"><name>Step 2-2. Scramble accumulators</name>

<t>After the accumulation steps are finished for all stripes in the block, the accumulators are scrambled using the last 64 bytes of the secret.</t>

<figure><sourcecode type="c"><![CDATA[
round_scramble():
  u64 secretWords[8] = secret[secretLength-64:secretLength];
  for (i = 0; i < 8; i++) {
    acc[i] = acc[i] xor (acc[i] >> 47);
    acc[i] = acc[i] xor secretWords[i];
    acc[i] = acc[i] * PRIME32_1;
  }
]]></sourcecode></figure>

<t>A round is thus a <spanx style="verb">round_accumulate</spanx> followed by a <spanx style="verb">round_scramble</spanx>:</t>

<figure><sourcecode type="c"><![CDATA[
round(u8 block[blockSize]):
  round_accumulate(block);
  round_scramble();
]]></sourcecode></figure>

<t>Step 2 is looped to consume the input until there are less than or equal to <spanx style="verb">blockSize</spanx> bytes of input left. Note that we leave the last block to the next step even if it is a full block.</t>

</section>
<section anchor="step-3-process-the-last-block-and-the-last-64-bytes"><name>Step 3. Process the last block and the last 64 bytes</name>

<t>Accumulation steps are run for the stripes in the last block, except for the last stripe (whether it is full or not). After that, run a final accumulation step by treating the last 64 bytes as a stripe. Note that the last 64 bytes might overlap with the second-to-last block.</t>

<figure><sourcecode type="c"><![CDATA[
// len is the size of the last block (1 <= len <= blockSize)
lastRound(u8 block[], size len, u64 lastStripe[8]):
  size nFullStripes = (len-1)/64;
  for (n = 0; n < nFullStripes; n++) {
    u64 stripe[8] = block[n*64:n*64+64];
    accumulate(stripe, n * 8);
  }
  accumulate(lastStripe, secretLength - 71);
]]></sourcecode></figure>

</section>
</section>
<section anchor="step-4-finalization"><name>Step 4. Finalization</name>

<t>In the finalization step, a merging procedure is used to extract a single 64-bit value from the accumulators, using an initial seed value and a 64-byte segment of the secret.</t>

<figure><sourcecode type="c"><![CDATA[
finalMerge(u64 initValue, size secretOffset):
  u64 secretWords[8] = secret[secretOffset:secretOffset+64];
  u64 result = initValue;
  for (i = 0; i < 4; i++) {
    // 64-bit by 64-bit multiplication to 128-bit full result
    u128 mulResult = (u128)(acc[i*2] xor secretWords[i*2]) *
                     (u128)(acc[i*2+1] xor secretWords[i*2+1]);
    result = result + (lowerHalf(mulResult) xor higherHalf(mulResult));
                      // (mulResult and 0xFFFFFFFFFFFFFFFF) xor (mulResult >> 64)
  }
  return avalanche(result);
]]></sourcecode></figure>

<t>XXH3-128 runs the merging procedure twice for the two halves of the result, using different secret segments and different initial values derived from the total input length.
The XXH3-64 result is just the lower half of the XXH3-128 result.</t>

<figure><sourcecode type="c"><![CDATA[
XXH3_64_large():
  return finalMerge((u64)inputLength * PRIME64_1, 11);

XXH3_128_large():
  return {finalMerge((u64)inputLength * PRIME64_1, 11), // lower half
          finalMerge(~((u64)inputLength * PRIME64_2), secretLength - 75)}; // higher half
]]></sourcecode></figure>

</section>
</section>
<section anchor="performance-considerations"><name>Performance considerations</name>

<t>The xxHash algorithms are simple and compact to implement. They provide a system independent "fingerprint" or digest of a message of arbitrary length.</t>

<t>The algorithm allows input to be streamed and processed in multiple steps. In such case, an internal buffer is needed to ensure data is presented to the algorithm in full stripes.</t>

<t>On 64-bit systems, the 64-bit variant <spanx style="verb">XXH64</spanx> is generally faster to compute, so it is a recommended variant, even when only 32-bit are needed.</t>

<t>On 32-bit systems though, positions are reversed: <spanx style="verb">XXH64</spanx> performance is reduced, due to its usage of 64-bit arithmetic. <spanx style="verb">XXH32</spanx> becomes a faster variant.</t>

<t>Finally, when vector operations are possible, <spanx style="verb">XXH3</spanx> is likely the faster variant.</t>

</section>
<section anchor="reference-implementation"><name>Reference Implementation</name>

<t>A reference library written in C is available at https://www.xxhash.com <xref target="XXHASH"></xref>.
The web page also links to multiple other implementations written in many different languages.
It links to the <eref target="https://github.com/Cyan4973/xxHash">github project page</eref> where an <eref target="https://github.com/Cyan4973/xxHash/issues">issue board</eref> can be used for further public discussions on the topic.</t>

</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<t>None</t>

</section>
<section anchor="security-considerations"><name>Security Considerations</name>

<t>xxHash is not a cryptographic hash function, and has not been designed
for use in any cryptographic setting.</t>

<t>Implementations has to follow best practices to avoid security
concerns, and users needs to continously re-evaulate implementations
for security vulnerabilities.</t>

</section>
<section anchor="notices"><name>Notices</name>

<t>This document is derived from
https://github.com/Cyan4973/xxHash/blob/dev/doc/xxhash_spec.md commit
d66a9cb6f223b1f15cceebee39bc07ed0bd4ad3d with notice below, with all
changes are tracked at https://gitlab.com/jas/ietf-xxhash using Git.</t>

<figure><sourcecode type="c"><![CDATA[
Version 0.2.0 (29/06/23)

Version changes

v0.2.0: added XXH3 specification, by Adrien Wu
v0.1.1: added a note on rationale for selection of constants
v0.1.0: initial release

Copyright (c) Yann Collet

Permission is granted to copy and distribute this document
for any purpose and without charge,
including translations into other languages
and incorporation into compilations,
provided that the copyright notice and this notice are preserved,
and that any substantive changes or deletions from the original
are clearly marked.
Distribution of this document is unlimited.
]]></sourcecode></figure>

</section>


  </middle>

  <back>


    <references title='Informative References'>

<reference anchor="XXHASH" target="https://xxhash.com/">
  <front>
    <title>xxHash</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>


    </references>



  </back>

<!-- ##markdown-source:
H4sIAMkx6mgAA+09a3PbRpLf+SumnKo7UiIpAgQpio5dZzv2xVeJsxVnd7Pl
8kkgMBSRkAAXDz02cX779WNeAEGKdpK93NWmKjIJzPT09PR7eoaDwaBTJuVa
zsWju7svw2IllmFRiji5lvBPuL7O8qRcbR51wsUilzem2aNOnEVpuIGOcR4u
y8EPWSGXRZGlg7u7FTQYjEadKCwlALifiyRdZp1km89Fmn0h8+QmLJMbWXyX
V0Xpj0YXI79TVItNUhRJlpb3W4ldYrmV8CctOz/K+9ssj+cdMRA8Pn76/vsv
8R8crXMj00rCe5HLbQZYrspyW8zPzq5hcuFiGGWbsx/C4iyR5VIh+KhTlGEa
X4brLIXh7mXR2SZz8a7Mor4osrzMYT7w6X6DH953wqpcZTmiAKMIsazWa57/
38I0FS+y9VqW9CbLr+fia1mG9E1uwmQ9F9F9mP7HBh4iKrsw3iabLBX/pWno
9izw1X8Y8g4BPL3OM1w1GSdllneQvvmGiIpEAMo8e/vlnNqVYX4ty7nQFOHZ
E0X4fW35H3U6g8FAhIuizMOo7HS+kEWUJ9sS1kVkS1GupDjEKEPuv0nieC07
nc/E67TMs7iKEECn890qKQRwTrWBZRUxwV7IwgXbhChgZmKRlSsx9geLBN6k
sZgG9PEmzJMwLWGZkIyxuIKJj/0raoKfp8HVUHwHsC20MvwRxgtT4K9tBcDE
RhZFeC1xcmEOQPMwvxdrmV7DiAgHmmY0/XAtCgmD3ITrSvYR5VRsaW4MMKtK
hAhwxj4wgcYxLMSjZZJey3ybJ2n5CF894kk+AmqpWQNZ4PUG5rO+R7ok1ykM
hVMvtjDoULwusQ3wslzDixTkLMrvt2V2nYfbVQIsi7hCizQrYUpAFFFmIrzJ
EnialkBtnkEEfJqgkBWiWwDNNLlxJB++LJcyx6VRVCl6fcQXQG1B+vEFzxjm
45DuNkFaYZNYwlQBP4YK06MFQbzMnADWQjLzAEupNd2E0Qo6FsMOrdqBDoqq
tsNzZA3NCHpBnJnwsgw7X2a3MIMcCCWuQUxS3UcUq3C9Nh3lHbA9rAFyJBGI
+/dFkucS1iJCGdOSEG0rcSayQlQFrREwRJiXSVStw5w4BNRRUa1L+AeEGWie
oDpLIliI2xUoR8CHWoGaA1RgOgUt420Sw5ycMRKYZ+ezz8Q3W5mHJIqwzPSh
6HSeAfaZfgEAcingG+oDIN4GZrXOxE9jvz8NPgggXTEUz0gUJCAiMkBhuc5u
uZ+8wwnCVDpakmBihVkkhBXmzmDcDqTMSNyYuphVaunxV5QbEio9FxSOAtaO
JRJZXka5JMnZAPGSweK+BCxI7kDUEyRnGBf4oSqQE9dJCTpswFQEFk9vmN9R
GYmr0yuwURIIBjA0QmEMehM1ErwftLwHY0T6TzU5aWlCqG3XsJjUClXpQJyc
vLyLJKmL+ckJMgQTBbBeIr4JzpKWFddHXHUrz5/17sSJ4E/3VzQ/PZYi4+Je
f0pRy68bY6OAg6yTOREAhVoy4w0R++/F559/LgpnDogAkVNkizIkiYUxoiQn
zgXuL1bJskTSdnNitPS6B3CuQC8uCZ2r4gp5SWyzIlHrSgM9fXrEOAY4QsyT
6xWBLBoAxZ+3wCF6JHgrwWRJcTW6MpP62LE09jtDfQW64dBQd8CUf2uMBS0H
twnw+vfffIuyigOQFPztSqlWEuOeAvHzfgBH9P/l+32dU3kdauMMIIDlweiy
1n1mjJ5rxH/6DDwAkGhjEgexffuB1QwohZtE3nY6f4WR5DWwLFKt2iLJgJYl
6C5xK8HzAlVYt6CpsZ1XX12hBJNQs3XS3QDvFWp1MBVgnIDeylqIL0FjU7+E
DKo1x2DueJ4wHlozMKaPqeEmvEfj8A+ZZ2zol2DfsltEsijltqkNYVBYWUBI
EhGV7VOKVk1jiF6K6zGgyQStyFPIw7Qg0WVlBZS5BE8p2criEuF4U0HKipEx
rRmPAjw1iea4ADMgAvEojMARAomD58WjvpBg08DEcUOysKmoUmUFlQ4mDh+K
l9jU6S4iaAuEACsG3khBoxj3GeQ5IcsEdk6u++xRIPxqqzvgN3QB0NiQNVca
Bk2CjCpinCpF49GkjmMgCqNW+w0N1RekRsBrInkkUqJMOXZBfI2849ixXP69
SpBqKIp6APSRgOerzQLkFRQ9uvDo/qEF174HeEjZ7bzT+eWXXyJQy2dnYrTw
RiMP/hvhP/hJfaMP+BDaFajnIgYqKhCfP337+uuXY//SE0/E6O7i5fj8/OK5
9+fHDkzoyZAMwBGPhP8fgukTzNnk5fMXz87PHZga6EhDY3QV+gdhjgnmC/+5
/+zl+AsLc6RwYjQVehr+A3gGBNM//yJ4+dx/5cJ0UWRKKhQfpOeEYHrTyXR6
TvSEhSKuAm1mlpQF11ntgnXIUoZllaPWuc4ycG+SOxQ74g2PGowgFpDAmehZ
ZRlw0TU7Y2nGD2KIMe834PzkSURSWpDUAN+VCXDySq632Aa+o5cMcrUNFwk4
GIlkH+wz8RYUi/DQ24On4Tr5B+ukHN1rV6I7nR0phUBMxR7UVdmrRYgCmzlx
xhUGGlesY4YQHKYRKyz9vDBNyV1Qwk/2SrM9UhyGRualqOXU4Wf72X9sm/q7
Td3XY/t65DwO9OOBHUAt6WdELfAocaoRTHKutSYEMujrgkFIjcrssGeI0zSt
cMGKDQp393PTsMeetVVBtwk0wLhHKTOyQkorDyEyTwtQJaQHiVqm+QZCQfJW
gYO0dqytIFDzNWIEmCD6GDpANA5abZmQhlXrr5ywwhqavnJMsX16DVrUgTpv
LpHYpfvECoUbuqqIM4LGaDRzyZFKRrZOBC5/+kPxJ0UNRQkIFNRHMq8oamVy
XWUVtJDXFI+7BqzDAScGfRiRJjdgs2L2NANxuQ4hWLnsY4+AO5D1GhLGyyQH
kccmCAFDI8Sx2sZgAWri4PFKgrufgeQe0cFnJVBkgpx7ki/qhgEBuRJhUWTA
b2XDYqr1uLyshQqXl/Vg4RUMQUb4JwTad4f+wKgqnDSjEWOsMSAPxWWeVWl8
yRiGW+AS5apZlwSZA8BZDoAB3sDq0z+nooujvoFYwIhf73GjETry3rj59GRH
9CjPUqyq5XJtHcYCCUdOGAoI0maZZ9qToSW9FMDeEPYgS4APCGJL3RKT3Lh0
SHIJgeQRoaf/32OfBEnJNKr4akMKT3LIorgS8RIlaPyhYmHSExnAjykURKTx
NS4y6HhcAPQNyacjkDTP21W2ltrrlBSMkWeD79aYQ+BQHJeD+fZ2lcCKgwpF
lUCuXagxcpXOUKsnQHMFyytTsEgbCJ+N/I1d+RsDcVz3DNksv5agyDlgD5hv
XW3Dq4F4Yq4lIcE0PuwGe8eciOFEhdEtdkKuqCin1gYSossC0VMZMSsoii1J
LRSKXYsakwKjdcmYEP/1kFfJYODXc/11zG99/T3g77OeNQdMmwBoE8eK7zha
YFXHT0pwFdc6iqC8mGSG+THNblNkE9LI4CeAsy6Y0xEs/PtDhZnDRYaJvTjm
UEVqUBgjWwL1jTBgKEhZm2QbUnhFkQlG2ckdgBg2CIF/YYKgvHuE71cEXc3x
TUahRVhywO/MENGDEdeYjTXjKh8Xkwq5ZHOoPF1QranKQq0pODUuNjo/ccy8
QHbQzsllwAlbPhQLyyCEENEaWYpjJwgCAJI3UeJgGzuCZTiTPRKl5SkjWnIC
EP1vjqag2QaRyvJYQbEKcFvIKs4GURZLy18ggMDFXTMwE1Q8fSKCnviJEiuC
peUJ6fnLsQ+UUJr8kjV5lxC73JY5qUz8z10t6m215LjeBpmVeRV42bYKdCsD
W5wCTo9FE9MBPoW2EDwfmo3XPhsk+8ehP9mHvterm4IW9L1W9D1G35oObeBA
y1U5WRDUzrDIzNLMKuyigwOdliarpQXHZcXpULzSzwFbMMhhGq1kr+PwEb7a
NxiyvUo1RCAiEalcNlTGkqnxlZliVuyrJBhzPkfTi4ScbfDwQcUvKLBVOgS1
3xokVBt0jaaQyyU4Wm1qAENYov7TpyBA2lirlyd1L3pPr/HeXuMDvaY7OvV8
KL6huTNROX3b7V2BhU0pjVnbqmjNKqDy18lycoWKe9CrG20hdTxO5g7VFfg5
Z9AKg6V1eO9muzFfBKsKxhner+RdGEMMgHlL3qRiVwosbpZSKpyfcs6fQ/gS
Azdt6IwZM1jikxTjwBCj/jroFdpYbcTA4Vsk123enuhuMlBWSAbw5iPcB0Cm
Zt+1Z7Jo0+BQFm0aHJdFU0nyfy8cZx74r4oolIV5Q8t7DC0STCzD5HX2HVwk
ttab8AciNW9qRNSJxETn3ykNo3ecTHq/nuvZSDAz9yorBSZlaTepMCu25t0Q
XvS+WKARRYHI5foeIWA0vK1sREyuFwgHGE5OMinXT8N0k/7tKbWinlMr9iTV
IEz6nZJqZhvxj5hU06v5e+XUFPzfK6W2Lz3Gz1vSTiBrpPumQSPlxmmy2fmf
v/rq6ETZ3qSXenxodL+WSOPkV/DKHf2h9Nde2qh/D40+rqXHmAavLmpzfyDx
uJc2CqNDowe1xCTTYDquz/1wOnEvbdSbQ6NPaulGpsGLCY3+ryTh75EkBNq3
JAlJAu1nzgJy02aSsPF6J0nIj5tJQhzgo5KE2gQ8mCTUDf//JAmZgs0kIQrL
/1qS0Bjko5OEsz9qktD1AP6QSULqgI7/mz6lB3vzB/KGKJGtecMxRXm5BNWY
1vKGjjT+ofKG0+D/bt7Q6KF/Vt7wN8oZuvlClo0j84VDJ/lVd6LtFLAHZboo
3JB3bsZLl2OxaJjEGCDPTig8zshgm4BWCdUlTdMhWrd3qYVn5xUg1kfW11Ik
nOiaJW1EEv3GhOX1uJxFxZUiRyEHSoiYMyhCg5WvOHDgmNehRdtmwK/Ns2og
rfMmS39MI/+YRuNjGgX/L3O/u2nfT826jr0/YNZ11p6nnAYfl3WtiRQC6u1J
W/o266rFq5kAdSSsJac5a81pzkxKNln+ntllSsy5GVqcxN65jt25+ofmOm6d
6z8//dw2v8m++TkpaHct/5WC/mekoMd7ksma09p7+Rd7ex1IQY/9Y1LQ0+Dh
FHTNA/9XCtpJQXMdp5OA1hllVcPpJJ8z9eYDV9yjgyW51Pg2c2rhbzhhUcwJ
8gBDS3C26LPnz0QXaAVfsBC57xT6q2bYggQB3ERdFG9L4tf3qtqfk5d2TINk
wccZOFIfDZxyHjDwSbURXe984Acj8zikeA/3S7t+4J2q5yySReNchwsc+ymQ
3JbUBCZDNsk/1KkKFW6gKKu08iqXNXjYRx9QMQ6cU14qI53b/jVZVmZs8taB
GdxzBzbLpT1IrupVKzYNDqRoj6t5bE/DtVU8HlfvuBfeTrXjcbWOe+HtVDr+
NgnpT0lH/zbJ6E9JRf82iehPSUP/NknoT0lB/zYJ6E9JPz9A7dGvofbl1997
DrUv2qmtoOjBDIMpsltWs+OrtvvnDCMzh128eu57L6YT7+XF7ItXfj3lztuR
HAAUH2fQh05/sB8HAFAjaHKJpxMvyyu1QUoZSBUaXYGGM2eNVsn1Cr8MnBoZ
fIHPpdnXXIXrpTo4pCui2EHYMV2ut8EKnA8R6E1D19HQweUfzNdAtE5OrLdx
cvJR3ga4cZhgRiK+pQNYyp4DYpjXLSj/DA1wgTgNhple4yWgpwHDLZNrQHSx
bjNgOBHdW7n3c5XcVQOrTC8MzlaZXiT7+avf6GVOjuTgDuKez32pvXl8gykH
zOV5Y+V8IFYFOAU8GqxHiAuqRx1Z8PaVHqbuDngXPh1TY7S0Ha5L3UxDYfK+
gz7vQfowKhvdLWZ9+LuU+Hca4d/xBf71x/g3DPBvsMC/C9mnHufUauTh3xn9
9enJ8pw+05Mwxr9exD1igh4TrCm9kTTGjMa4GNFf6h0v1Bg+jTuyOPDfBbVa
UL8pffaW3CMiHM8JrpxSbxo1ItwigiQn1GbGPWY0xiSkcen9eWx7LJd9gwfM
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
NHuVDaGo0nUCnIxt0bf6H9CZlFLCiwAA

-->

</rfc>

