| rfc9923.original.xml | rfc9923.xml | |||
|---|---|---|---|---|
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="UTF-8"?> | |||
| <?xml-model href="rfc7991bis.rnc"?> <!-- Required for schema | ||||
| validation and schema-aware editing --> | <!-- pre-edited by ST 08/19/25 --> | |||
| <!-- formatted by ST 08/20/25 and 08/26/25--> | ||||
| <!DOCTYPE rfc [ | <!DOCTYPE rfc [ | |||
| <!ENTITY filename "draft-eastlake-fnv-35"> | ||||
| <!ENTITY nbsp " "> | <!ENTITY nbsp " "> | |||
| <!ENTITY zwsp "​"> | <!ENTITY zwsp "​"> | |||
| <!ENTITY nbhy "‑"> | <!ENTITY nbhy "‑"> | |||
| <!ENTITY wj "⁠"> | <!ENTITY wj "⁠"> | |||
| ]> | ]> | |||
| <!-- <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> --> | ||||
| <!-- This third-party XSLT can be enabled for direct transformations | ||||
| in XML processors, including most browsers --> | ||||
| <!-- If further character entities are required then they should be | ||||
| added to the DOCTYPE above. Use of an external entity file is not | ||||
| recommended. --> | ||||
| <?rfc strict="yes" ?> | ||||
| <!-- give errors regarding ID-nits and DTD validation --> | ||||
| <!-- control the table of contents (ToC) --> | ||||
| <?rfc toc="yes"?> | ||||
| <rfc | <rfc xmlns:xi="http://www.w3.org/2001/XInclude" category="info" docName="draft-e | |||
| xmlns:xi="http://www.w3.org/2001/XInclude" | astlake-fnv-35" number="9923" ipr="trust200902" obsoletes="" updates="" submissi | |||
| category="info" | onType="independent" xml:lang="en" version="3" tocInclude="true" symRefs="true" | |||
| docName="&filename;" | sortRefs="true"> | |||
| ipr="trust200902" | ||||
| obsoletes="" updates="" | ||||
| submissionType="IETF" | ||||
| xml:lang="en" | ||||
| version="3"> | ||||
| <!-- | ||||
| * docName should be the name of your draft * category should be | ||||
| one of std, bcp, info, exp, historic * ipr should be one of | ||||
| trust200902, noModificationTrust200902, noDerivativesTrust200902, | ||||
| pre5378Trust200902 * updates can be an RFC number as NNNN * | ||||
| obsoletes can be an RFC number as NNNN | ||||
| <!-- ____________________FRONT_MATTER____________________ --> | ||||
| <front> | <front> | |||
| <title abbrev="FNV">The FNV Non-Cryptographic Hash | <title abbrev="FNV">The FNV Non-Cryptographic Hash Algorithm</title> | |||
| Algorithm</title> | <seriesInfo name="RFC" value="9923"/> | |||
| <!-- The abbreviated title is required if the full title is | ||||
| longer than 39 characters --> | ||||
| <seriesInfo name="Internet-Draft" | ||||
| value="&filename;"/> | ||||
| <author fullname="Glenn S. Fowler" initials="G." | <author fullname="Glenn S. Fowler" initials="G." surname="Fowler"> | |||
| surname="Fowler"> | ||||
| <organization>Google</organization> | <organization>Google</organization> | |||
| <address> | <address> | |||
| <email>glenn.s.fowler@gmail.com</email> | <email>glenn.s.fowler@gmail.com</email> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <author fullname="Landon Curt Noll" initials="L." | <author fullname="Landon Curt Noll" initials="L." surname="Noll"> | |||
| surname="Noll"> | ||||
| <organization>Cisco Systems</organization> | <organization>Cisco Systems</organization> | |||
| <address> | <address> | |||
| <postal> | <postal> | |||
| <street>170 West Tasman Drive</street> | <street>170 West Tasman Drive</street> | |||
| <city>San Jose</city> | <city>San Jose</city> | |||
| <region>California</region> | <region>California</region> | |||
| <code>95134</code> | <code>95134</code> | |||
| <country>USA</country> | <country>United States of America</country> | |||
| </postal> | </postal> | |||
| <phone>+1-408-424-1102</phone> | <phone>+1-408-424-1102</phone> | |||
| <email>fnv-ietf7-mail@asthe.com</email> | <email>fnv-ietf8-mail@asthe.com</email> | |||
| <uri>http://www.isthe.com/chongo/index.html</uri> | <uri>http://www.isthe.com/chongo/index.html</uri> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <author fullname="Kiem-Phong Vo" initials="K." | <author fullname="Kiem-Phong Vo" initials="K." surname="Vo"> | |||
| surname="Vo"> | ||||
| <organization>Google</organization> | <organization>Google</organization> | |||
| <address> | <address> | |||
| <email>phongvo@gmail.com</email> | <email>phongvo@gmail.com</email> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <author fullname="Donald E. Eastlake 3rd" initials="D." | <author fullname="Donald E. Eastlake 3rd" initials="D." surname="Eastlake 3rd | |||
| surname="Eastlake"> | "> | |||
| <organization>Independent</organization> | <organization>Independent</organization> | |||
| <address> | <address> | |||
| <postal> | <postal> | |||
| <street>2386 Panoramic Circle</street> | <street>2386 Panoramic Circle</street> | |||
| <city>Apopka</city> | <city>Apopka</city> | |||
| <region>Florida</region> | <region>Florida</region> | |||
| <code>32703</code> | <code>32703</code> | |||
| <country>USA</country> | <country>United States of America</country> | |||
| </postal> | </postal> | |||
| <phone>+1-508-333-2270</phone> | <phone>+1-508-333-2270</phone> | |||
| <email>d3e3e3@gmail.com</email> | <email>d3e3e3@gmail.com</email> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <author fullname="Tony Hansen" initials="T." | <author fullname="Tony Hansen" initials="T." surname="Hansen"> | |||
| surname="Hansen"> | ||||
| <organization>AT&T</organization> | <organization>AT&T</organization> | |||
| <address> | <address> | |||
| <postal> | <postal> | |||
| <street>200 Laurel Avenue South</street> | <street>200 Laurel Avenue South</street> | |||
| <city>Middletown</city> | <city>Middletown</city> | |||
| <region>New Jersey</region> | <region>New Jersey</region> | |||
| <code>07748</code> | <code>07748</code> | |||
| <country>USA</country> | <country>United States of America</country> | |||
| </postal> | </postal> | |||
| <email>tony@att.com</email> | <email>tony@att.com</email> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <date year="2025" month="6" day="6"/> | <date year="2025" month="December"/> | |||
| <area/> | ||||
| <workgroup>Network Working Group</workgroup> | ||||
| <!-- "Internet Engineering Task Force" is fine for individual | ||||
| submissions. If this element is not present, the default is | ||||
| "Network Working Group", which is used by the RFC Editor as a | ||||
| nod to the history of the RFC Series. --> | ||||
| <keyword></keyword> | <!-- [rfced] Please insert any keywords (beyond those that appear in the | |||
| <!-- Multiple keywords are allowed. Keywords are incorporated | title) for use on <https://www.rfc-editor.org/search>. --> | |||
| into HTML output files for use by search engines. --> | ||||
| <abstract> | <abstract> | |||
| <t>FNV (Fowler/Noll/Vo) is a fast, non-cryptographic hash algorithm | <t>FNV (Fowler/Noll/Vo) is a fast, non-cryptographic hash algorithm | |||
| with good dispersion that has been widely used and is referenced in a | with good dispersion that has been widely used and is referenced in a | |||
| number of standards documents. The purpose of this document is to | number of standards documents. The purpose of this document is to | |||
| make information on FNV and open-source code performing all | make information on FNV and open-source code performing all | |||
| specified sizes of FNV conveniently available to the Internet | specified sizes of FNV conveniently available to the Internet | |||
| community.</t> | community.</t> | |||
| </abstract> | </abstract> | |||
| </front> | </front> | |||
| <!-- ____________________MIDDLE_MATTER____________________ --> | ||||
| <middle> | <middle> | |||
| <section> <!-- 1. --> | <section> | |||
| <name>Introduction</name> | <name>Introduction</name> | |||
| <t>FNV (Fowler/Noll/Vo) hashes are designed to be fast and have a | <t>FNV (Fowler/Noll/Vo) hashes are designed to be fast and have a | |||
| small code footprint. Their good dispersion makes them particularly | small code footprint. Their good dispersion makes them particularly | |||
| well-suited for hashing nearly identical strings, including URLs, | well suited for hashing nearly identical strings, including URLs, | |||
| hostnames, filenames, text, and IP and MAC addresses. Their speed | hostnames, filenames, text, and IP and Media Access Control (MAC) addresses. T | |||
| allows one to quickly hash lots of data.</t> | heir speed | |||
| allows one to quickly hash lots of data. | ||||
| <!-- [rfced] Abbreviations: | ||||
| a) Per Section 3.6 of RFC 7322 ("RFC Style Guide" | ||||
| (https://www.rfc-editor.org/info/rfc7322)), we expanded "MAC" where | ||||
| first used. Please let us know any concerns. | ||||
| Currently: | ||||
| Their good dispersion makes them particularly well | ||||
| suited for hashing nearly identical strings, including URLs, | ||||
| hostnames, filenames, text, and IP and Media Access Control (MAC) | ||||
| addresses. | ||||
| b) For ease of the reader, should the following abbreviations also be | ||||
| defined? If yes, please provide the correct definitions. | ||||
| MASS | ||||
| IDE (We see "IDE" defined as "Integrated Development Environments" | ||||
| in [fasmlab].) | ||||
| BFD (perhaps "Bidirectional Forwarding Detection"?) --> | ||||
| </t> | ||||
| <t>The purpose of this document is to make information on FNV and | <t>The purpose of this document is to make information on FNV and | |||
| open-source code performing all specified sizes of FNV conveniently | open-source code performing all specified sizes of FNV conveniently | |||
| available to the Internet community. This work is not an Internet | available to the Internet community. This work is not an Internet | |||
| standard and is not the result of consensus of the IETF | Standard and does not have the consensus of the IETF community.</t> | |||
| community.</t> | ||||
| <section anchor="applicability"> <!-- 1.1 --> | <!-- [rfced] [ISE] Questions for the ISE: | |||
| a) Because the original Section 1.1 contains the key | ||||
| word "NOT RECOMMENDED", we (1) prepended the existing Section 1.1 | ||||
| with a new Section 1.1 with the title "Conventions Used in This | ||||
| Document", (2) added the typical boilerplate text, and (3) added | ||||
| entries for RFCs 2119 and 8174 to the Normative References | ||||
| section. Please let us know any concerns. | ||||
| b) May we list the years in the copyright notices within all of the | ||||
| code components (17 instances) as "2016-2025" per guidance from our | ||||
| legal counsel? | ||||
| One example | ||||
| Original: | ||||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | ||||
| * identified as authors of the code. All rights reserved. | ||||
| Perhaps: | ||||
| /* Copyright (c) 2016-2025 IETF Trust and the persons | ||||
| * identified as authors of the code. All rights reserved. | ||||
| --> | ||||
| <section> | ||||
| <name>Conventions Used in This Document</name> | ||||
| <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", | ||||
| "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", | ||||
| "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>", | ||||
| "<bcp14>SHOULD NOT</bcp14>", | ||||
| "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | ||||
| "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document | ||||
| are to be interpreted as described in BCP 14 | ||||
| <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only | ||||
| when, they appear in all capitals, as shown here.</t> | ||||
| </section> | ||||
| <section anchor="applicability"> | ||||
| <name>Applicability of Non-Cryptographic Hashes and FNV</name> | <name>Applicability of Non-Cryptographic Hashes and FNV</name> | |||
| <t>While a general theory of hash function strength and utility is | <t>While a general theory of hash function strength and utility is | |||
| beyond the scope of this document, typical attacks on hash function | beyond the scope of this document, typical attacks on hash functions | |||
| involve one of the following:</t> | involve one of the following:</t> | |||
| <dl> | <dl spacing="normal" newline="false"> | |||
| <dt>Collision:</dt><dd>Finding two data inputs that yield the same | <dt>Collision:</dt><dd>Finding two data inputs that yield the same | |||
| hash output.</dd> | hash output.</dd> | |||
| <dt>First Pre-Image:</dt><dd>Given a hash output, finding a data | <dt>First Pre-Image:</dt><dd>Given a hash output, finding a data | |||
| input that hashes to that output.</dd> | input that hashes to that output.</dd> | |||
| <dt>Second Pre-Image:</dt><dd>Given a first data input, finding a | <dt>Second Pre-Image:</dt><dd>Given a first data input, finding a | |||
| second input that produces the same hash output as the first.</dd> | second input that produces the same hash output as the first.</dd> | |||
| </dl> | </dl> | |||
| <t>For a hash function producing N bits, there necessarily will be | <t>For a hash function producing N bits, there necessarily will be | |||
| collisions among the hashes of more than 2**N distinct inputs. And | collisions among the hashes of more than 2**N distinct inputs. And | |||
| if the hash function can produce hashes covering all 2**N possible | if the hash function can produce hashes covering all 2**N possible | |||
| outputs, then there will exist first and second pre-images. FNV is | outputs, then there will exist first and second pre-images. FNV is | |||
| NOT RECOMMENDED for any application that requires that it be | <bcp14>NOT RECOMMENDED</bcp14> for any application that requires that it be | |||
| computationally infeasible to succeed in one of the above | computationally infeasible for one of the above types of | |||
| attacks.</t> | attacks to succeed. | |||
| <!-- [rfced] Sections 1.1 and subsequent: Do the instances of "2**" | ||||
| in running text (seven, by our count) indicate superscripted numbers? | ||||
| If yes, would you like us to apply the <sup> (superscript) element, | ||||
| even though the artwork and sourcecode will still use the "**"s? | ||||
| Original: | ||||
| ... | ||||
| collisions among the hashes of more than 2**N distinct inputs. And | ||||
| if the hash function can produce hashes covering all 2**N possible | ||||
| ... | ||||
| also a power of 2, in particular n = 2**s. For each such n-bit FNV | ||||
| ... | ||||
| bits in it: one relatively high order one bit, the 2**9 bit, and 4 or | ||||
| ... | ||||
| hash size S such that 2**S > max. Then, calculate the following: | ||||
| ... | ||||
| from a bias against large values with the bias being larger if 2**S | ||||
| ... | ||||
| arithmetic mod 2**HashSize. --> | ||||
| <!-- [rfced] Section 1.1: We found this sentence difficult to | ||||
| follow. We updated it as noted below. If this is incorrect, please | ||||
| provide clarifying text. | ||||
| Original: | ||||
| FNV is | ||||
| NOT RECOMMENDED for any application that requires that it be | ||||
| computationally infeasible to succeed in one of the above attacks. | ||||
| Currently: | ||||
| FNV is | ||||
| NOT RECOMMENDED for any application that requires that it be | ||||
| computationally infeasible for one of the above types of attacks to | ||||
| succeed. --> | ||||
| </t> | ||||
| <t>FNV hashes are generally not applicable for use when faced with | <t>FNV hashes are generally not applicable for use when faced with | |||
| an active adversary in a security scheme where the modest effort | an active adversary in a security scheme where the modest effort | |||
| required to compute FNV hashes (see <xref target="Effort"/>) and | required to compute FNV hashes (see <xref target="Effort"/>) and | |||
| their other noncryptographic characteristics (see <xref | their other non-cryptographic characteristics (see <xref | |||
| target="noncrypto"/>) would make the scheme ineffective against the | target="noncrypto"/>) would make the scheme ineffective against the | |||
| threat model being considered. It is sometimes hard to determine | threat model being considered. It is sometimes hard to determine | |||
| whether or not there are attack vectors via a hash.</t> | whether or not there are attack vectors via a hash.</t> | |||
| <t>For a discussion of adversarial inducement of collisions, see | <t>For a discussion of adversarial inducement of collisions, see | |||
| <xref target="bang"/>.</t> | <xref target="bang"/>.</t> | |||
| </section> | </section> | |||
| <section anchor="Uses"> | <section anchor="Uses"> | |||
| <name>FNV Hash Uses</name> | <name>FNV Hash Uses</name> | |||
| <t>The FNV hash has been widely used. Examples include the | <t>The FNV hash has been widely used. Examples include the | |||
| following:</t> | following:</t> | |||
| <ul> | <ul> | |||
| <li>NFS implementations (e.g., FreeBSD 4.3 <xref | <li>NFS implementations (e.g., FreeBSD 4.3 <xref | |||
| target="FreeBSD"/>, IRIX, Linux (NFS v4)),</li> | target="FreeBSD"/>, IRIX, Linux (NFS v4)),</li> | |||
| <li>text based referenced resources for video games on the PS2, | <li>text-based referenced resources for video games on the PS2, | |||
| Gamecube, and XBOX</li> | Gamecube, and XBOX,</li> | |||
| <li><xref target="Cohesia"/> MASS project server collision | <li>Cohesia MASS project server collision avoidance <xref target="Cohesia" | |||
| avoidance,</li> | />,</li> | |||
| <li>to improve the fragment cache <xref target="FragCache"/> at | <li>to improve the fragment cache <xref target="FragCache"/> at | |||
| X (formerly Twitter),</li> | X (formerly Twitter),</li> | |||
| <li>the flatassembler open source x86 assembler - user-defined | <li>the flatassembler open-source x86 assembler - user-defined | |||
| symbol hashtree <xref target="flatassembler"/>,</li> | symbol hashtree <xref target="flatassembler"/>,</li> | |||
| <li>Used in the speed-sensitive guts of <xref | <li>used in the speed-sensitive guts of <xref | |||
| target="twistylists"/>, an open-source structured namespace | target="twistylists"/>, an open-source structured namespace | |||
| manager,</li> | manager,</li> | |||
| <li>database indexing hashes,</li> | <li>database indexing hashes,</li> | |||
| <li>PowerBASIC <xref target="BASIC"/> inline assembly routine,</li> | <li>PowerBASIC inline assembly routine <xref target="BASIC"/>,</li> | |||
| <li>major web search / indexing engines,</li> | <li>major web search / indexing engines,</li> | |||
| <li>the <xref target="calc"/> calculator,</li> | <li>the "calc" C-style calculator <xref target="calc"/>,</li> | |||
| <li>netnews history file Message-ID lookup functions,</li> | <li>netnews history file Message-ID lookup functions,</li> | |||
| <li><xref target="FRET"/> - a tool to identify file data | <li><xref target="FRET"/> - a tool to identify file data | |||
| structures / helps to understand file formats</li> | structures / help understand file formats,</li> | |||
| <li>anti-spam filters,</li> | <li>anti-spam filters,</li> | |||
| <li>used in an implementation of libketama for use in items | <li>used in an implementation of libketama for use in items | |||
| such as <xref target="memcache"/>,</li> | such as <xref target="memcache"/>,</li> | |||
| <!-- [rfced] Section 1.2: Will "libketama" be clear to readers? | ||||
| Would it be helpful to also cite <https://www.metabrew.com/article/ | ||||
| libketama-consistent-hashing-algo-memcached-clients> ("libketama: | ||||
| Consistent Hashing library for memcached clients") here and list it | ||||
| in the Informative References section? | ||||
| We ask because we don't see "libketama" mentioned on the [memcache] | ||||
| page. | ||||
| Original: | ||||
| * used in an implementation of libketama for use in items such as | ||||
| [memcache], --> | ||||
| <li>a spellchecker programmed in Ada 95,</li> | <li>a spellchecker programmed in Ada 95,</li> | |||
| <li>used in the BSD IDE project <xref target="fasmlab"/>,</li> | <li>used in the BSD IDE project <xref target="fasmlab"/>,</li> | |||
| <li>non-cryptographic file fingerprints,</li> | <li>non-cryptographic file fingerprints,</li> | |||
| <li>used in the deliantra game server for its shared | <li>used in the deliantra game server for its shared | |||
| string implementation <xref target="deliantra"/></li> | string implementation <xref target="deliantra"/>,</li> | |||
| <li>computing Unique IDs in DASM (DTN (Delay Tolerant | <li>computing Unique IDs in DASM (DTN (Delay Tolerant | |||
| Networking) Applications for Symbian Mobile-phones),</li> | Networking) Applications for Symbian Mobile-phones),</li> | |||
| <li>Microsoft's hash_map implementation for VC++ 2005,</li> | <li>Microsoft's hash_map implementation for VC++ 2005,</li> | |||
| <li>the realpath cache in PHP 5.x | <li>the realpath cache in PHP 5.x | |||
| (php-5.2.3/TSRM/tsrm_virtual_cwd.c),</li> | (php-5.2.3/TSRM/tsrm_virtual_cwd.c),</li> | |||
| <li>DNS (Domain Name System) servers,</li> | <li>DNS (Domain Name System) servers,</li> | |||
| <li>used to improve <xref target="Leprechaun"/>, an extremely | <li>used to improve <xref target="Leprechaun"/>, an extremely | |||
| fast word list creator,</li> | fast wordlist creator,</li> | |||
| <li>the <xref target="Vely"/> framework for C language,</li> | <li>the Vely framework <xref target="Vely"/> for the C language,</li> | |||
| <li>Golf language hash tables <xref target="GolfHash"/>,</li> | <li>Golf language hash tables <xref target="GolfHash"/>,</li> | |||
| <li>the libstr logging library <xref target="libstr"/>,</li> | <li>the libsir logging library <xref target="libsir"/>,</li> | |||
| <li>a standard library for modern fortran <xref | ||||
| <!-- [rfced] Section 1.2 and Informative References: As the cited | ||||
| page does not mention "libstr" and shows "Standard Incident Reporter | ||||
| library" at the top of the page, we changed "libstr" to "libsir" | ||||
| accordingly. Please let us know any concerns. | ||||
| Also, for the reference entry, we could not identify "Lederman, R." at | ||||
| <https://github.com/aremmell/libsir>, and we were unsure if "RML aremmell" | ||||
| is the same person. Please let us know if any further updates are needed. | ||||
| Original: | ||||
| * the libstr logging library [libstr], | ||||
| ... | ||||
| [libstr] Lederman, R. and J. Johnson, "libstr logging library", | ||||
| <https://github.com/aremmell/libsir>. | ||||
| Currently: | ||||
| * the libsir logging library [libsir], | ||||
| ... | ||||
| [libsir] Lederman, R. and J. Johnson, "libsir logging library", | ||||
| commit 0ae0173, 3 December 2025, | ||||
| <https://github.com/aremmell/libsir>. --> | ||||
| <li>a standard library for modern Fortran <xref | ||||
| target="Fortran"/>,</li> | target="Fortran"/>,</li> | |||
| <li>to help seeding a pseudo random number generator <xref | <li>to help with seeding a pseudorandom number generator <xref | |||
| target="Vortetty"/>,</li> | target="Vortetty"/>,</li> | |||
| </ul> | </ul> | |||
| <t>and many other uses. It is also referenced in the <xref | <t>and many other uses. It is also referenced in the following standards do | |||
| target="RFC7357"/>, <xref target="RFC7873"/>, and <xref | cuments: <xref target="RFC7357"/>, <xref target="RFC7873"/>, and <xref | |||
| target="IEEE8021Qbp"/> standards documents.</t> | target="IEEE8021Qbp"/>.</t> | |||
| <t>A study has recommended FNV in connection with the IPv6 Flow | <t>A study has recommended FNV in connection with the IPv6 Flow | |||
| Label field <xref target="IPv6flow"/>. Additionally, there was a | Label field <xref target="IPv6flow"/>. Additionally, there was a | |||
| proposal to use FNV for BFD sequence number generation <xref | proposal to use FNV for BFD sequence number generation <xref | |||
| target="BFDseq"/> and a recent article and study on | target="I-D.ietf-bfd-secure-sequence-numbers"/> and a recent article and study | |||
| non-cryptographic hash functions <xref target="NCHF"/>.</t> | on | |||
| non-cryptographic hash functions <xref target="NCHF"/>. | ||||
| <!-- [rfced] Section 1.2: We had trouble following these sentences. | ||||
| If the suggested text is not correct, please clarify. | ||||
| Please note that [BFDseq] underwent significant changes since | ||||
| March 2022 and no longer mentions FNV, so we took that into account | ||||
| in the suggested text. If the suggested text is incorrect, please | ||||
| let us know how this text should be updated. | ||||
| Original: | ||||
| A study has recommended FNV in connection with the IPv6 Flow Label | ||||
| field [IPv6flow]. Additionally, there was a proposal to use FNV for | ||||
| BFD sequence number generation [BFDseq] and a recent article and | ||||
| study on non-cryptographic hash functions [NCHF]. | ||||
| Suggested: | ||||
| [IPv6flow] researched and recommended using 32-bit FNV1a in | ||||
| connection with the IPv6 flow label value. Additionally, | ||||
| [ISAAC-Auth] proposes the use of Indirection, Shift, Accumulate, | ||||
| Add, and Count (ISAAC) as a means of BFD sequence number generation, | ||||
| and [NCHF] discusses criteria for evaluating non-cryptographic hash | ||||
| functions. --> | ||||
| </t> | ||||
| <t>If you use an FNV function in an application, you are kindly | <t>If you use an FNV function in an application, you are kindly | |||
| requested to send an EMail about it to | requested to send an email about it to | |||
| <fnvhash-mail@asthe.com> with "FNV hash function" forming | <fnvhash-mail@asthe.com> with "FNV hash function" forming | |||
| part of the subject line.</t> | part of the subject line. | |||
| <!-- [rfced] Section 1.2: Please confirm that | ||||
| <fnvhash-mail@asthe.com> is still a valid, working email address. | ||||
| Original: | ||||
| If you use an FNV function in an application, you are kindly | ||||
| requested to send an EMail about it to <fnvhash-mail@asthe.com> with | ||||
| "FNV hash function" forming part of the subject line. --> | ||||
| </t> | ||||
| </section> | </section> | |||
| <section anchor="noncrypto"> | <section anchor="noncrypto"> | |||
| <name>Why is FNV Non-Cryptographic?</name> | <name>Why Is FNV Non-Cryptographic?</name> | |||
| <t>A full discussion of cryptographic hash requirements and strength | <t>A full discussion of cryptographic hash requirements and strength | |||
| is beyond the scope of this document. However, here are three | is beyond the scope of this document. However, here are three | |||
| characteristics of FNV that would generally be considered to make it | characteristics of FNV that would generally be considered to make it | |||
| non-cryptographic:</t> | non-cryptographic:</t> | |||
| <ol> | <ol spacing="normal"> | |||
| <li>Sticky State - A cryptographic hash should not have a state in | <li>Sticky State - A cryptographic hash should not have a state in | |||
| which it can stick for a plausible input pattern. But, in the very | which it can stick for a plausible input pattern. But in the very | |||
| unlikely event that the FNV hash variable accidentally becomes zero | unlikely event that the FNV hash variable accidentally becomes zero | |||
| and the input is a sequence of zero bytes, the hash variable will | and the input is a sequence of zero bytes, the hash variable will | |||
| remain at zero until there is a non-zero input byte and the final | remain at zero until there is a non-zero input byte and the final | |||
| hash value will be unaffected by the length of that sequence of zero | hash value will be unaffected by the length of that sequence of zero | |||
| input bytes. For the common case of fixed length input, this would | input bytes. For the common case of fixed-length input, this would | |||
| usually not be significant because the number of non-zero bytes | usually not be significant because the number of non-zero bytes | |||
| would vary inversely with the number of zero bytes and for some | would vary inversely with the number of zero bytes and for some | |||
| types of input, runs of zeros do not occur. Furthermore, the use of | types of input, runs of zeros do not occur. Furthermore, the use of | |||
| a different offset_basis or the inclusion of even a little | a different offset_basis or the inclusion of even a little | |||
| unpredictable input may be sufficient, under some circumstances, to | unpredictable input may be sufficient, under some circumstances, to | |||
| stop an adversary from inducing a zero hash variable (see <xref | stop an adversary from inducing a zero hash variable (see <xref | |||
| target="bang"/>).</li> | target="bang"/>).</li> | |||
| <li>Diffusion - Every output bit of a cryptographic hash should be | <li>Diffusion - Every output bit of a cryptographic hash should be | |||
| an equally complex function of every input bit. But it is easy to | an equally complex function of every input bit. But it is easy to | |||
| see that the least significant bit of a direct FNV hash is the XOR | see that the least significant bit of a direct FNV hash is the XOR | |||
| of the least significant bits of every input byte and does not | of the least significant bits of every input byte and does not | |||
| depend on any other input bits. While more complex, the second | depend on any other input bits. While more complex, the second | |||
| through seventh least significant bits of an FNV hash have a similar | through seventh least significant bits of an FNV hash have a similar | |||
| weakness; only the top bit of the bottom byte of output, and higher | weakness; only the top bit of the bottom byte of output, and higher-order bits | |||
| order bits, depend on all input bits. If these properties are | , depend on all input bits. If these properties are | |||
| considered a problem, they can be easily fixed by XOR folding (see | considered a problem, they can be easily fixed by XOR folding (see | |||
| <xref target="fold"/>).</li> | <xref target="fold"/>).</li> | |||
| <li>Work Factor - Depending on intended use, it is frequently | <li>Work Factor - Depending on intended use, it is frequently | |||
| desirable that a hash function should be computationally expensive | desirable that a hash function should be computationally expensive | |||
| for general purpose and graphics processors since these may be | for general-purpose and graphics processors, since these may be | |||
| profusely available through elastic cloud services or botnets. This | profusely available through elastic cloud services or botnets. This | |||
| is to slow down testing of possible inputs if the output is known or | is applied to slow down testing of possible inputs if the output is known or | |||
| the like. But FNV is designed to be inexpensive on a general-purpose | the like. But FNV is designed to be inexpensive on a general-purpose | |||
| processor. (See <xref target="Effort"/>.)</li> | processor (see <xref target="Effort"/>).</li> | |||
| </ol> | </ol> | |||
| <t>Nevertheless, none of the above have proven to be a problem in | <t>Nevertheless, none of the above have proven to be a problem in | |||
| actual practice for the many non-cryptographic applications of FNV | actual practice for the many non-cryptographic applications of FNV | |||
| (see <xref target="Uses"/>).</t> | (see <xref target="Uses"/>).</t> | |||
| </section> | </section> | |||
| </section> <!-- end 1. Introduction --> | </section> | |||
| <section> <!-- 2. --> | <section> | |||
| <name>FNV Basics</name> | <name>FNV Basics</name> | |||
| <t>This document focuses on the FNV-1a function whose pseudo-code is | <t>This document focuses on the FNV-1a function, whose pseudocode is | |||
| as follows:</t> | as follows:</t> | |||
| <sourcecode type="pseudocode"> | <!-- [rfced] <sourcecode> entries: Please review the sourcecode-type | |||
| settings in this document, and please refer to | ||||
| <https://www.rfc-editor.org/rpc/wiki/doku.php?id=sourcecode-types> | ||||
| for the list of approved types. Please note that we changed | ||||
| 'type="C"' to 'type="c"' per the sourcecode-types page. | ||||
| Also, please note that "makefile" is not included on the | ||||
| sourcecode-types page. Does the page contain an acceptable | ||||
| substitute that you could use? If not, it's fine to leave the | ||||
| "type" attribute unset. | ||||
| Another option: If the sourcecode-types page does not contain an | ||||
| applicable type, please let us know if you would like us to request | ||||
| that additional sourcecode types (e.g., "makefile") be approved and | ||||
| listed on the sourcecode-types page. (As noted above, it's also fine | ||||
| to leave the "type" attribute unset.) | ||||
| Also, please let us know whether any artwork elements should be | ||||
| marked as sourcecode; if yes, please provide the sourcecode type. --> | ||||
| <sourcecode type="pseudocode"><![CDATA[ | ||||
| hash = offset_basis | hash = offset_basis | |||
| for each octet_of_data to be hashed | for each octet_of_data to be hashed | |||
| hash = hash xor octet_of_data | hash = hash xor octet_of_data | |||
| hash = hash * FNV_Prime mod 2**HashSize | hash = hash * FNV_Prime mod 2**HashSize | |||
| return hash | return hash | |||
| </sourcecode> | ]]></sourcecode> | |||
| <t>In the pseudo-code above, hash is a power-of-two number of bits | <t>In the pseudocode above, hash is a power-of-2 number of bits | |||
| (HashSize is 32, 64, 128, 256, 512, or 1024) and offset_basis and | (HashSize is 32, 64, 128, 256, 512, or 1024), and offset_basis and | |||
| FNV_Prime depend on the size of hash.</t> | FNV_Prime depend on the size of hash.</t> | |||
| <t>The FNV-1 algorithm is the same, including the values of | <t>The FNV-1 algorithm is the same, including the values of | |||
| offset_basis and FNV_Prime, except that the order of the two lines | offset_basis and FNV_Prime, except that the order of the two lines | |||
| with the "xor" and multiply operations are reversed. Operational | with the "xor" and multiply operations is reversed. Operational | |||
| experience indicates better hash dispersion for small amounts of data | experience indicates better hash dispersion for small amounts of data | |||
| with FNV-1a. FNV-0 is the same as FNV-1 but with offset_basis set to | with FNV-1a. FNV-0 is the same as FNV-1 but with offset_basis set to | |||
| zero. FNV-1a is suggested for general use.</t> | zero. FNV-1a is suggested for general use.</t> | |||
| <section> <!-- 2.1 --> | <section> | |||
| <name>FNV Primes</name> | <name>FNV Primes</name> | |||
| <t>The theory behind FNV_Prime's is beyond the scope of this document | <t>The theory behind FNV_Primes is beyond the scope of this document, | |||
| but the basic property to look for is how an FNV_Prime would impact | but the basic property to look for is how an FNV_Prime would impact | |||
| dispersion. Now, consider any n-bit FNV hash where n >= 32 and is also | dispersion. Now, consider any n-bit FNV hash where n >= 32 and is also | |||
| a power of 2, in particular n = 2**s. For each such n-bit FNV hash, an | a power of 2 -- in particular, n = 2**s. For each such n-bit FNV hash, an | |||
| FNV_Prime p is defined as:</t> | FNV_Prime p is defined as follows:</t> | |||
| <ul> | <ul> | |||
| <li><t>When s is an integer and 4 < s < 11, then | <li><t>When s is an integer and 4 < s < 11, | |||
| FNV_Prime is the smallest prime p of the form:</t> | FNV_Prime is the smallest prime p of the form:</t> | |||
| <artwork align="center"> | <artwork align="left"><![CDATA[ 256**int((5 + 2**s)/12) + 2**8 | |||
| 256**int((5 + 2**s)/12) + 2**8 + b | + b | |||
| </artwork> | ]]></artwork> | |||
| </li> | </li> | |||
| <li><t>where b is an integer such that:</t> | <li><t>where b is an integer such that:</t> | |||
| <artwork align="center"> | <artwork align="left"><![CDATA[ 0 < b < 2**8 | |||
| 0 < b < 2**8 | ]]></artwork> | |||
| </artwork> | ||||
| </li> | </li> | |||
| <li><t>The number of one-bits in b is 4 or 5</t></li> | <li><t>The number of one-bits in b is four or five</t></li> | |||
| <li><t>and where</t> | <li><t>and where</t> | |||
| <artwork align="center"> | <artwork align="left"><![CDATA[ ( p mod (2**40 - 2**24 - 1) ) > ( 2**24 + 2 | |||
| ( p mod (2**40 - 2**24 - 1) ) > ( 2**24 + 2**8 + 2**7 ) | **8 + 2**7 ) | |||
| </artwork> | ]]></artwork> | |||
| </li> | </li> | |||
| </ul> | </ul> | |||
| <t>Experimentally, FNV_Primes matching the above constraints tend to | <t>Experimentally, FNV_Primes matching the above constraints tend to | |||
| have better dispersion properties. They improve the polynomial | have better dispersion properties. They improve the polynomial | |||
| feedback characteristic when an FNV_Prime multiplies an intermediate | feedback characteristic when an FNV_Prime multiplies an intermediate | |||
| hash value. As such, the hash values produced are more scattered | hash value. As such, the hash values produced are more scattered | |||
| throughout the n-bit hash space.</t> | throughout the n-bit hash space.</t> | |||
| <t>The case where s < 5 is not considered due to the resulting low | <t>The case where s < 5 is not considered due to the resulting low | |||
| hash quality. Such small hashes can, if desired, be derived from a 32 | hash quality. Such small hashes can, if desired, be derived from a | |||
| bit FNV hash by XOR folding (see <xref target="fold"/>). The case | 32-bit FNV hash by XOR folding (see <xref target="fold"/>). The case | |||
| where s > 10 is not considered because of the doubtful utility of such | where s > 10 is not considered because of the doubtful utility of such | |||
| large FNV hashes and because the criteria for such large FNV_Primes is | large FNV hashes and because the criteria for such large FNV_Primes is | |||
| more complex, due to the sparsity of such large primes, and would | more complex, due to the sparsity of such large primes, and would | |||
| needlessly clutter the criteria given above.</t> | needlessly clutter the criteria given above. | |||
| <t>Per the above constraints, an FNV_Prime should have only 6 or 7 | <!-- [rfced] Section 2.1: Is "criteria" used in the singular here | |||
| one-bits in it: one relatively high order one bit, the 2**9 bit, and 4 | (as currently indicated by "is more complex"), or is it used to | |||
| or 5 one bits in the low order byte. Therefore, some compilers may | indicate more than one criterion (in which case "is more complex" | |||
| should be "are more complex")? | ||||
| Original: | ||||
| The case where s > 10 is | ||||
| not considered because of the doubtful utility of such large FNV | ||||
| hashes and because the criteria for such large FNV_Primes is more | ||||
| complex, due to the sparsity of such large primes, and would | ||||
| needlessly clutter the criteria given above. --> | ||||
| </t> | ||||
| <t>Per the above constraints, an FNV_Prime should have only six or seven | ||||
| one-bits in it: one relatively high-order one bit, the 2**9 bit, and four | ||||
| or five one bits in the low-order byte. Therefore, some compilers may | ||||
| seek to improve the performance of a multiplication with an FNV_Prime | seek to improve the performance of a multiplication with an FNV_Prime | |||
| by replacing the multiplication with shifts and adds. However, the | by replacing the multiplication with shifts and adds. However, the | |||
| performance of this substitution is highly hardware-dependent and | performance of this substitution is highly hardware dependent and | |||
| should be done with care. The selection of FNV_Primes prioritizes the | should be done with care. The selection of FNV_Primes prioritizes the | |||
| quality of the resulting hash function, not compiler optimization | quality of the resulting hash function, not compiler optimization | |||
| considerations.</t> | considerations.</t> | |||
| </section> | </section> | |||
| <section anchor="constoffb"> <!-- 2.2 --> | <section anchor="constoffb"> | |||
| <name>FNV offset_basis</name> | <name>FNV offset_basis</name> | |||
| <t>The offset_basis values for the n-bit FNV-1a algorithms are | <t>The offset_basis values for the n-bit FNV-1a algorithms are | |||
| computed by applying the n-bit FNV-0 algorithm to the following | computed by applying the n-bit FNV-0 algorithm to the following | |||
| 32-octet ASCII <xref target="RFC0020"/> character string:</t> | 32-octet ASCII <xref target="RFC0020"/> character string:</t> | |||
| <artwork align="center" type="ascii-art"> | <artwork align="left"><![CDATA[ chongo <Landon Curt Noll> /\ | |||
| chongo <Landon Curt Noll> /\../\ | ../\ | |||
| </artwork> | ]]></artwork> | |||
| <t>or, in <xref target="C"/> notation, the following string:</t> | <t>or, in C notation <xref target="C"/>, the following string:</t> | |||
| <artwork align="center" type="ascii-art"> | <artwork align="left"><![CDATA[ "chongo <Landon Curt Noll> /\ | |||
| "chongo <Landon Curt Noll> /\\../\\" | \../\\" | |||
| </artwork> | ]]></artwork> | |||
| <t>In the general case, almost any offset_basis would serve as long as | <t>In the general case, almost any offset_basis would serve as long as | |||
| it is non-zero. However, FNV hashes calculated with different | it is non-zero. However, FNV hashes calculated with different | |||
| offset_basis values will not interoperate. The choice of a | offset_basis values will not interoperate. The choice of a | |||
| non-standard offset_basis may be beneficial in some limited | non-standard offset_basis may be beneficial in some limited | |||
| circumstances to defend against attacks that try to induce hash | circumstances to defend against attacks that try to induce hash | |||
| collisions as discussed in <xref target="bang"/>. Any entity that can | collisions as discussed in <xref target="bang"/>. Any entity that can | |||
| observe the FNV hash output, and can cause the null string (the string | observe the FNV hash output, and can cause the null string (the string | |||
| of length zero) to be hashed, will thereby be able to directly observe | of length zero) to be hashed, will thereby be able to directly observe | |||
| the offset_basis which will be the hash output.</t> | the offset_basis which will be the hash output. | |||
| <!-- [rfced] Section 2.2: Is the offset_basis sometimes the hash | ||||
| output, or always? If neither suggestion below is correct, please | ||||
| clarify. | ||||
| Original: | ||||
| Any entity that can observe the FNV hash | ||||
| output, and can cause the null string (the string of length zero) to | ||||
| be hashed, will thereby be able to directly observe the offset_basis | ||||
| which will be the hash output. | ||||
| Suggestion #1 (sometimes): | ||||
| Any entity that can observe the FNV hash | ||||
| output, and can cause the null string (the string of length zero) to | ||||
| be hashed, will thereby be able to directly observe the offset_basis | ||||
| that will be the hash output. | ||||
| Suggestion #2 (always): | ||||
| Any entity that can observe the FNV hash | ||||
| output, and can cause the null string (the string of length zero) to | ||||
| be hashed, will thereby be able to directly observe the | ||||
| offset_basis, which will be the hash output. --> | ||||
| </t> | ||||
| </section> | </section> | |||
| <section anchor="endian"> <!-- 2.3 --> | <section anchor="endian"> | |||
| <name>FNV Endianism</name> | <name>FNV Endianism</name> | |||
| <t>For persistent storage or interoperability between different | <t>For persistent storage or interoperability between different | |||
| hardware platforms, an FNV hash shall be represented in the little | hardware platforms, an FNV hash shall be represented in the little | |||
| endian format <xref target="IEN137"/>. That is, the FNV hash will be | endian format <xref target="IEN137"/>. That is, the FNV hash will be | |||
| stored in an array hash[N] with N bytes such that its integer value | stored in an array hash[N] with N bytes such that its integer value | |||
| can be retrieved as follows:</t> | can be retrieved as follows:</t> | |||
| <sourcecode type="C"> | <sourcecode type="c"><![CDATA[ | |||
| unsigned char hash[N]; | unsigned char hash[N]; | |||
| for ( i = N-1, value = 0; i >= 0; --i ) | for ( i = N-1, value = 0; i >= 0; --i ) | |||
| value = ( value << 8 ) + hash[i]; | value = ( value << 8 ) + hash[i]; | |||
| </sourcecode> | ]]></sourcecode> | |||
| <t>However, when FNV hashes are used in a single process or a group | <t>However, when FNV hashes are used in a single process or a group | |||
| of processes sharing memory on processors with compatible endian-ness, | of processes sharing memory on processors with compatible endianness, | |||
| the natural endian-ness of those processors can be used, as long as it | the natural endianness of those processors can be used, as long as it | |||
| is used consistently, regardless of its type, little, big, or some | is used consistently, regardless of its type -- little, big, or some | |||
| other exotic form.</t> | other exotic form.</t> | |||
| <t>The code provided in Section 6 has FNV hash functions that return a | <t>The code provided in <xref target="sec-cons"/> has FNV hash functions that re turn a | |||
| little endian byte vector for all lengths. Because they are more | little endian byte vector for all lengths. Because they are more | |||
| efficient, the code also provides functions that return FNV hashes as | efficient, the code also provides functions that return FNV hashes as | |||
| 32-bit integers or, where supported, 64-bit integers, for those sizes | 32-bit integers or, where supported, 64-bit integers, for those sizes | |||
| of FNV hash. Such integers are compatible with the same size byte | of FNV hash. Such integers are compatible with the same-size byte | |||
| vectors on little endian computers but use of the functions returning | vectors on little endian computers, but the use of the functions returning | |||
| integers on big endian or other non-little-endian machines will be | integers on big endian or other non-little-endian machines will be | |||
| byte-reversed or otherwise incompatible with the byte vector return | byte-reversed or otherwise incompatible with the byte vector return | |||
| values.</t> | values. | |||
| <!-- [rfced] Section 2.3: We do not see any code provided in | ||||
| Section 6 ("Security Considerations"). Please let us know which | ||||
| section should be cited here. | ||||
| Original: | ||||
| The code provided in Section 6 has FNV hash functions that return a | ||||
| little endian byte vector for all lengths. --> | ||||
| </t> | ||||
| </section> | </section> | |||
| </section> <!-- 2. --> | </section> | |||
| <section anchor="fold"> <!-- 3. --> | <section anchor="fold"> | |||
| <name>Other Hash Sizes and XOR Folding</name> | <name>Other Hash Sizes and XOR Folding</name> | |||
| <t>Many hash uses require a hash that is not one of the FNV sizes for | <t>Many hash uses require a hash that is not one of the FNV sizes for | |||
| which constants are provided in <xref target="const"/>. If a larger | which constants are provided in <xref target="const"/>. If a larger | |||
| hash size is needed, please contact the authors of this document.</t> | hash size is needed, please contact the authors of this document.</t> | |||
| <t>For scenarios where a fixed-size binary field of k bits is desired | <t>For scenarios where a fixed-size binary field of k bits is desired | |||
| with k < 1024 but not among the provided constants in Section 5, | with k < 1024 but not among the constants provided in <xref target="const"/>, | |||
| the recommended approach involves using the smallest FNV hash of size | the recommended approach involves using the smallest FNV hash of size | |||
| S where S > k and employing xor folding, as shown below. The final | S where S > k and employing xor folding, as shown below. The final | |||
| bit masking operation is logically unnecessary if the size of the | bit-masking operation is logically unnecessary if the size of the | |||
| variable k-bit-hash is exactly k bits.</t> | variable k-bit-hash is exactly k bits.</t> | |||
| <sourcecode type="pseudocode"> | <sourcecode type="pseudocode"><![CDATA[ | |||
| temp = FNV_S ( data-to-be-hashed ) | temp = FNV_S ( data-to-be-hashed ) | |||
| k-bit-hash = ( temp xor temp>>k ) bitwise-and ( 2**k - 1 ) | k-bit-hash = ( temp xor temp>>k ) bitwise-and ( 2**k - 1 ) | |||
| </sourcecode> | ]]></sourcecode> | |||
| <t>A somewhat stronger hash may be obtained for exact FNV sizes by | <t>A somewhat stronger hash may be obtained for exact FNV sizes by | |||
| calculating an FNV twice as long as the desired output ( S = 2*k ) and | calculating an FNV twice as long as the desired output ( S = 2*k ) and | |||
| performing such xor data folding using a k equal to the size of the | performing such xor data folding using a k equal to the size of the | |||
| desired output. However, if a much stronger hash is desired, | desired output. However, if a much stronger hash is desired, | |||
| cryptographic algorithms, such as those in <xref target="FIPS202"/> or | cryptographic algorithms, such as those specified in <xref target="FIPS202"/> or | |||
| <xref target="RFC6234"/>, should be used.</t> | <xref target="RFC6234"/>, should be used.</t> | |||
| <t>If it is desired to obtain a hash result that is a value between 0 | <t>If it is desired to obtain a hash result that is a value between 0 | |||
| and max, where max+1 is a not a power of two, simply choose an FNV | and max, where max+1 is not a power of 2, simply choose an FNV | |||
| hash size S such that 2**S > max. Then calculate the following:</t> | hash size S such that 2**S > max. Then, calculate the following:</t> | |||
| <artwork align="center"> | <artwork align="left"><![CDATA[ FNV_S mod ( max+1 ) | |||
| FNV_S mod ( max+1 ) | ]]></artwork> | |||
| </artwork> | ||||
| <t>The resulting remainder will be in the range desired but will | <t>The resulting remainder will be in the range desired but will | |||
| suffer from a bias against large values with the bias being larger if | suffer from a bias against large values, with the bias being larger if | |||
| 2**S is only a little bigger than max. If this bias is acceptable, no | 2**S is only slightly larger than max. If this bias is acceptable, no | |||
| further processing is needed. If this bias is unacceptable, it can be | further processing is needed. If this bias is unacceptable, it can be | |||
| avoided by retrying for certain high values of hash, as follows, | avoided by retrying for certain high values of hash, as follows, | |||
| before applying the mod operation above:</t> | before applying the mod operation above:</t> | |||
| <sourcecode type="pseudocode"> | <sourcecode type="pseudocode"><![CDATA[ | |||
| X = ( int( ( 2**S - 1 ) / ( max+1 ) ) ) * ( max+1 ) | X = ( int( ( 2**S - 1 ) / ( max+1 ) ) ) * ( max+1 ) | |||
| while ( hash >= X ) | while ( hash >= X ) | |||
| hash = ( hash * FNV_Prime ) + offset_basis | hash = ( hash * FNV_Prime ) + offset_basis | |||
| </sourcecode> | ]]></sourcecode> | |||
| </section> <!-- 3 --> | </section> | |||
| <section> <!-- 4. --> | <section anchor="sec-4"> | |||
| <name>Hashing Multiple Values Together</name> | <name>Hashing Multiple Values Together</name> | |||
| <t>Sometimes there are multiple different component values, say three | <t>Sometimes, there are multiple different component values, say three | |||
| strings X, Y, and Z, where a hash over all of them is desired. The | strings X, Y, and Z, where a hash over all of them is desired. The | |||
| simplest thing to do is to concatenate them in a fixed order and | simplest thing to do is to concatenate them in a fixed order and | |||
| compute the hash of that concatenation, as in</t> | compute the hash of that concatenation, as in</t> | |||
| <artwork align="center"> | <artwork align="left"><![CDATA[ hash ( X | Y | Z ) | |||
| hash ( X | Y | Z ) | ]]></artwork> | |||
| </artwork> | ||||
| <t>where the vertical bar character ("|") represents string | <t>where the vertical bar character ("|") represents string | |||
| concatenation. If the components being combined are of variable | concatenation. If the components being combined are of variable | |||
| length, some information is lost by simple concatenation. For example, | length, some information is lost by simple concatenation. For example, | |||
| X = "12" and Y = "345" would not be distinguished from X = "123" and Y | X = "12" and Y = "345" would not be distinguished from X = "123" and Y | |||
| = "45". To preserve that information, each component should be | = "45". To preserve that information, each component should be | |||
| preceded by an encoding of its length, or end with some sequence that | preceded by an encoding of its length or should end with some sequence that | |||
| cannot occur within the component, or some similar technique should be | cannot occur within the component, or some similar technique should be | |||
| used.</t> | used.</t> | |||
| <t>For FNV, the same hash results if X, Y, and Z are actually | <t>For FNV, the same hash results if X, Y, and Z are actually | |||
| concatenated and the FNV hash applied to the resulting string or if | concatenated and the FNV hash applied to the resulting string or if | |||
| FNV is calculated on an initial substring and the result used as the | FNV is calculated on an initial substring and the result used as the | |||
| offset_basis when calculating the FNV hash of the remainder of the | offset_basis when calculating the FNV hash of the remainder of the | |||
| string. This can be done several times. Assuming FNVoffset_basis ( v, | string. This can be done several times. Assuming that FNVoffset_basis ( v, | |||
| w ) is FNV of w using v as the offset_basis, then in the example | w ) is the FNV of w using v as the offset_basis, then in the example | |||
| above, fnvx = FNV ( X ) could be calculated and then fnvxy = | above, fnvx = FNV ( X ) could be calculated and then fnvxy = | |||
| FNVoffset_basis ( fnvx, Y ), and finally fnvxyz = FNVoffset_basis ( | FNVoffset_basis ( fnvx, Y ), and finally fnvxyz = FNVoffset_basis ( | |||
| fnvxy, Z). The resulting fnvxyz would be the same as FNV ( X | Y | Z | fnvxy, Z ). The resulting fnvxyz would be the same as FNV ( X | Y | Z ). | |||
| ).</t> | ||||
| <!-- [rfced] Section 4: We had trouble parsing this sentence - in | ||||
| particular, the "and ... or" relationships. Will this sentence be | ||||
| clear to readers as written? | ||||
| Original: | ||||
| For FNV, the same hash results if X, Y, and Z are actually | ||||
| concatenated and the FNV hash applied to the resulting string or if | ||||
| FNV is calculated on an initial substring and the result used as the | ||||
| offset_basis when calculating the FNV hash of the remainder of the | ||||
| string. | ||||
| Possibly: | ||||
| For FNV, the same hash results if 1) X, Y, and Z are actually | ||||
| concatenated and the FNV hash is applied to the resulting string or | ||||
| 2) FNV is calculated on an initial substring and the result is used | ||||
| as the offset_basis when calculating the FNV hash of the remainder | ||||
| of the string. --> | ||||
| </t> | ||||
| <t>This means that if you have the value of FNV ( X ) and you want to | <t>This means that if you have the value of FNV ( X ) and you want to | |||
| calculate FNV ( X | Y ), you do not need to find X. You can simply | calculate FNV ( X | Y ), you do not need to find X. You can simply | |||
| calculate FNVoffset_basis ( FNV ( X ), Y ) and thereby get FNV ( X |Y | calculate FNVoffset_basis ( FNV ( X ), Y ) and thereby get FNV ( X | Y ).</ | |||
| ).</t> | t> | |||
| <t>Sometimes such a hash needs to be repeatedly calculated and the | <t>Sometimes, such a hash needs to be repeatedly calculated; the | |||
| component values vary but some vary more frequently than others. For | component values vary, but some vary more frequently than others. For | |||
| example, assume some sort of computer network traffic flow ID, such as | example, assume that some sort of computer network traffic flow ID, such as | |||
| the IPv6 flow ID <xref target="RFC6437"/>, is to be calculated for | the IPv6 flow ID <xref target="RFC6437"/>, is to be calculated for | |||
| network packets based on the source and destination IPv6 address and | network packets based on the source and destination IPv6 addresses and | |||
| the Traffic Class <xref target="RFC8200"/>. If the Flow ID is | the Traffic Class <xref target="RFC8200"/>. If the Flow ID is | |||
| calculated in the originating host, the source IPv6 address would | calculated in the originating host, the source IPv6 address would | |||
| likely always be the same or perhaps assume one of a very small number | likely always be the same or would perhaps assume one of a very small number | |||
| of values. By placing this quasi-constant IPv6 source address first in | of values. By placing this quasi-constant IPv6 source address first in | |||
| the string being FNV hashed, FNV ( IPv6source ) could be calculated | the string being FNV-hashed, FNV ( IPv6source ) could be calculated | |||
| and used as the offset_basis for calculating FNV of the IPv6 | and used as the offset_basis for calculating the FNV of the IPv6 | |||
| destination address and Traffic Class for each packet. As a result, | destination address and Traffic Class for each packet. As a result, | |||
| the per packet hash would be over 17 bytes rather than over 33 bytes | the per-packet hash would be over 17 bytes rather than over 33 bytes, | |||
| saving computational resources. The source code in this document | saving computational resources. The source code in this document | |||
| includes functions facilitating the use of a non-standard | includes functions facilitating the use of a non-standard | |||
| offset_basis.</t> | offset_basis. | |||
| <!-- [rfced] Section 4: We only see one mention of the idea of | ||||
| "flow ID" in RFC 6437 ("a stateless method of flow identification and | ||||
| label assignment") but quite a few instances of "Flow Label" and | ||||
| "flow label" (and one instance of "Flow label"). Should "flow ID" | ||||
| and "Flow ID" be "flow label" or "Flow Label" here? | ||||
| Original: | ||||
| For example, assume some sort of computer network traffic flow ID, | ||||
| such as the IPv6 flow ID [RFC6437], is to be calculated for network | ||||
| packets based on the source and destination IPv6 address and the | ||||
| Traffic Class [RFC8200]. If the Flow ID is calculated in the | ||||
| originating host, the source IPv6 address would likely always be the | ||||
| same or perhaps assume one of a very small number of values. --> | ||||
| </t> | ||||
| <t>An alternative method of hashing multiple values is to concatenate | <t>An alternative method of hashing multiple values is to concatenate | |||
| the hashes of those values and then hash the concatenation, this is, | the hashes of those values and then hash the concatenation -- that is, | |||
| compute something like</t> | compute something like</t> | |||
| <artwork align="center"> | <artwork align="left"><![CDATA[ hash ( hash (X) | hash (Y) | has | |||
| hash ( hash(X) | hash (Y) | hash (Z) ) | h (Z) ) | |||
| </artwork> | ]]></artwork> | |||
| <t>This will involve more computation than simply computing the hash | <t>This will involve more computation than simply computing the hash | |||
| of the concatenation of the values and thus, unless parallel | of the concatenation of the values and thus, unless parallel | |||
| computational resources are available, greater latency; however, if | computational resources are available, greater latency; however, if | |||
| parallel computational resources are available and the values being | parallel computational resources are available and the values being | |||
| hashed together are long enough to overcome any initial/final hash | hashed together are long enough to overcome any initial/final hash | |||
| function overhead, which is very small for FNV, latency can be reduced | function overhead, which is very small for FNV, latency can be reduced | |||
| by hashing the concatenation of the hashes of the values.</t> | by hashing the concatenation of the hashes of the values.</t> | |||
| <t>For another example of a similar technique, assume a desire to use | <t>For another example of a similar technique, assume a desire to use | |||
| FNV-N to hash a byte string of length L. Let B = N/8, the number of | FNV-N to hash a byte string of length L. Let B = N/8, the number of | |||
| bytes of FNV-N output. If that string is divided into k successive | bytes of FNV-N output. If that string is divided into k successive | |||
| equal length substrings and assuming, for simplicity, that L is an | substrings of equal length and assuming, for simplicity, that L is an | |||
| integer multiple of k, hashing the substrings and then hashing the | integer multiple of k, hashing the substrings and then hashing the | |||
| concatenation of their hashes will hash a total of L + k*B bytes, | concatenation of their hashes will hash a total of L + k*B bytes, | |||
| clearly more than the initial string size L. However, if sufficient | clearly more than the initial string size L. However, if sufficient | |||
| parallel computational resources are available to hash all the | parallel computational resources are available to hash all the | |||
| substrings simultaneously, the elapsed time can be changed | substrings simultaneously, the elapsed time can be changed | |||
| approximately from on the order of L to on the order of L/k + k*B. For | approximately from on the order of L to on the order of L/k + k*B. For | |||
| sufficiently large L, this parallelization will reduce the elapsed | sufficiently large L, this parallelization will reduce the elapsed | |||
| time to produce the overall hash.</t> | time to produce the overall hash.</t> | |||
| </section> <!-- 4. --> | </section> | |||
| <section anchor="const"> <!-- 5. --> | <section anchor="const"> | |||
| <name>FNV Constants</name> | <name>FNV Constants</name> | |||
| <t>The FNV Primes are as follows:</t> | <t>The FNV Primes are as follows:</t> | |||
| <table> | <table> | |||
| <thead> | <thead> | |||
| <tr><th>Size FNV Prime = Expression</th></tr> | <tr><th>Size FNV Prime = Expression</th></tr> | |||
| <tr><th align="right">= Decimal</th></tr> | <tr><th align="right">= Decimal</th></tr> | |||
| <tr><th align="right">= Hexadecimal</th></tr> | <tr><th align="right">= Hexadecimal</th></tr> | |||
| </thead> | </thead> | |||
| <tbody> | <tbody> | |||
| <tr><td>32-bit FNV_Prime = 2**24 + 2**8 + 0x93</td></tr> | <tr><td>32-bit FNV_Prime = 2**24 + 2**8 + 0x93</td></tr> | |||
| <tr><td align="right">= 16,&zwsp;777,&zwsp;619</td></tr> | <tr><td align="right">= 16,&zwsp;777,&zwsp;619</td></tr> | |||
| skipping to change at line 696 ¶ | skipping to change at line 907 ¶ | |||
| 32E56D5A591028B7 4B29FC4223FDADA1 6C3BF34EDA3674DA 9A21D90000000000 | 32E56D5A591028B7 4B29FC4223FDADA1 6C3BF34EDA3674DA 9A21D90000000000 | |||
| 0000000000000000 0000000000000000 0000000000000000 0000000000000000 | 0000000000000000 0000000000000000 0000000000000000 0000000000000000 | |||
| 0000000000000000 000000000004C6D7 EB6E73802734510A 555F256CC005AE55 | 0000000000000000 000000000004C6D7 EB6E73802734510A 555F256CC005AE55 | |||
| 6BDE8CC9C6A93B21 AFF4B16C71EE90B3</td></tr> | 6BDE8CC9C6A93B21 AFF4B16C71EE90B3</td></tr> | |||
| </tbody> | </tbody> | |||
| </table> | </table> | |||
| </section> | </section> | |||
| <section> <!-- 6. --> | <section anchor="sec-cons"> | |||
| <name>Security Considerations</name> | <name>Security Considerations</name> | |||
| <t>No assertion of suitability for cryptographic applications is made | <t>No assertion of suitability for cryptographic applications is made | |||
| for the FNV hash algorithms.</t> | for the FNV hash algorithms.</t> | |||
| <t>Use of a cryptographic hash function should be considered when | <t>The use of a cryptographic hash function should be considered when | |||
| active adversaries are a factor (see <xref | active adversaries are a factor (see <xref | |||
| target="applicability"/>).</t> | target="applicability"/>).</t> | |||
| <section anchor="bang"> | <section anchor="bang"> | |||
| <name>Inducing Collisions</name> | <name>Inducing Collisions</name> | |||
| <t>An attacker could attempt to induce collisions to cause denial or | <t>An attacker could attempt to induce collisions to cause denial or | |||
| degradation of service. Consider the following simplified example: a | degradation of service. Consider the following simplified example: A | |||
| hash table of n buckets is being maintained with the bucket used by | hash table of n buckets is being maintained with the bucket used by | |||
| some item i determined by</t> | some item i determined by</t> | |||
| <artwork align="center"> | <artwork align="left"><![CDATA[ hash(i) mod n | |||
| hash(i) mod n | ]]></artwork> | |||
| </artwork> | ||||
| <t>and with a linked list out of each bucket of the items that all | <t>and with a linked list out of each bucket of the items that all | |||
| hash to that bucket. Such an arrangement might be used for the symbol | hash to that bucket. Such an arrangement might be used for the symbol | |||
| table in a compiler or for some of the routing information (i.e., RIB | table in a compiler or for some of the routing information (i.e., a RIB | |||
| (Routing Information Base)) in a router. Then a large number of items | (Routing Information Base)) in a router. A large number of items | |||
| hashing to the same bucket will likely result in much slower times to | hashing to the same bucket will then likely result in much slower times to | |||
| retrieve from or update the information stored through the table for | retrieve from or update the information stored through the table for | |||
| one of those items. Typically, an attacker could arrange for the | one of those items. Typically, an attacker could arrange for the | |||
| number of distinct items being hashed to be orders of magnitude larger | number of distinct items being hashed to be orders of magnitude larger | |||
| than n, even if n was tens or hundreds of thousands, so collisions are | than n, even if n was tens or hundreds of thousands, so collisions are | |||
| guaranteed to occur in this example regardless of the nature of the | guaranteed to occur in this example regardless of the nature of the | |||
| hash function.</t> | hash function. | |||
| <!-- [rfced] Section 6.1: Is a Routing Information Base the only | ||||
| source of routing information (in which case "i.e.," is correct), or | ||||
| is it an example of a source of routing information (in which case | ||||
| "e.g.," should be used here instead)? | ||||
| Original: | ||||
| Such an arrangement might be used for the symbol table in a | ||||
| compiler or for some of the routing information (i.e., RIB | ||||
| (Routing Information Base)) in a router. --> | ||||
| </t> | ||||
| <t>There are a number of different circumstances that might surround | <t>There are a number of different circumstances that might surround | |||
| this example of which the following three are illustrative:</t> | this example, of which the following three are illustrative:</t> | |||
| <ul> | <ul> | |||
| <li>If a hash function is being used in an exactly known way for the | <li>If a hash function is being used in an exactly known way for the | |||
| above scenario, including a known offset_basis such as a standard | above scenario, including a known offset_basis such as a standard | |||
| offset_basis specified in this document, then an adversary could | offset_basis specified in this document, then an adversary could | |||
| test items off-line and generate an arbitrary set of items whose | test items offline and generate an arbitrary set of items whose | |||
| hash table indexes would collide. Under these circumstances, the | hash table indexes would collide. Under these circumstances, the | |||
| adversary would not have to conduct any trials of actually | adversary would not have to conduct any trials of actually | |||
| submitting items and would not have to measure performance to find | submitting items and would not have to measure performance to find | |||
| collisions. Then submitting such a set of items would degrade or | collisions. Submitting such a set of items would then degrade or | |||
| deny service. For FNV, use of an offset_basis not known by the | deny service. For FNV, the use of an offset_basis not known by the | |||
| adversary is adequate to defeat this case.</li> | adversary is adequate to defeat this case.</li> | |||
| <li>If the adversary cannot detect when collisions occur, or service | <li>If the adversary cannot detect when collisions occur or when service | |||
| is degraded, then it is sufficient for the adversary to be unable to | is degraded, then it is sufficient for the adversary to be unable to | |||
| predict the hash outcomes. For FNV, use of an offset_basis not known | predict the hash outcomes. For FNV, the use of an offset_basis not known | |||
| by the adversary may be adequate to defend against this case.</li> | by the adversary may be adequate to defend against this case. | |||
| <!-- [rfced] Section 6.1: As it appears to us that "occur, or | ||||
| service is degraded" means "occur or when service is degraded" as | ||||
| opposed to "occur or if service is degraded", we updated this | ||||
| sentence accordingly. If this is incorrect, please provide | ||||
| clarifying text. | ||||
| Original: | ||||
| * If the adversary cannot detect when collisions occur, or service | ||||
| is degraded, then it is sufficient for the adversary to be unable | ||||
| to predict the hash outcomes. | ||||
| Currently: | ||||
| * If the adversary cannot detect when collisions occur or when | ||||
| service is degraded, then it is sufficient for the adversary to be | ||||
| unable to predict the hash outcomes. --> | ||||
| </li> | ||||
| <li>If the adversary can detect the degradation in service caused by | <li>If the adversary can detect the degradation in service caused by | |||
| collisions in the above example and can feed large numbers of | collisions in the above example and can feed large numbers of | |||
| variable items to the process, then they can collect sets of items | variable items to the process, then they can collect sets of items | |||
| that appear to collide. Even if there are limits to the number of | that appear to collide. Even if there are limits to the number of | |||
| items that can be submitted, if there can be multiple trials, the | items that can be submitted, if there can be multiple trials, the | |||
| adversary can collect multiple sets of items that collide within | adversary can collect multiple sets of items that collide within | |||
| each set or one growing set of items all of which collide. Then, by | each set or one growing set of items, all of which collide. Then, by | |||
| submitting such items, the adversary can degrade or deny | submitting such items, the adversary can degrade or deny | |||
| service. That is true regardless of whether the hash function used | service. That is true regardless of whether the hash function used | |||
| is a non-cryptographic hash function such as FNV or a cryptographic | is a non-cryptographic hash function such as FNV or a cryptographic | |||
| hash function such as those in <xref target="FIPS202"/> or <xref | hash function such as those specified in <xref target="FIPS202"/> or <xref | |||
| target="RFC6234"/>. One defense in this case is to detect when a | target="RFC6234"/>. One defense in this case is to detect when a | |||
| large number of collisions are happening (which could, but would be | large number of collisions are happening (which could, but would be | |||
| unlikely to, occur by chance) and, when that is detected, rehash the | unlikely to, occur by chance) and, when that is detected, rehash the | |||
| items with some change to the hash algorithm and use the changed | items with some change to the hash algorithm and use the changed | |||
| hash algorithm for subsequent items; for example, if FNV is being | hash algorithm for subsequent items -- for example, if FNV is being | |||
| used, to rehash with a different offset_basis and then continue | used, to rehash with a different offset_basis and then continue | |||
| using that new offset_basis. There exist commercially deployed | using that new offset_basis. There exist commercially deployed | |||
| routers that use this technique to ameliorate excessive hash | routers that use this technique to ameliorate excessive hash | |||
| collisions in internal tables.</li> | collisions in internal tables.</li> | |||
| </ul> | </ul> | |||
| </section> | </section> | |||
| </section> <!-- 6. --> | </section> | |||
| <section> <!-- 7. --> | <section> | |||
| <name>Historical Notes</name> | <name>Historical Notes</name> | |||
| <t>The FNV hash algorithm originated from an idea submitted as | <t>The FNV hash algorithm originated from an idea submitted as | |||
| reviewer comments to the <xref target="IEEE"/> POSIX P1003.2 | reviewer comments to the IEEE POSIX P1003.2 committee <xref target="IEEE"/> in | |||
| committee in 1991 by Glenn Fowler and Phong Vo. Subsequently, during | 1991 by <contact fullname="Glenn Fowler"/> and <contact fullname="Phong Vo"/>. | |||
| a ballot round, Landon Curt Noll proposed an enhancement to their | Subsequently, during | |||
| a ballot round, <contact fullname="Landon Curt Noll"/> proposed an enhancement | ||||
| to their | ||||
| algorithm. Some people tried this hash and found that it worked | algorithm. Some people tried this hash and found that it worked | |||
| rather well. In an EMail message to Landon, they named it the | rather well. In an email message to Landon, they named it the | |||
| "Fowler/Noll/Vo" or FNV hash from their last names in alphabetic | "Fowler/Noll/Vo" or FNV hash from their last names in alphabetical | |||
| order. <xref target="FNV"/></t> | order <xref target="FNV"/>. | |||
| </t> | ||||
| <!-- [rfced] Section 7: We found the citation for [IEEE] confusing, | ||||
| as we could not readily locate information on the IEEE POSIX P1003.2 | ||||
| committee when searching [IEEE]. Also, in a general web search, we | ||||
| saw a reference to a September 1991 draft | ||||
| (https://mirror.math.princeton.edu/pub/oldlinux/Linux.old/ | ||||
| Ref-docs/POSIX/all.pdf) and a 1992 paper | ||||
| (https://standards.ieee.org/ieee/1003.2/1408/). Will this text and | ||||
| citation be clear to readers? | ||||
| Original: | ||||
| The FNV hash algorithm originated from an idea submitted as reviewer | ||||
| comments to the [IEEE] POSIX P1003.2 committee in 1991 by Glenn | ||||
| Fowler and Phong Vo. --> | ||||
| <!-- LB: Checked the quoted (DNE) text below, and fixed it to match | ||||
| what's listed in the reference. --> | ||||
| <t>The string used to calculate the offset_basis values (see <xref | <t>The string used to calculate the offset_basis values (see <xref | |||
| target="constoffb"/>) was selected because the person testing FNV | target="constoffb"/>) was selected because the person testing FNV | |||
| with non-zero offset_basis values was looking at an email message | with non-zero offset_basis values was looking at an email message | |||
| from Landon and was copying his standard email signature line; | from Landon and was copying his standard email signature line; | |||
| however, they "didn't see very well" <xref target="FNV"/> and copied | however, they "did not see very well" <xref target="FNV"/> and copied | |||
| it incorrectly. In fact, Landon uses</t> | it incorrectly. In fact, Landon uses</t> | |||
| <artwork align="center" type="ascii-art"> | <artwork align="left"><![CDATA[ chongo (Landon Curt Noll) | |||
| chongo (Landon Curt Noll) /\oo/\ | /\oo/\ | |||
| </artwork> | ]]></artwork> | |||
| <t>but, since it doesn't matter, no effort has been made to correct | <t>but, since it doesn't matter, no effort has been made to correct | |||
| this.</t> | this.</t> | |||
| </section> <!-- 7. --> | </section> | |||
| <section anchor="SourceCode"> <!-- 8. --> | <section anchor="SourceCode"> | |||
| <name>The Source Code</name> | <name>The Source Code</name> | |||
| <t>The following sub-sections provide reference <xref target="C"/> | <t>The following subsections provide reference C source code <xref target="C"/> | |||
| source code and a test driver with command line interface for | and a test driver with a command line interface for | |||
| FNV-1a.</t> | FNV-1a.</t> | |||
| <t>Section 8.2 provides the C header and code source files for the FNV | <t><xref target="sec-8.2"/> provides the C header and code source files for the | |||
| functions. Section 8.3 provides the test driver. Section 8.4 provides | FNV | |||
| functions. <xref target="sec-8.3"/> provides the test driver. <xref target="sec- | ||||
| 8.4"/> provides | ||||
| a simple makefile to build the test driver or a library file with all | a simple makefile to build the test driver or a library file with all | |||
| FNV sizes.</t> | FNV sizes.</t> | |||
| <t>Alternative source code for 32- and 64-bit FNV is available at | <t>Alternative source code for 32- and 64-bit FNV is available at | |||
| <xref target="LCN2"/>. Other alternative source code, including in x86 | <xref target="LCN2"/>. Other alternative source code, including in x86 | |||
| assembler, is currently available at <xref target="FNV"/>. In some | assembler, is currently available at <xref target="FNV"/>. In some | |||
| cases, this further source code has been further optimized.</t> | cases, this further source code has been further optimized.</t> | |||
| <section> <!-- 8.1 --> | <section> | |||
| <name>Source Code Details</name> | <name>Source Code Details</name> | |||
| <section> <!-- 8.1.1 --> | <section> | |||
| <name>FNV Functions Available</name> | <name>FNV Functions Available</name> | |||
| <t>The functions provided are listed below. The "xxx" in the | <t>The functions provided are listed below. The "xxx" in the | |||
| function names is "32", "64", "128", "256", "512", or "1024" | function names is "32", "64", "128", "256", "512", or "1024", | |||
| depending on the length of the FNV. All of the FNV hash functions | depending on the length of the FNV. All of the FNV hash functions | |||
| have as their return value an integer whose meaning is specified in | have as their return value an integer whose meaning is specified in | |||
| FNVErrorCodes.h.</t> | FNVErrorCodes.h.</t> | |||
| <t>Functions providing a byte vector hash are available for all | <t>Functions providing a byte vector hash are available for all | |||
| lengths. For FNV-32, versions are available that provide a 32-bit | lengths. For FNV-32, versions are available that provide a 32-bit | |||
| integer and are identified by replacing "xxx" with "32INT". For | integer and are identified by replacing "xxx" with "32INT". For | |||
| example, FNV32string provides a 4-byte vector but FNV32INTstring | example, FNV32string provides a 4-byte vector, but FNV32INTstring | |||
| provides a 32-bit integer. For FNV-64, if compiled with 64-bit | provides a 32-bit integer. For FNV-64, if compiled with 64-bit | |||
| integers enabled (i.e., FNV_64bitIntegers defined, see FNVconfig.h), | integers enabled (i.e., FNV_64bitIntegers defined; see FNVconfig.h), | |||
| versions are available that provide a 64-bit integer and are | versions are available that provide a 64-bit integer and are | |||
| identified by replacing "xxx" with "64INT"`. Versions providing an | identified by replacing "xxx" with "64INT". Versions providing an | |||
| integer hash will not be compatible between systems of different | integer hash will not be compatible between systems of different | |||
| endian-ness (see <xref target="endian"/>).</t> | endianness (see <xref target="endian"/>).</t> | |||
| <t>If you want to copy the source code from this document, note that | <t>If you want to copy the source code from this document, note that | |||
| it is indented by three spaces in the ".txt" version. It may be | it is indented by three spaces in the ".txt" version. It may be | |||
| simplest to copy from the ".html" version of this document.</t> | simplest to copy from the ".html" version of this document.</t> | |||
| <artwork align="left"><![CDATA[ | ||||
| FNVxxxstring, FNVxxxblock, FNVxxxfile: | ||||
| <dl> | FNVxxxstringBase, FNVxxxblockBase, FNVxxxfileBase: | |||
| <dt>FNVxxxstring, FNVxxxblock, FNVxxxfile:</dt><dd/> | ||||
| <dt>FNVxxxstringBase, FNVxxxblockBase, FNVxxxfileBase:</dt><dd/> | ||||
| <dt>FNVxxxINTstring, FNVxxxINTblock, FNVxxxINTfile:</dt><dd/> | FNVxxxINTstring, FNVxxxINTblock, FNVxxxINTfile: | |||
| ]]></artwork> | ||||
| <dl> | ||||
| <dt>FNVxxxINTstringBase, FNVxxxINTblockBase, | <dt>FNVxxxINTstringBase, FNVxxxINTblockBase, | |||
| FNVxxxINTfileBase:</dt> | FNVxxxINTfileBase:</dt> | |||
| <dd>These are simple functions for directly returning the FNV hash | <dd>These are simple functions for directly returning the FNV hash | |||
| of a zero terminated byte string not including that zero byte, the | of a zero-terminated byte string not including that zero byte, the | |||
| FNV hash of a counted block of bytes, and the FNV of a file, | FNV hash of a counted block of bytes, and the FNV of a file, | |||
| respectively. The functions whose name has the "Base" suffix take | respectively. The functions whose names have the "Base" suffix take | |||
| an additional parameter specifying the offset_basis. Note that for | an additional parameter specifying the offset_basis. Note that for | |||
| applications of FNV-32 and of FNV-64 where integers of that size | applications of FNV-32 and of FNV-64 where integers of that size | |||
| are supported and an integer data type output is acceptable, the | are supported and an integer data type output is acceptable, the | |||
| code is sufficiently simple that, to maximize performance, use of | code is sufficiently simple that, to maximize performance, the use of | |||
| open coding or macros may be more appropriate than calling a | open coding or macros may be more appropriate than calling a | |||
| subroutine.</dd> | subroutine.</dd> | |||
| <!-- [rfced] Section 8.1.1: Should "Base" be "Basis" for these | ||||
| entries? We don't see "Base" used anywhere else in comparable | ||||
| parameter names (e.g., "FNV64stringBasis", "FNV32blockBasis" as | ||||
| used later). | ||||
| Original: | ||||
| FNVxxxstringBase, FNVxxxblockBase, FNVxxxfileBase: | ||||
| ... | ||||
| FNVxxxINTstringBase, FNVxxxINTblockBase, FNVxxxINTfileBase: | ||||
| ... | ||||
| The functions whose name has the "Base" suffix take an additional | ||||
| parameter specifying the offset_basis. --> | ||||
| <dt>FNVxxxinit, FNVxxxinitBasis:</dt><dd/> | <dt>FNVxxxinit, FNVxxxinitBasis:</dt><dd/> | |||
| <!-- [rfced] Section 8.1.1: The following four entries don't seem to | ||||
| have any descriptive information below them. We also see that the | ||||
| first three entries are contained in an <artwork> element but the | ||||
| fourth entry is part of the description list. | ||||
| Will the use/purpose of these four entries be clear to readers, or | ||||
| should all of them have definitions and be part of the same | ||||
| definition list? | ||||
| Original: | ||||
| FNVxxxstring, FNVxxxblock, FNVxxxfile: | ||||
| FNVxxxstringBase, FNVxxxblockBase, FNVxxxfileBase: | ||||
| FNVxxxINTstring, FNVxxxINTblock, FNVxxxINTfile: | ||||
| ... | ||||
| FNVxxxinit, FNVxxxinitBasis: --> | ||||
| <dt>FNVxxxINTinitBasis:</dt><dd>These functions and the next two | <dt>FNVxxxINTinitBasis:</dt><dd>These functions and the next two | |||
| sets of functions below provide facilities for incrementally | sets of functions below provide facilities for incrementally | |||
| calculating FNV hashes. They all assume a data structure of type | calculating FNV hashes. They all assume a data structure of type | |||
| FNVxxxcontext that holds the current state of the hash. FNVxxxinit | FNVxxxcontext that holds the current state of the hash. FNVxxxinit | |||
| initializes that context to the standard | initializes that context to the standard | |||
| offset_basis. FNVxxxinitBasis takes an offset_basis value as a | offset_basis. FNVxxxinitBasis takes an offset_basis value as a | |||
| parameter and may be useful for hashing concatenations, as | parameter and may be useful for hashing concatenations, as | |||
| described in Section 4, as well as for simply using a non-standard | described in <xref target="sec-4"/>, as well as for simply using a non-stand ard | |||
| offset_basis.</dd> | offset_basis.</dd> | |||
| <dt>FNVxxxblockin, FNVxxxstringin, FNVxxxfilein:</dt><dd>These | <dt>FNVxxxblockin, FNVxxxstringin, FNVxxxfilein:</dt><dd>These | |||
| functions hash a sequence of bytes into an FNVxxxcontext that was | functions hash a sequence of bytes into an FNVxxxcontext that was | |||
| originally initialized by FNVxxxinit or | originally initialized by FNVxxxinit or | |||
| FNVxxxinitBasis. FNVxxxblockin hashes in a counted block of | FNVxxxinitBasis. FNVxxxblockin hashes in a counted block of | |||
| bytes. FNVxxxstringin hashes in a zero terminated byte string not | bytes. FNVxxxstringin hashes in a zero-terminated byte string not | |||
| including the final zero byte. FNVxxxfilein hashes in the contents | including the final zero byte. FNVxxxfilein hashes in the contents | |||
| of a file.</dd> | of a file.</dd> | |||
| <dt>FNVxxxresult, FNVxxxINTresult:</dt><dd>This function extracts | <dt>FNVxxxresult, FNVxxxINTresult:</dt><dd>This function extracts | |||
| the final FNV hash result from an FNVxxxcontext.</dd> | the final FNV hash result from an FNVxxxcontext.</dd> | |||
| </dl> | </dl> | |||
| </section> | </section> | |||
| <section> <!-- 8.1.2 --> | <section> | |||
| <name>Source Files and 64-bit Support </name> | <name>Source Files and 64-Bit Support </name> | |||
| <t>Code optimized for 64-bit integer support, that is, support of | <t>Code optimized for 64-bit integer support -- that is, support of | |||
| 64-bit integer addition and 32x32-bit multiplication producing a | 64-bit integer addition and 32-bit x 32-bit multiplication producing a | |||
| 64-bit product, is provided based on whether or not the | 64-bit product -- is provided based on whether or not the | |||
| FNV_64bitIntegers symbol is defined. By default, this is set in | FNV_64bitIntegers symbol is defined. By default, this is set in | |||
| FNVconfig.h based on the compilation target; however, this can be | FNVconfig.h based on the compilation target; however, this can be | |||
| overridden by editing that file or by defining certain symbols in, for | overridden by editing that file or by defining certain symbols in, for | |||
| example, a command line invoking compilation.</t> | example, a command line invoking compilation. | |||
| <t>For support of a single FNV size, say "xxx", in an application, the | <!-- [rfced] Section 8.1.2: Does "a command line invoking | |||
| application itself needs to include the FNVxxx.h (which will, in turn, | compilation" mean "a compilation that invokes a command line" or | |||
| include the FNVconfig.h and FNVErrorCodes.h) files. To build the | "a command line invoking a compilation"? | |||
| Original: | ||||
| By default, this is set in FNVconfig.h based on | ||||
| the compilation target; however, this can be overridden by editing | ||||
| that file or by defining certain symbols in, for example, a command | ||||
| line invoking compilation. --> | ||||
| </t> | ||||
| <t>For support of a single FNV size, say "xxx" (e.g., FNV64), in an application, | ||||
| the | ||||
| application itself needs to include the appropriate FNVxxx.h file (which will, i | ||||
| n turn, | ||||
| include the FNVconfig.h and FNVErrorCodes.h files). To build the | ||||
| particular FNVxxx code itself, compile the FNVxxx.c file with | particular FNVxxx code itself, compile the FNVxxx.c file with | |||
| FNVconfig.h, fnv-private.h, FNVErrorCodes.h, and FNVxxx.h | FNVconfig.h, fnv-private.h, FNVErrorCodes.h, and FNVxxx.h (available in <xref ta | |||
| available. Since the test program in Section 8.3 uses all sizes of | rget="sec-8.2"/>). Since the test program provided in <xref target="sec-8.3"/> u | |||
| FNV, all the .c and .h files are needed to compile it.</t> | ses all sizes of FNV, all the .c and .h files are needed to compile it. | |||
| <!-- [rfced] Section 8.1.2: We had trouble following these sentences. | ||||
| We updated them as follows. If these updates are incorrect, please | ||||
| clarify the text. | ||||
| Original: | ||||
| For support of a single FNV size, say "xxx", in an application, the | ||||
| application itself needs to include the FNVxxx.h (which will, in | ||||
| turn, include the FNVconfig.h and FNVErrorCodes.h) files. To build | ||||
| the particular FNVxxx code itself, compile the FNVxxx.c file with | ||||
| FNVconfig.h, fnv-private.h, FNVErrorCodes.h, and FNVxxx.h available. | ||||
| Currently: | ||||
| For support of a single FNV size, say "xxx" (e.g., FNV64), in an | ||||
| application, the application itself needs to include the appropriate | ||||
| FNVxxx.h file (which will, in turn, include the FNVconfig.h and | ||||
| FNVErrorCodes.h files). To build the particular FNVxxx code itself, | ||||
| compile the FNVxxx.c file with FNVconfig.h, fnv-private.h, | ||||
| FNVErrorCodes.h, and FNVxxx.h (available in Section 8.2). --> | ||||
| </t> | ||||
| </section> | </section> | |||
| <section> <!-- 8.1.3 --> | <section anchor="sec-8.1.3"> | |||
| <name>Command Line Interface</name> | <name>Command Line Interface</name> | |||
| <t>The test program provided in Section 8.3 has a command line | <t>The test program provided in <xref target="sec-8.3"/> has a command line | |||
| interface. By default, with no command line arguments, it runs | interface. By default, with no command line arguments, it runs | |||
| tests of all FNV lengths. Command line options are as follows:</t> | tests of all FNV lengths. Command line options are as follows:</t> | |||
| <artwork align="center" type="ascii-art"> | <artwork align="left"><![CDATA[ FNVhash [-a] [-h] [-t nnn] [-u nnn] [-v] [-f f | |||
| FNVhash [-a] [-h] [-t nnn] [-u nnn] [-v] [-f filename] [token ...] | ilename] [token ...] | |||
| </artwork> | ]]></artwork> | |||
| <t>The option letters have the following meaning:</t> | <t>The option letters have the following meanings:</t> | |||
| <dl> | <dl newline="false"> | |||
| <dt>-a</dt><dd>Run tests for all lengths.</dd> | <dt>-a</dt><dd>Run tests for all lengths.</dd> | |||
| <dt>-h</dt><dd>Print a help message about the command line.</dd> | <dt>-h</dt><dd>Print a help message about the command line.</dd> | |||
| <dt>-v</dt><dd>Complement the Verbose flag which is initially | <dt>-v</dt><dd>Complement the Verbose flag, which is initially | |||
| off. When the flag is on, the program prints more information during | off. When the flag is on, the program prints more information during | |||
| tests, etc.</dd> | tests, etc.</dd> | |||
| <dt>-t nnn</dt><dd>Run tests for length nnn which must be one of 32, | <dt>-t nnn</dt><dd>Run tests for length nnn, which must be one of 32, | |||
| 64, 128, 256, 512, or 1024.</dd> | 64, 128, 256, 512, or 1024.</dd> | |||
| <dt>-u nnn</dt><dd>Use hash size nnn which must be one of 32, 64, | <dt>-u nnn</dt><dd>Use hash size nnn, which must be one of 32, 64, | |||
| 128, 256, 512, or 1024. This is useful to set the hash size for use | 128, 256, 512, or 1024. This is useful for setting the hash size for use | |||
| by the -f option or in hashing tokens on the command line after the | by the -f option or in hashing tokens on the command line after the | |||
| options.</dd> | options.</dd> | |||
| <dt>-f filename</dt><dd>Hash the contents of the file with name | <dt>-f filename</dt><dd>Hash the contents of the file with name | |||
| filename. The hash size must have been set by a prior -t or -u | filename. The hash size must have been set by a prior -t or -u | |||
| option in the command line.</dd> | option in the command line.</dd> | |||
| <dt>token</dt><dd>Tokens appearing on the command line after the | <dt>token</dt><dd>Tokens appearing on the command line after the | |||
| options are hashed with the current hash size which must have been | options are hashed with the current hash size, which must have been | |||
| set by a prior -t or -u option in the command line.</dd> | set by a prior -t or -u option in the command line.</dd> | |||
| </dl> | </dl> | |||
| <t>For example,</t> | <t>For example,</t> | |||
| <artwork align="center" type="ascii-art"> | <artwork align="left"><![CDATA[ FNVhash -t 128 -h -v -t 64 -v -u 256 -f foo | |||
| FNVhash -t 128 -h -v -t 64 -v -u 256 -f foobar.txt RabOof 1234 | bar.txt RabOof 1234 | |||
| </artwork> | ]]></artwork> | |||
| <t>runs tests for FNV128, then prints a command line help message, | <t>runs tests for FNV128, then prints a command line help message, | |||
| then turns on Verbose, then runs the tests for FNV64, then turns off | then turns on Verbose, then runs the tests for FNV64, then turns off | |||
| Verbose, then sets the hash size to 256, then hashes the contents of | Verbose, then sets the hash size to 256, then hashes the contents of | |||
| file foobar.txt, then hashes the token "RabOof", and finally hashes | file foobar.txt, then hashes the token "RabOof", and finally hashes | |||
| the token "1234".</t> | the token "1234".</t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section> <!-- 8.2 --> | <section anchor="sec-8.2"> | |||
| <name>FNV-1a C Code</name> | <name>FNV-1a C Code</name> | |||
| <t>This section provides the direct FNV-1a function for each of the | <t>This section provides the direct FNV-1a function for each of the | |||
| lengths for which it is specified in this document.</t> | lengths for which it is specified in this document.</t> | |||
| <t>The following is a configuration header to set whether 64-bit | <t>The following is a configuration header to set whether 64-bit | |||
| integers are supported and establish an enum used for return | integers are supported and establish an enum used for return | |||
| values.</t> | values.</t> | |||
| <sourcecode type="C" markers="true" name="FNVconfig.h"> | <!-- [rfced] Sections 8.2 and subsequent: We changed instances of | |||
| <![CDATA[ | "RFC NNNN" to "RFC 9923". Please let us know any concerns. --> | |||
| <sourcecode type="c" markers="true" name="FNVconfig.h"><![CDATA[ | ||||
| //************************ FNVconfig.h **************************// | //************************ FNVconfig.h **************************// | |||
| //**************** See RFC NNNN for details. ********************// | //**************** See RFC 9923 for details. ********************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * | ||||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| #ifndef _FNVconfig_H_ | #ifndef _FNVconfig_H_ | |||
| #define _FNVconfig_H_ | #define _FNVconfig_H_ | |||
| /* Description: | /* | |||
| * Description: | ||||
| * This file provides configuration ifdefs for the | * This file provides configuration ifdefs for the | |||
| * FNV-1a non-cryptographic hash algorithms. */ | * FNV-1a non-cryptographic hash algorithms. */ | |||
| /* FNV_64bitIntegers - Define this if your system supports | /* FNV_64bitIntegers - Define this if your system supports | |||
| * 64-bit arithmetic including 32-bit x 32-bit | * 64-bit arithmetic including 32-bit x 32-bit | |||
| * multiplication producing a 64-bit product. If | * multiplication producing a 64-bit product. If | |||
| * undefined, it will be assumed that 32-bit arithmetic | * undefined, it will be assumed that 32-bit arithmetic | |||
| * is supported including 16-bit x 16-bit multiplication | * is supported including 16-bit x 16-bit multiplication | |||
| * producing a 32-bit result. | * producing a 32-bit result. | |||
| */ | */ | |||
| #include <stdint.h> | #include <stdint.h> | |||
| /* Check if 64-bit integers are supported in the target */ | /* Check if 64-bit integers are supported in the target */ | |||
| #ifdef UINT64_MAX | #ifdef UINT64_MAX | |||
| skipping to change at line 1035 ¶ | skipping to change at line 1354 ¶ | |||
| # define uint64_t no_64_bit_integers | # define uint64_t no_64_bit_integers | |||
| # endif | # endif | |||
| #endif | #endif | |||
| #endif /* _FNVconfig_H_ */ | #endif /* _FNVconfig_H_ */ | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <t>The following code is a simple header file to define the return | <t>The following code is a simple header file to define the return | |||
| value error codes for the FNV routines.</t> | value error codes for the FNV routines.</t> | |||
| <sourcecode type="C" markers="true" name="FNVErrorCodes.h"> | <sourcecode type="c" markers="true" name="FNVErrorCodes.h"><![CDATA[ | |||
| //********************** FNVErrorCodes.h **************************// | //********************** FNVErrorCodes.h **************************// | |||
| //**************** See RFC NNNN for details. **********************// | //**************** See RFC 9923 for details. **********************// | |||
| /* Copyright (c) 2016, 2023, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2023, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| #ifndef _FNV_ErrCodes_ | #ifndef _FNV_ErrCodes_ | |||
| #define _FNV_ErrCodes_ | #define _FNV_ErrCodes_ | |||
| //****************************************************************// | //****************************************************************// | |||
| // | // | |||
| // All FNV functions, except the FNVxxxfile functions, | // All FNV functions, except the FNVxxxfile functions, | |||
| skipping to change at line 1059 ¶ | skipping to change at line 1378 ¶ | |||
| // 0 -> success | // 0 -> success | |||
| // >0 -> error as listed below | // >0 -> error as listed below | |||
| // | // | |||
| enum { /* success and errors */ | enum { /* success and errors */ | |||
| fnvSuccess = 0, | fnvSuccess = 0, | |||
| fnvNull, // 1 Null pointer parameter | fnvNull, // 1 Null pointer parameter | |||
| fnvStateError, // 2 called Input after Result or before Init | fnvStateError, // 2 called Input after Result or before Init | |||
| fnvBadParam // 3 passed a bad parameter | fnvBadParam // 3 passed a bad parameter | |||
| }; | }; | |||
| #endif /* _FNV_ErrCodes_ */ | #endif /* _FNV_ErrCodes_ */ | |||
| </sourcecode> | ]]></sourcecode> | |||
| <t>The following code is a private header file used by all the FNV | <t>The following code is a private header file that is used by all the FNV | |||
| functions further below and which states the terms for use and | functions further below and that states the terms for use and | |||
| redistribution of all of this source code.</t> | redistribution of all of this source code.</t> | |||
| <sourcecode type="C" markers="true" name="fnv-private.h"> | <sourcecode type="c" markers="true" name="fnv-private.h"><![CDATA[ | |||
| //********************** fnv-private.h ************************// | //************************ fnv-private.h **************************// | |||
| //**************** See RFC NNNN for details *******************// | //****************** See RFC 9923 for details. ********************// | |||
| /* Copyright (c) 2016, 2023, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2023, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * | * | |||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | |||
| * are met: | * are met: | |||
| * | * | |||
| * * Redistributions of source code must retain the above copyright | * * Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | |||
| * | * | |||
| skipping to change at line 1092 ¶ | skipping to change at line 1411 ¶ | |||
| * | * | |||
| * * Neither the name of Internet Society, IETF or IETF Trust, nor | * * Neither the name of Internet Society, IETF or IETF Trust, nor | |||
| * the names of specific contributors, may be used to endorse or | * the names of specific contributors, may be used to endorse or | |||
| * promote products derived from this software without specific | * promote products derived from this software without specific | |||
| * prior written permission. | * prior written permission. | |||
| * | * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
| * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
| * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
| * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
| * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | |||
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | |||
| * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |||
| * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | |||
| * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
| * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| * SUCH DAMAGE. | * SUCH DAMAGE. | |||
| */ | */ | |||
| skipping to change at line 1117 ¶ | skipping to change at line 1436 ¶ | |||
| * Six FNV-1a hashes are defined with these sizes: | * Six FNV-1a hashes are defined with these sizes: | |||
| * FNV32 32 bits, 4 bytes | * FNV32 32 bits, 4 bytes | |||
| * FNV64 64 bits, 8 bytes | * FNV64 64 bits, 8 bytes | |||
| * FNV128 128 bits, 16 bytes | * FNV128 128 bits, 16 bytes | |||
| * FNV256 256 bits, 32 bytes | * FNV256 256 bits, 32 bytes | |||
| * FNV512 512 bits, 64 bytes | * FNV512 512 bits, 64 bytes | |||
| * FNV1024 1024 bits, 128 bytes | * FNV1024 1024 bits, 128 bytes | |||
| */ | */ | |||
| /* Private stuff used by this implementation of the FNV | /* Private stuff used by this implementation of the FNV | |||
| * (Fowler, Noll, Vo) non-cryptographic hash function FNV-1a. | * (Fowler/Noll/Vo) non-cryptographic hash function FNV-1a. | |||
| * External callers don't need to know any of this. */ | * External callers don't need to know any of this. */ | |||
| enum { /* State value bases for context->Computed */ | enum { /* State value bases for context->Computed */ | |||
| FNVinited = 22, | FNVinited = 22, | |||
| FNVcomputed = 76, | FNVcomputed = 76, | |||
| FNVemptied = 220, | FNVemptied = 220, | |||
| FNVclobber = 122 /* known bad value for testing */ | FNVclobber = 122 /* known bad value for testing */ | |||
| }; | }; | |||
| /* Deltas to assure distinct state values for different lengths */ | /* Deltas to assure distinct state values for different lengths */ | |||
| enum { | enum { | |||
| FNV32state = 1, | FNV32state = 1, | |||
| FNV64state = 3, | FNV64state = 3, | |||
| FNV128state = 5, | FNV128state = 5, | |||
| FNV256state = 7, | FNV256state = 7, | |||
| FNV512state = 11, | FNV512state = 11, | |||
| FNV1024state = 13 | FNV1024state = 13 | |||
| }; | }; | |||
| #endif /* _FNV_PRIVATE_H_ */ | #endif /* _FNV_PRIVATE_H_ */ | |||
| </sourcecode> | ]]></sourcecode> | |||
| <section> | <section> | |||
| <name>FNV32 Code</name> | <name>FNV32 Code</name> | |||
| <t>The header and C source for 32-bit FNV-1a providing a 32-bit | <t>The following code is the header and C source for 32-bit FNV-1a providing a 3 2-bit | |||
| integer or 4-byte vector hash.</t> | integer or 4-byte vector hash.</t> | |||
| <sourcecode type="C" markers="true" name="FNV32.h"> | <sourcecode type="c" markers="true" name="FNV32.h"><![CDATA[ | |||
| <![CDATA[ | ||||
| //*************************** FNV32.h ****************************// | //*************************** FNV32.h ****************************// | |||
| //****************** See RFC NNNN for details ********************// | //****************** See RFC 9923 for details. *******************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| #ifndef _FNV32_H_ | #ifndef _FNV32_H_ | |||
| #define _FNV32_H_ | #define _FNV32_H_ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| skipping to change at line 1175 ¶ | skipping to change at line 1493 ¶ | |||
| #include "FNVErrorCodes.h" | #include "FNVErrorCodes.h" | |||
| #include <stdint.h> | #include <stdint.h> | |||
| #define FNV32size (32/8) | #define FNV32size (32/8) | |||
| #define FNV32basis 0x811C9DC5 | #define FNV32basis 0x811C9DC5 | |||
| /* If you do not have the ISO standard stdint.h header file, then | /* If you do not have the ISO standard stdint.h header file, then | |||
| * you must typedef the following types: | * you must typedef the following types: | |||
| * | * | |||
| * type meaning | * type meaning | |||
| * uint32_t unsigned 32-bit integer | * uint32_t unsigned 32-bit integer | |||
| * uint8_t unsigned 8-bit integer (i.e., unsigned char) | * uint8_t unsigned 8-bit integer (i.e., unsigned char) | |||
| */ | */ | |||
| /* | /* | |||
| * This structure holds context information for an FNV32 hash | * This structure holds context information for an FNV32 hash | |||
| */ | */ | |||
| typedef struct FNV32context_s { | typedef struct FNV32context_s { | |||
| int Computed; /* state */ | int Computed; /* state */ | |||
| uint32_t Hash; | uint32_t Hash; | |||
| } FNV32context; | } FNV32context; | |||
| /* | /* Function Prototypes: | |||
| * Function Prototypes: | ||||
| * | * | |||
| * FNV32string: hash a zero-terminated string not including | * FNV32string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV32stringBasis: also takes an offset_basis parameter | * FNV32stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV32block: hash a specified length byte vector | * FNV32block: hash a specified length byte vector | |||
| * FNV32blockBasis: also takes an offset_basis parameter | * FNV32blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV32file: hash the contents of a file | * FNV32file: hash the contents of a file | |||
| * FNV32fileBasis: also takes an offset_basis parameter | * FNV32fileBasis: also takes an offset_basis parameter | |||
| skipping to change at line 1290 ¶ | skipping to change at line 1607 ¶ | |||
| extern int FNV32result ( FNV32context * const, | extern int FNV32result ( FNV32context * const, | |||
| uint8_t out[FNV32size] ); | uint8_t out[FNV32size] ); | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| } | } | |||
| #endif | #endif | |||
| #endif /* _FNV32_H_ */ | #endif /* _FNV32_H_ */ | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <sourcecode type="C" markers="true" name="FNV32.c"> | <!-- [rfced] Sections 8.2.1 and subsequent: Does "a specified length | |||
| <![CDATA[ | byte vector" mean "a specified 'length byte vector'", "a byte vector | |||
| of specified length", or something else? We ask because we see text | ||||
| such as "4-byte vector" and "the same size byte vectors" used | ||||
| elsewhere. Please clarify. | ||||
| Examples from original: | ||||
| * FNV32block: hash a specified length byte vector | ||||
| ... | ||||
| * FNV32blockin: hash in a specified length byte vector | ||||
| ... | ||||
| * FNV32INTblock: hash a specified length byte vector | ||||
| ... | ||||
| * FNV64block: hash a specified length byte vector --> | ||||
| <sourcecode type="c" markers="true" name="FNV32.c"><![CDATA[ | ||||
| //************************** FNV32.c **************************// | //************************** FNV32.c **************************// | |||
| //**************** See RFC NNNN for details. ******************// | //**************** See RFC 9923 for details. ******************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| /* This code implements the FNV (Fowler, Noll, Vo) non-cryptographic | /* This code implements the FNV (Fowler/Noll/Vo) non-cryptographic | |||
| * hash function FNV-1a for 32-bit hashes. | * hash function FNV-1a for 32-bit hashes. | |||
| */ | */ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV32.h" | #include "FNV32.h" | |||
| /* 32-bit FNV_prime = 2^24 + 2^8 + 0x93 */ | /* 32-bit FNV_prime = 2^24 + 2^8 + 0x93 */ | |||
| #define FNV32prime 0x01000193 | #define FNV32prime 0x01000193 | |||
| /* FNV32 hash a zero-terminated string not including the zero | /* FNV32 hash a zero-terminated string not including the zero | |||
| *****************************************************************/ | *****************************************************************/ | |||
| int FNV32INTstring ( const char *in, uint32_t * const out ) { | int FNV32INTstring ( const char *in, uint32_t * const out ) { | |||
| return FNV32INTstringBasis( in, out, FNV32basis ); | return FNV32INTstringBasis ( in, out, FNV32basis ); | |||
| } /* end FNV32INTstring */ | } /* end FNV32INTstring */ | |||
| /* FNV32 hash a zero-terminated string not including the zero | /* FNV32 hash a zero-terminated string not including the zero | |||
| * with a non-standard basis | * with a non-standard basis | |||
| *****************************************************************/ | *****************************************************************/ | |||
| int FNV32INTstringBasis ( const char *in, | int FNV32INTstringBasis ( const char *in, | |||
| uint32_t * const out, | uint32_t * const out, | |||
| uint32_t basis ) { | uint32_t basis ) { | |||
| uint8_t ch; | uint8_t ch; | |||
| skipping to change at line 1650 ¶ | skipping to change at line 1981 ¶ | |||
| if ( ctx->Computed != FNVcomputed+FNV32state ) | if ( ctx->Computed != FNVcomputed+FNV32state ) | |||
| return fnvStateError; | return fnvStateError; | |||
| ctx->Computed = FNVemptied+FNV32state; | ctx->Computed = FNVemptied+FNV32state; | |||
| for ( int i=0; i<FNV32size; ++i ) | for ( int i=0; i<FNV32size; ++i ) | |||
| out[i] = ((uint8_t *)&ctx->Hash)[i]; | out[i] = ((uint8_t *)&ctx->Hash)[i]; | |||
| ctx->Hash = 0; | ctx->Hash = 0; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV32result */ | } /* end FNV32result */ | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <!-- [rfced] Sections 8.2.1 and subsequent: Do instances of | ||||
| "FNV32 hash a ...", "FNV64 hash a", etc. mean "FNV32-hash a ...", | ||||
| "FNV64-hash a", etc. (i.e., to indicate verbs), or do they mean | ||||
| "FNV32: Hash a ...", "FNV64: Hash a", etc. (to indicate instructions, | ||||
| e.g., per "Hash the contents of the file" in Section 8.1.3)? | ||||
| Examples from original: | ||||
| /* FNV32 hash a zero-terminated string not including the zero | ||||
| ... | ||||
| /* FNV64 hash a zero-terminated string not including the zero | ||||
| ... | ||||
| * FNV64string: hash a zero-terminated string not including | ||||
| ... | ||||
| * FNV32block: hash a specified length byte vector | ||||
| ... | ||||
| * FNV32blockin: hash in a specified length byte vector --> | ||||
| </section> | </section> | |||
| <!-- [rfced] Sections 8.2.2 and subsequent: Please note that we | ||||
| removed or added spaces in the following code items. | ||||
| Original (these are most of the items that we modified): | ||||
| int error; (2 instances) | ||||
| int rc; | ||||
| FNV128context ctx; | ||||
| ( memcmp ( was, should, N) != 0 ) | ||||
| (uint8_t *)0 , (we only found one instance of a space before a | ||||
| comma, so we removed the space here) | ||||
| TestR ( "result2", fnvNull, RSLT ( &CTX, (uint8_t *)0 ) ); | ||||
| FNV128result ( &e128Context, hash ) ); | ||||
| TestR ( "result3i", fnvStateError, RSLTINT ( &ctx, &INTV ) ); | ||||
| The spacing changes can be seen in the latest rfc9923-rfcdiff file. | ||||
| Please let us know if you do not agree with these changes, and we | ||||
| will revert them. | ||||
| Please also note that we did not make any changes to | ||||
| Stefan Santesson's code, as we consider it "Do Not Edit" (DNE) | ||||
| and have flagged it as such in the XML file. --> | ||||
| <section> | <section> | |||
| <name>FNV64 Code</name> | <name>FNV64 Code</name> | |||
| <t>The header and C source for 64-bit FNV-1a. Provides an 8-byte | <t>The following code is the header and C source for 64-bit FNV-1a providing an 8-byte | |||
| vector or, optionally, if 64-bit integers are supported, a 64-bit | vector or, optionally, if 64-bit integers are supported, a 64-bit | |||
| integer hash.</t> | integer hash.</t> | |||
| <sourcecode type="C" markers="true" name="FNV64.h"> | <sourcecode type="c" markers="true" name="FNV64.h"><![CDATA[ | |||
| <![CDATA[ | ||||
| //*************************** FNV64.h ****************************// | //*************************** FNV64.h ****************************// | |||
| //***************** See RFC NNNN for details. ********************// | //***************** See RFC 9923 for details. ********************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| #ifndef _FNV64_H_ | #ifndef _FNV64_H_ | |||
| #define _FNV64_H_ | #define _FNV64_H_ | |||
| /* Description: | /* | |||
| * Description: | ||||
| * This file provides headers for the 64-bit version of | * This file provides headers for the 64-bit version of | |||
| * the FNV-1a non-cryptographic hash algorithm. | * the FNV-1a non-cryptographic hash algorithm. | |||
| */ | */ | |||
| #include "FNVconfig.h" | #include "FNVconfig.h" | |||
| #include "FNVErrorCodes.h" | #include "FNVErrorCodes.h" | |||
| #include <stdint.h> | #include <stdint.h> | |||
| #define FNV64size (64/8) | #define FNV64size (64/8) | |||
| #ifdef FNV_64bitIntegers | #ifdef FNV_64bitIntegers | |||
| #define FNV64basis 0xCBF29CE484222325 | #define FNV64basis 0xCBF29CE484222325 | |||
| #endif | #endif | |||
| /* If you do not have the ISO standard stdint.h header file, then | /* If you do not have the ISO standard stdint.h header file, then | |||
| * you must typedef the following types: | * you must typedef the following types: | |||
| * | * | |||
| * type meaning | * type meaning | |||
| * uint64_t unsigned 64-bit integer (ifdef FNV_64bitIntegers) | * uint64_t unsigned 64-bit integer (ifdef FNV_64bitIntegers) | |||
| * uint32_t unsigned 32-bit integer | * uint32_t unsigned 32-bit integer | |||
| * uint16_t unsigned 16-bit integer | * uint16_t unsigned 16-bit integer | |||
| * uint8_t unsigned 8-bit integer (i.e., unsigned char) | * uint8_t unsigned 8-bit integer (i.e., unsigned char) | |||
| */ | */ | |||
| /* | /* | |||
| * This structure holds context information for an FNV64 hash | * This structure holds context information for an FNV64 hash | |||
| */ | */ | |||
| #ifdef FNV_64bitIntegers | #ifdef FNV_64bitIntegers | |||
| /* version if 64-bit integers supported */ | /* version if 64-bit integers supported */ | |||
| typedef struct FNV64context_s { | typedef struct FNV64context_s { | |||
| int Computed; /* state */ | int Computed; /* state */ | |||
| uint64_t Hash; | uint64_t Hash; | |||
| skipping to change at line 1718 ¶ | skipping to change at line 2089 ¶ | |||
| int Computed; /* state */ | int Computed; /* state */ | |||
| uint16_t Hash[FNV64size/2]; | uint16_t Hash[FNV64size/2]; | |||
| } FNV64context; | } FNV64context; | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| /* Function Prototypes: | /* Function Prototypes: | |||
| * | * | |||
| * FNV64string: hash a zero-terminated string not including | * FNV64string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV164stringBasis: also takes an offset_basis parameter | * FNV64stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV64block: hash a specified length byte vector | * FNV64block: hash a specified length byte vector | |||
| * FNV64blockBasis: also takes an offset_basis parameter | * FNV64blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV64file: hash the contents of a file | * FNV64file: hash the contents of a file | |||
| * FNV128fileBasis: also takes an offset_basis parameter | * FNV128fileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV64init: initializes an FNV64 context | * FNV64init: initializes an FNV64 context | |||
| * FNV64initBasis: initializes an FNV64 context with a | * FNV64initBasis: initializes an FNV64 context with a | |||
| * provided 8-byte vector basis | * provided 8-byte vector basis | |||
| skipping to change at line 1820 ¶ | skipping to change at line 2191 ¶ | |||
| uint64_t * const out ); | uint64_t * const out ); | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| } | } | |||
| #endif | #endif | |||
| #endif /* _FNV64_H_ */ | #endif /* _FNV64_H_ */ | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <sourcecode type="C" markers="true" name="FNV64.c"> | <!-- [rfced] Section 8.2.2: Please review the items listed under | |||
| <![CDATA[ | "Function Prototypes:" and under the "Hash is returned as an 8-byte | |||
| vector by the functions above. If 64-bit integers are supported" | ||||
| text in this section. Because it appears that the focus here is on | ||||
| "FNV64" parameters and there may have been some copy-paste issues in | ||||
| this section, please review the following, and advise: | ||||
| a) Because it appears that "FNV164stringBasis" should be | ||||
| "FNV64stringBasis", we updated accordingly. Please let us know | ||||
| if this is incorrect. | ||||
| Original: | ||||
| * FNV164stringBasis: also takes an offset_basis parameter | ||||
| Currently: | ||||
| * FNV64stringBasis: also takes an offset_basis parameter | ||||
| b) It appears that "FNV128fileBasis" and "FNV128filein" should be | ||||
| "FNV64fileBasis" and "FNV64filein". May we update accordingly? | ||||
| Original: | ||||
| * FNV64file: hash the contents of a file | ||||
| * FNV128fileBasis: also takes an offset_basis parameter | ||||
| * | ||||
| * FNV64init: initializes an FNV64 context | ||||
| * FNV64initBasis: initializes an FNV64 context with a | ||||
| * provided 8-byte vector basis | ||||
| * FNV64blockin: hash in a specified length byte vector | ||||
| * FNV64stringin: hash in a zero-terminated string not | ||||
| * including the terminating zero | ||||
| * FNV128filein: hash in the contents of a file | ||||
| * FNV64result: returns the hash value | ||||
| c) It appears that "FNV32INTstringBasis", "FNV32INTblockBasis", and | ||||
| "FNV32INTfileBasis" should be "FNV64INTstringBasis", | ||||
| "FNV64INTblockBasis", and "FNV64INTfileBasis". Should we update | ||||
| accordingly? | ||||
| Original: | ||||
| * FNV64INTstring: hash a zero-terminated string not including | ||||
| * the terminating zero | ||||
| * FNV32INTstringBasis: also takes an offset_basis parameter | ||||
| * | ||||
| * FNV64INTblock: hash a specified length byte vector | ||||
| * FNV32INTblockBasis: also takes an offset_basis parameter | ||||
| * | ||||
| * FNV64INTfile: hash the contents of a file | ||||
| * FNV32INTfileBasis: also takes an offset_basis parameter | ||||
| * | ||||
| * FNV64INTinitBasis: initializes an FNV32 context with a | ||||
| * provided 64-bit integer basis | ||||
| d) Should "FNV64INTinitBasis: initializes an FNV32 context" be | ||||
| "FNV64INTinitBasis: initializes an FNV64 context"? | ||||
| Original: | ||||
| FNV64INTinitBasis: initializes an FNV32 context with a --> | ||||
| <sourcecode type="c" markers="true" name="FNV64.c"><![CDATA[ | ||||
| //*************************** FNV64.c ****************************// | //*************************** FNV64.c ****************************// | |||
| //****************** See RFC NNNN for details ********************// | //****************** See RFC 9923 for details. *******************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| /* This file implements the FNV (Fowler, Noll, Vo) non-cryptographic | /* This file implements the FNV (Fowler/Noll/Vo) non-cryptographic | |||
| * hash function FNV-1a for 64-bit hashes. | * hash function FNV-1a for 64-bit hashes. | |||
| */ | */ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "FNVconfig.h" | #include "FNVconfig.h" | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV64.h" | #include "FNV64.h" | |||
| //***************************************************************** | //***************************************************************** | |||
| skipping to change at line 1927 ¶ | skipping to change at line 2355 ¶ | |||
| //***************************************************************** | //***************************************************************** | |||
| #ifdef FNV_64bitIntegers | #ifdef FNV_64bitIntegers | |||
| /* 64-bit FNV_prime = 2^40 + 2^8 + 0xb3 */ | /* 64-bit FNV_prime = 2^40 + 2^8 + 0xb3 */ | |||
| #define FNV64prime 0x00000100000001B3 | #define FNV64prime 0x00000100000001B3 | |||
| /* FNV64 hash a zero-terminated string not including the zero | /* FNV64 hash a zero-terminated string not including the zero | |||
| * to a 64-bit integer (64-bit) | * to a 64-bit integer (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64INTstring ( const char *in, uint64_t * const out ) { | int FNV64INTstring ( const char *in, uint64_t * const out ) { | |||
| return FNV64INTstringBasis (in, out, FNV64basis ); | return FNV64INTstringBasis ( in, out, FNV64basis ); | |||
| } /* end FNV64INTstring */ | } /* end FNV64INTstring */ | |||
| /* FNV64 hash a zero-terminated string not including the zero | /* FNV64 hash a zero-terminated string not including the zero | |||
| * to a 64-bit integer (64-bit) with a non-standard basis | * to a 64-bit integer (64-bit) with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64INTstringBasis ( const char *in, | int FNV64INTstringBasis ( const char *in, | |||
| uint64_t * const out, | uint64_t * const out, | |||
| uint64_t basis ) { | uint64_t basis ) { | |||
| uint64_t temp; | uint64_t temp; | |||
| uint8_t ch; | uint8_t ch; | |||
| skipping to change at line 2060 ¶ | skipping to change at line 2488 ¶ | |||
| for ( i = FNV64size-2; i>=0; --i ) | for ( i = FNV64size-2; i>=0; --i ) | |||
| temp = (temp<<8) + basis[i]; | temp = (temp<<8) + basis[i]; | |||
| for (; length > 0; length-- ) | for (; length > 0; length-- ) | |||
| temp = FNV64prime * ( temp ^ *in++ ); | temp = FNV64prime * ( temp ^ *in++ ); | |||
| for ( i=0; i<FNV64size; ++i ) | for ( i=0; i<FNV64size; ++i ) | |||
| out[i] = ((uint8_t *)&temp)[i]; | out[i] = ((uint8_t *)&temp)[i]; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64blockBasis */ | } /* end FNV64blockBasis */ | |||
| //***************************************************************** | //***************************************************************** | |||
| // Set of init, input, and output functions below | // Set of init, input, and output functions below | |||
| // to incrementally compute FNV64 | // to incrementally compute FNV64 | |||
| //***************************************************************** | //***************************************************************** | |||
| /* initialize context (64-bit) | /* initialize context (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64init( FNV64context * const ctx ) { | int FNV64init( FNV64context * const ctx ) { | |||
| return FNV64INTinitBasis ( ctx, FNV64basis ); | return FNV64INTinitBasis ( ctx, FNV64basis ); | |||
| } /* end FNV64init */ | } /* end FNV64init */ | |||
| /* initialize context with a provided 64-bit integer basis (64-bit) | /* initialize context with a provided 64-bit integer basis (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| skipping to change at line 2119 ¶ | skipping to change at line 2547 ¶ | |||
| break; | break; | |||
| default: | default: | |||
| return fnvStateError; | return fnvStateError; | |||
| } | } | |||
| for ( temp = ctx->Hash; length > 0; length-- ) | for ( temp = ctx->Hash; length > 0; length-- ) | |||
| temp = FNV64prime * ( temp ^ *in++ ); | temp = FNV64prime * ( temp ^ *in++ ); | |||
| ctx->Hash = temp; | ctx->Hash = temp; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64blockin */ | } /* end FNV64blockin */ | |||
| /* hash in a zero-terminated string not including the zero (64-bit) | /* hash in a zero-terminated string not including the zero (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64stringin ( FNV64context * const ctx, const char *in ) { | int FNV64stringin ( FNV64context * const ctx, const char *in ) { | |||
| uint64_t temp; | uint64_t temp; | |||
| uint8_t ch; | uint8_t ch; | |||
| if ( !ctx || !in ) | if ( !ctx || !in ) | |||
| return fnvNull; | return fnvNull; | |||
| switch ( ctx->Computed ) { | switch ( ctx->Computed ) { | |||
| case FNVinited+FNV64state: | case FNVinited+FNV64state: | |||
| ctx->Computed = FNVcomputed+FNV64state; | ctx->Computed = FNVcomputed+FNV64state; | |||
| skipping to change at line 2143 ¶ | skipping to change at line 2571 ¶ | |||
| default: | default: | |||
| return fnvStateError; | return fnvStateError; | |||
| } | } | |||
| temp = ctx->Hash; | temp = ctx->Hash; | |||
| while ( (ch = (uint8_t)*in++) ) | while ( (ch = (uint8_t)*in++) ) | |||
| temp = FNV64prime * ( temp ^ ch ); | temp = FNV64prime * ( temp ^ ch ); | |||
| ctx->Hash = temp; | ctx->Hash = temp; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64stringin */ | } /* end FNV64stringin */ | |||
| /* return hash as 64-bit int (64-bit) | /* return hash as 64-bit int (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64INTresult ( FNV64context * const ctx, | int FNV64INTresult ( FNV64context * const ctx, | |||
| uint64_t * const out ) { | uint64_t * const out ) { | |||
| if ( !ctx || !out ) | if ( !ctx || !out ) | |||
| return fnvNull; | return fnvNull; | |||
| if ( ctx->Computed != FNVcomputed+FNV64state ) | if ( ctx->Computed != FNVcomputed+FNV64state ) | |||
| return fnvStateError; | return fnvStateError; | |||
| ctx->Computed = FNVemptied+FNV64state; | ctx->Computed = FNVemptied+FNV64state; | |||
| *out = ctx->Hash; | *out = ctx->Hash; | |||
| ctx->Hash = 0; | ctx->Hash = 0; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64INTresult */ | } /* end FNV64INTresult */ | |||
| /* return hash as 8-byte vector (64-bit) | /* return hash as 8-byte vector (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64result ( FNV64context * const ctx, | int FNV64result ( FNV64context * const ctx, | |||
| uint8_t out[FNV64size] ) { | uint8_t out[FNV64size] ) { | |||
| if ( !ctx || !out ) | if ( !ctx || !out ) | |||
| return fnvNull; | return fnvNull; | |||
| if ( ctx->Computed != FNVcomputed+FNV64state ) | if ( ctx->Computed != FNVcomputed+FNV64state ) | |||
| return fnvStateError; | return fnvStateError; | |||
| ctx->Computed = FNVemptied+FNV64state; | ctx->Computed = FNVemptied+FNV64state; | |||
| for ( int i=0; i<FNV64size; ++i ) | for ( int i=0; i<FNV64size; ++i ) | |||
| out[i] = ((uint8_t *)&ctx->Hash)[i]; | out[i] = ((uint8_t *)&ctx->Hash)[i]; | |||
| skipping to change at line 2223 ¶ | skipping to change at line 2651 ¶ | |||
| /* 64-bit FNV_prime = 2^40 + 2^8 + 0xb3 */ | /* 64-bit FNV_prime = 2^40 + 2^8 + 0xb3 */ | |||
| /* #define FNV64prime 0x00000100000001B3 */ | /* #define FNV64prime 0x00000100000001B3 */ | |||
| #define FNV64primeX 0x01B3 | #define FNV64primeX 0x01B3 | |||
| #define FNV64shift 8 | #define FNV64shift 8 | |||
| /* FNV64 hash a zero-terminated string not including the zero | /* FNV64 hash a zero-terminated string not including the zero | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64string ( const char *in, uint8_t out[FNV64size] ) { | int FNV64string ( const char *in, uint8_t out[FNV64size] ) { | |||
| FNV64context ctx; | FNV64context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV64init (&ctx)) ) | if ( (error = FNV64init (&ctx)) ) | |||
| return error; | return error; | |||
| if ( (error = FNV64stringin (&ctx, in)) ) | if ( (error = FNV64stringin (&ctx, in)) ) | |||
| return error; | return error; | |||
| return FNV64result (&ctx, out); | return FNV64result (&ctx, out); | |||
| } /* end FNV64string */ | } /* end FNV64string */ | |||
| /* FNV64 hash a zero-terminated string not including the zero | /* FNV64 hash a zero-terminated string not including the zero | |||
| * with a non-standard offset_basis | * with a non-standard offset_basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64stringBasis ( const char *in, | int FNV64stringBasis ( const char *in, | |||
| uint8_t out[FNV64size], | uint8_t out[FNV64size], | |||
| const uint8_t basis[FNV64size] ) { | const uint8_t basis[FNV64size] ) { | |||
| FNV64context ctx; | FNV64context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV64initBasis (&ctx, basis)) ) | if ( (error = FNV64initBasis (&ctx, basis)) ) | |||
| return error; | return error; | |||
| if ( (error = FNV64stringin (&ctx, in)) ) | if ( (error = FNV64stringin (&ctx, in)) ) | |||
| return error; | return error; | |||
| return FNV64result (&ctx, out); | return FNV64result (&ctx, out); | |||
| } /* end FNV64stringBasis */ | } /* end FNV64stringBasis */ | |||
| /* FNV64 hash a counted block | /* FNV64 hash a counted block | |||
| ******************************************************************/ | ******************************************************************/ | |||
| skipping to change at line 2297 ¶ | skipping to change at line 2725 ¶ | |||
| if ( !ctx ) | if ( !ctx ) | |||
| return fnvNull; | return fnvNull; | |||
| ctx->Hash[0] = 0xCBF2; | ctx->Hash[0] = 0xCBF2; | |||
| ctx->Hash[1] = 0x9CE4; | ctx->Hash[1] = 0x9CE4; | |||
| ctx->Hash[2] = 0x8422; | ctx->Hash[2] = 0x8422; | |||
| ctx->Hash[3] = 0x2325; | ctx->Hash[3] = 0x2325; | |||
| ctx->Computed = FNVinited+FNV64state; | ctx->Computed = FNVinited+FNV64state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64init */ | } /* end FNV64init */ | |||
| /* initialize context with a non-standard basis (32-bit) | /* initialize context with a non-standard basis (32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64initBasis ( FNV64context * const ctx, | int FNV64initBasis ( FNV64context * const ctx, | |||
| const uint8_t basis[FNV64size] ) { | const uint8_t basis[FNV64size] ) { | |||
| if ( !ctx || !basis ) | if ( !ctx || !basis ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i < FNV64size/2; ++i ) { | for ( int i=0; i < FNV64size/2; ++i ) { | |||
| uint32_t temp = *basis++; | uint32_t temp = *basis++; | |||
| ctx->Hash[i] = ( temp<<8 ) + *basis++; | ctx->Hash[i] = ( temp<<8 ) + *basis++; | |||
| } | } | |||
| ctx->Computed = FNVinited+FNV64state; | ctx->Computed = FNVinited+FNV64state; | |||
| skipping to change at line 2418 ¶ | skipping to change at line 2846 ¶ | |||
| ctx->Computed = FNVemptied+FNV64state; | ctx->Computed = FNVemptied+FNV64state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64result */ | } /* end FNV64result */ | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| //***************************************************************** | //***************************************************************** | |||
| // END VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // END VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //***************************************************************** | //***************************************************************** | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <!-- [rfced] Section 8.2.2: Does "Null input/out pointer" mean | ||||
| "Null input/output pointer", "Null input pointer /out pointer", or | ||||
| something else? | ||||
| Original: | ||||
| return fnvNull; /* Null input/out pointer */ --> | ||||
| </section> | </section> | |||
| <section> | <section> | |||
| <name>FNV128 Code</name> | <name>FNV128 Code</name> | |||
| <t>The header and C source for 128-bit FNV-1a providing a byte | <t>The following code is the header and C source for 128-bit FNV-1a providing a byte | |||
| vector hash.</t> | vector hash.</t> | |||
| <sourcecode type="C" markers="true" name="FNV128.h"> | <sourcecode type="c" markers="true" name="FNV128.h"><![CDATA[ | |||
| <![CDATA[ | ||||
| //************************** FNV128.h ************************// | //************************** FNV128.h ************************// | |||
| //*************** See RFC NNNN for details. ******************// | //*************** See RFC 9923 for details. ******************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| #ifndef _FNV128_H_ | #ifndef _FNV128_H_ | |||
| #define _FNV128_H_ | #define _FNV128_H_ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| skipping to change at line 2545 ¶ | skipping to change at line 2979 ¶ | |||
| extern int FNV128result ( FNV128context * const, | extern int FNV128result ( FNV128context * const, | |||
| uint8_t out[FNV128size] ); | uint8_t out[FNV128size] ); | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| } | } | |||
| #endif | #endif | |||
| #endif /* _FNV128_H_ */ | #endif /* _FNV128_H_ */ | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <sourcecode type="C" markers="true" name="FNV128.c"> | <!-- [rfced] Sections 8.2.3, 8.2.4, 8.2.5, and 8.2.6: Please review | |||
| <![CDATA[ | the following, and let us know if any changes are needed: | |||
| a) Please confirm that the same text - "Hash is returned as an array | ||||
| of 8-bit unsigned integers" - is correct for all four sections. | ||||
| We ask because of "Hash is returned as a 4-byte vector by the | ||||
| functions above, and the following return a 32-bit unsigned integer" | ||||
| in Section 8.2.1 ("FNV32 Code"). | ||||
| b) Please search for instances of "This structure holds context | ||||
| information for an FNV", and let us know if the data that follows | ||||
| these lines is correct. The first and second instances appear to be | ||||
| OK, but we want to confirm that the data that follows the third, | ||||
| fourth, fifth, and sixth instances are also OK (i.e., should always | ||||
| indicate 64-bit integers; apologies if we are missing a statement | ||||
| that says support for 64-bit integers applies to all FNVs discussed | ||||
| in this document). | ||||
| c) Please search for instances of "version if", and confirm that | ||||
| the text should always be "version if 64-bit ...". --> | ||||
| <sourcecode type="c" markers="true" name="FNV128.c"><![CDATA[ | ||||
| //**************************** FNV128.c **************************// | //**************************** FNV128.c **************************// | |||
| //******************* See RFC NNNN for details *******************// | //******************* See RFC 9923 for details. ******************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| /* This file implements the FNV (Fowler, Noll, Vo) non-cryptographic | /* This file implements the FNV (Fowler/Noll/Vo) non-cryptographic | |||
| * hash function FNV-1a for 128-bit hashes. | * hash function FNV-1a for 128-bit hashes. | |||
| */ | */ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "FNVconfig.h" | #include "FNVconfig.h" | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV128.h" | #include "FNV128.h" | |||
| //***************************************************************** | //***************************************************************** | |||
| // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | |||
| //***************************************************************** | //***************************************************************** | |||
| /* FNV128 hash a zero-terminated string not including the zero | /* FNV128 hash a zero-terminated string not including the zero | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV128string ( const char *in, uint8_t out[FNV128size] ) { | int FNV128string ( const char *in, uint8_t out[FNV128size] ) { | |||
| FNV128context ctx; | FNV128context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV128init ( &ctx )) ) | if ( (error = FNV128init ( &ctx )) ) | |||
| return error; | return error; | |||
| skipping to change at line 2601 ¶ | skipping to change at line 3055 ¶ | |||
| if ( (error = FNV128stringin ( &ctx, in )) ) | if ( (error = FNV128stringin ( &ctx, in )) ) | |||
| return error; | return error; | |||
| return FNV128result ( &ctx, out ); | return FNV128result ( &ctx, out ); | |||
| } /* end FNV128stringBasis */ | } /* end FNV128stringBasis */ | |||
| /* FNV128 hash a counted block (64/32-bit) | /* FNV128 hash a counted block (64/32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV128block ( const void *vin, | int FNV128block ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV128size] ) { | uint8_t out[FNV128size] ) { | |||
| FNV128context ctx; | FNV128context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV128init ( &ctx )) ) | if ( (error = FNV128init ( &ctx )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV128blockin ( &ctx, vin, length )) ) | if ( (error = FNV128blockin ( &ctx, vin, length )) ) | |||
| return error; | return error; | |||
| return FNV128result ( &ctx, out ); | return FNV128result ( &ctx, out ); | |||
| } /* end FNV128block */ | } /* end FNV128block */ | |||
| /* FNV128 hash a counted block (64/32-bit) | /* FNV128 hash a counted block (64/32-bit) | |||
| skipping to change at line 2698 ¶ | skipping to change at line 3152 ¶ | |||
| fclose(fp); | fclose(fp); | |||
| return error; | return error; | |||
| } | } | |||
| error = ferror(fp); | error = ferror(fp); | |||
| fclose(fp); | fclose(fp); | |||
| if (error) return fnvBadParam; | if (error) return fnvBadParam; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV128filein */ | } /* end FNV128filein */ | |||
| //***************************************************************** | //***************************************************************** | |||
| // START VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | // START VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | |||
| //***************************************************************** | //***************************************************************** | |||
| #ifdef FNV_64bitIntegers | #ifdef FNV_64bitIntegers | |||
| /* 128-bit FNV_prime = 2^88 + 2^8 + 0x3b */ | /* 128-bit FNV_prime = 2^88 + 2^8 + 0x3b */ | |||
| /* 0x00000000 01000000 00000000 0000013B */ | /* 0x00000000 01000000 00000000 0000013B */ | |||
| #define FNV128primeX 0x013B | #define FNV128primeX 0x013B | |||
| #define FNV128shift 24 | #define FNV128shift 24 | |||
| //***************************************************************** | //***************************************************************** | |||
| // Set of init, input, and output functions below | // Set of init, input, and output functions below | |||
| skipping to change at line 2826 ¶ | skipping to change at line 3280 ¶ | |||
| for ( i = 3; i > 0; --i ) { | for ( i = 3; i > 0; --i ) { | |||
| temp[i-1] += temp[i] >> 32; | temp[i-1] += temp[i] >> 32; | |||
| temp[i] &= 0xFFFFFFFF; | temp[i] &= 0xFFFFFFFF; | |||
| } | } | |||
| } | } | |||
| for ( i=0; i<FNV128size/4; ++i ) | for ( i=0; i<FNV128size/4; ++i ) | |||
| ctx->Hash[i] = (uint32_t)temp[i]; | ctx->Hash[i] = (uint32_t)temp[i]; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV128stringin */ | } /* end FNV128stringin */ | |||
| /* return hash as 16-byte vector (64-bit) | /* return hash as 16-byte vector (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV128result ( FNV128context * const ctx, | int FNV128result ( FNV128context * const ctx, | |||
| uint8_t out[FNV128size] ) { | uint8_t out[FNV128size] ) { | |||
| if ( !ctx || !out ) | if ( !ctx || !out ) | |||
| return fnvNull; | return fnvNull; | |||
| if ( ctx->Computed != FNVcomputed+FNV128state ) | if ( ctx->Computed != FNVcomputed+FNV128state ) | |||
| return fnvStateError; | return fnvStateError; | |||
| for ( int i=0; i<FNV128size/4; ++i ) { | for ( int i=0; i<FNV128size/4; ++i ) { | |||
| out[4*i] = ctx->Hash[i] >> 24; | out[4*i] = ctx->Hash[i] >> 24; | |||
| out[4*i+1] = ctx->Hash[i] >> 16; | out[4*i+1] = ctx->Hash[i] >> 16; | |||
| skipping to change at line 2995 ¶ | skipping to change at line 3449 ¶ | |||
| out[2*i] = ctx->Hash[i] >> 8; | out[2*i] = ctx->Hash[i] >> 8; | |||
| out[2*i+1] = ctx->Hash[i]; | out[2*i+1] = ctx->Hash[i]; | |||
| ctx -> Hash[i] = 0; | ctx -> Hash[i] = 0; | |||
| } | } | |||
| ctx->Computed = FNVemptied+FNV128state; | ctx->Computed = FNVemptied+FNV128state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV128result */ | } /* end FNV128result */ | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| //****************************************************************** | //****************************************************************** | |||
| // END VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // END VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //****************************************************************** | //****************************************************************** | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| </section> | </section> | |||
| <section> | <section> | |||
| <name>FNV256 Code</name> | <name>FNV256 Code</name> | |||
| <t>The header and C source for 256-bit FNV-1a providing a byte | <t>The following code is the header and C source for 256-bit FNV-1a providing a byte | |||
| vector hash.</t> | vector hash.</t> | |||
| <sourcecode type="C" markers="true" name="FNV256.h"> | <sourcecode type="c" markers="true" name="FNV256.h"><![CDATA[ | |||
| <![CDATA[ | ||||
| //************************* FNV256.h ***********************// | //************************* FNV256.h ***********************// | |||
| //************** See RFC NNNN for details. *****************// | //************** See RFC 9923 for details. *****************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| #ifndef _FNV256_H_ | #ifndef _FNV256_H_ | |||
| #define _FNV256_H_ | #define _FNV256_H_ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| skipping to change at line 3064 ¶ | skipping to change at line 3517 ¶ | |||
| int Computed; /* state */ | int Computed; /* state */ | |||
| uint16_t Hash[FNV256size/2]; | uint16_t Hash[FNV256size/2]; | |||
| } FNV256context; | } FNV256context; | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| /* Function Prototypes: | /* Function Prototypes: | |||
| * | * | |||
| * FNV256string: hash a zero-terminated string not including | * FNV256string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV246stgringBasis: also takes an offset_basis parameter | * FNV256stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV256block: hash a specified length byte vector | * FNV256block: hash a specified length byte vector | |||
| * FNV256blockBasis: also takes an offset_basis parameter | * FNV256blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV256file: hash the contents of a file | * FNV256file: hash the contents of a file | |||
| * FNV256fileBasis: also takes an offset_basis parameter | * FNV256fileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV256init: initializes an FNV256 context | * FNV256init: initializes an FNV256 context | |||
| * FNV256initBasis: initializes an FNV256 context with a | * FNV256initBasis: initializes an FNV256 context with a | |||
| * provided 32-byte vector basis | * provided 32-byte vector basis | |||
| * FNV256blockin: hash in a specified length byte vector | * FNV256blockin: hash in a specified length byte vector | |||
| * FNV256stringin: hash in a zero-terminated string not | * FNV256stringin: hash in a zero-terminated string not | |||
| * including the terminating zero | * including the terminating zero | |||
| * FNV256filein: hash in the contents of a file | * FNV256filein: hash in the contents of a file | |||
| * FNV256result: returns the hash value | * FNV256result: returns the hash value | |||
| * | * | |||
| * Hash is returned as an array of 8-bit unsigned integers | * Hash is returned as an array of 8-bit unsigned integers | |||
| */ | */ | |||
| skipping to change at line 3126 ¶ | skipping to change at line 3579 ¶ | |||
| extern int FNV256result ( FNV256context * const, | extern int FNV256result ( FNV256context * const, | |||
| uint8_t out[FNV256size] ); | uint8_t out[FNV256size] ); | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| } | } | |||
| #endif | #endif | |||
| #endif /* _FNV256_H_ */ | #endif /* _FNV256_H_ */ | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <sourcecode type="C" markers="true" name="FNV256.c"> | <!-- [rfced] Sections 8.2.4, 8.2.5, and 8.2.6: As it appeared that | |||
| <![CDATA[ | "FNV246stgringBasis", "FMNV512filein", and "FMV1024fileBasis" should | |||
| be "FNV256stringBasis", "FNV512filein", and "FNV1024fileBasis", | ||||
| respectively, we updated accordingly. Please let us know if anything | ||||
| is incorrect. | ||||
| Original: | ||||
| * FNV246stgringBasis: also takes an offset_basis parameter | ||||
| ... | ||||
| * FMNV512filein: hash in the contents of a file | ||||
| ... | ||||
| } /* end FMV1024fileBasis */ | ||||
| Currently: | ||||
| * FNV256stringBasis: also takes an offset_basis parameter | ||||
| ... | ||||
| * FNV512filein: hash in the contents of a file | ||||
| ... | ||||
| } /* end FNV1024fileBasis */ --> | ||||
| <sourcecode type="c" markers="true" name="FNV256.c"><![CDATA[ | ||||
| //**************************** FNV256.c **************************// | //**************************** FNV256.c **************************// | |||
| //******************* See RFC NNNN for details *******************// | //******************* See RFC 9923 for details. ******************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| /* This file implements the FNV (Fowler, Noll, Vo) non-cryptographic | /* This file implements the FNV (Fowler/Noll/Vo) non-cryptographic | |||
| * hash function FNV-1a for 256-bit hashes. | * hash function FNV-1a for 256-bit hashes. | |||
| */ | */ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV256.h" | #include "FNV256.h" | |||
| //***************************************************************** | //***************************************************************** | |||
| // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | |||
| skipping to change at line 3280 ¶ | skipping to change at line 3752 ¶ | |||
| fclose(fp); | fclose(fp); | |||
| return error; | return error; | |||
| } | } | |||
| error = ferror(fp); | error = ferror(fp); | |||
| fclose(fp); | fclose(fp); | |||
| if (error) return fnvBadParam; | if (error) return fnvBadParam; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV256filein */ | } /* end FNV256filein */ | |||
| //***************************************************************** | //***************************************************************** | |||
| // START VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | // START VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | |||
| //***************************************************************** | //***************************************************************** | |||
| #ifdef FNV_64bitIntegers | #ifdef FNV_64bitIntegers | |||
| /* 256-bit FNV_prime = 2^168 + 2^8 + 0x63 */ | /* 256-bit FNV_prime = 2^168 + 2^8 + 0x63 */ | |||
| /* 0x0000000000000000 0000010000000000 | /* 0x0000000000000000 0000010000000000 | |||
| 0000000000000000 0000000000000163 */ | 0000000000000000 0000000000000163 */ | |||
| #define FNV256primeX 0x0163 | #define FNV256primeX 0x0163 | |||
| #define FNV256shift 8 | #define FNV256shift 8 | |||
| //***************************************************************** | //***************************************************************** | |||
| skipping to change at line 3431 ¶ | skipping to change at line 3903 ¶ | |||
| out[4*i+1] = ctx->Hash[i] >> 16; | out[4*i+1] = ctx->Hash[i] >> 16; | |||
| out[4*i+2] = ctx->Hash[i] >> 8; | out[4*i+2] = ctx->Hash[i] >> 8; | |||
| out[4*i+3] = ctx->Hash[i]; | out[4*i+3] = ctx->Hash[i]; | |||
| ctx -> Hash[i] = 0; | ctx -> Hash[i] = 0; | |||
| } | } | |||
| ctx->Computed = FNVemptied+FNV256state; | ctx->Computed = FNVemptied+FNV256state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV256result */ | } /* end FNV256result */ | |||
| //**************************************************************** | //**************************************************************** | |||
| // END VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | // END VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | |||
| //**************************************************************** | //**************************************************************** | |||
| #else /* FNV_64bitIntegers */ | #else /* FNV_64bitIntegers */ | |||
| //**************************************************************** | //**************************************************************** | |||
| // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //**************************************************************** | //**************************************************************** | |||
| /* version for when you only have 32-bit arithmetic | /* version for when you only have 32-bit arithmetic | |||
| *****************************************************************/ | *****************************************************************/ | |||
| /* 256-bit FNV_prime = 2^168 + 2^8 + 0x63 */ | /* 256-bit FNV_prime = 2^168 + 2^8 + 0x63 */ | |||
| /* 0x00000000 00000000 00000100 00000000 | /* 0x00000000 00000000 00000100 00000000 | |||
| 00000000 00000000 00000000 00000163 */ | 00000000 00000000 00000000 00000163 */ | |||
| #define FNV256primeX 0x0163 | #define FNV256primeX 0x0163 | |||
| #define FNV256shift 8 | #define FNV256shift 8 | |||
| skipping to change at line 3468 ¶ | skipping to change at line 3940 ¶ | |||
| if ( !ctx ) | if ( !ctx ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i<FNV256size/2; ++i ) | for ( int i=0; i<FNV256size/2; ++i ) | |||
| ctx->Hash[i] = FNV256basis[i]; | ctx->Hash[i] = FNV256basis[i]; | |||
| ctx->Computed = FNVinited+FNV256state; | ctx->Computed = FNVinited+FNV256state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV256init */ | } /* end FNV256init */ | |||
| /* initialize context with a provided 32-byte vector basis (32-bit) | /* initialize context with a provided 32-byte vector basis (32-bit) | |||
| *****************************************************************/ | ******************************************************************/ | |||
| int FNV256initBasis ( FNV256context * const ctx, | int FNV256initBasis ( FNV256context * const ctx, | |||
| const uint8_t basis[FNV256size] ) { | const uint8_t basis[FNV256size] ) { | |||
| if ( !ctx || !basis ) | if ( !ctx || !basis ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i < FNV256size/2; ++i ) { | for ( int i=0; i < FNV256size/2; ++i ) { | |||
| uint32_t temp = *basis++; | uint32_t temp = *basis++; | |||
| ctx->Hash[i] = ( temp<<8 ) + (*basis++); | ctx->Hash[i] = ( temp<<8 ) + (*basis++); | |||
| } | } | |||
| ctx->Computed = FNVinited+FNV256state; | ctx->Computed = FNVinited+FNV256state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| skipping to change at line 3526 ¶ | skipping to change at line 3998 ¶ | |||
| temp[i-1] += temp[i] >> 16; | temp[i-1] += temp[i] >> 16; | |||
| temp[i] &= 0xFFFF; | temp[i] &= 0xFFFF; | |||
| } | } | |||
| } | } | |||
| for ( i=0; i<FNV256size/2; ++i ) | for ( i=0; i<FNV256size/2; ++i ) | |||
| ctx->Hash[i] = temp[i]; | ctx->Hash[i] = temp[i]; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV256blockin */ | } /* end FNV256blockin */ | |||
| /* hash in a zero-terminated string not including the zero (32-bit) | /* hash in a zero-terminated string not including the zero (32-bit) | |||
| *****************************************************************/ | ******************************************************************/ | |||
| int FNV256stringin ( FNV256context * const ctx, const char *in ) { | int FNV256stringin ( FNV256context * const ctx, const char *in ) { | |||
| uint32_t temp[FNV256size/2]; | uint32_t temp[FNV256size/2]; | |||
| uint32_t temp2[6]; | uint32_t temp2[6]; | |||
| int i; | int i; | |||
| uint8_t ch; | uint8_t ch; | |||
| if ( !ctx || !in ) | if ( !ctx || !in ) | |||
| return fnvNull; | return fnvNull; | |||
| switch ( ctx->Computed ) { | switch ( ctx->Computed ) { | |||
| case FNVinited+FNV256state: | case FNVinited+FNV256state: | |||
| skipping to change at line 3584 ¶ | skipping to change at line 4056 ¶ | |||
| out[2*i] = ctx->Hash[i] >> 8; | out[2*i] = ctx->Hash[i] >> 8; | |||
| out[2*i+1] = ctx->Hash[i]; | out[2*i+1] = ctx->Hash[i]; | |||
| ctx->Hash[i] = 0; | ctx->Hash[i] = 0; | |||
| } | } | |||
| ctx->Computed = FNVemptied+FNV256state; | ctx->Computed = FNVemptied+FNV256state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV256result */ | } /* end FNV256result */ | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| //**************************************************************** | //**************************************************************** | |||
| // END VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // END VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //**************************************************************** | //**************************************************************** | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <!-- [rfced] Sections 8.2.4 and 8.2.6: Are these two extra lowercase | ||||
| "version for when you only have 32-bit arithmetic" entries still | ||||
| needed in this document? We ask because a "START VERSION FOR WHEN | ||||
| YOU ONLY HAVE 32-BIT ARITHMETIC" entry immediately precedes both | ||||
| of these lowercased entries, and the other three "START VERSION FOR | ||||
| WHEN YOU ONLY HAVE 32-BIT ARITHMETIC" entries (Sections 8.2.2, | ||||
| 8.2.3, and 8.2.5) don't have this extra entry. | ||||
| Original: | ||||
| /* version for when you only have 32-bit arithmetic | ||||
| ... | ||||
| /* version for when you only have 32-bit arithmetic --> | ||||
| </section> | </section> | |||
| <section> | <section> | |||
| <name>FNV512 Code</name> | <name>FNV512 Code</name> | |||
| <t>The header and C source for 512-bit FNV-1a providing a byte | <t>The following code is the header and C source for 512-bit FNV-1a providing a byte | |||
| vector hash.</t> | vector hash.</t> | |||
| <sourcecode type="C" markers="true" name="FNV512.h"> | <sourcecode type="c" markers="true" name="FNV512.h"><![CDATA[ | |||
| <![CDATA[ | ||||
| //************************* FNV512.h ***********************// | //************************* FNV512.h ***********************// | |||
| //************** See RFC NNNN for details. *****************// | //************** See RFC 9923 for details. *****************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| #ifndef _FNV512_H_ | #ifndef _FNV512_H_ | |||
| #define _FNV512_H_ | #define _FNV512_H_ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| skipping to change at line 3652 ¶ | skipping to change at line 4136 ¶ | |||
| typedef struct FNV512context_s { | typedef struct FNV512context_s { | |||
| int Computed; /* state */ | int Computed; /* state */ | |||
| uint16_t Hash[FNV512size/2]; | uint16_t Hash[FNV512size/2]; | |||
| } FNV512context; | } FNV512context; | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| /* Function Prototypes: | /* Function Prototypes: | |||
| * | * | |||
| * FNV512string: hash a zero-terminated string not including | * FNV512string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV512stringBasis: also takes an offset_basis parameter | * FNV512stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV512block: hash a specified length byte vector | * FNV512block: hash a specified length byte vector | |||
| * FNV512blockBasis: also takes an offset_basis parameter | * FNV512blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV512file: hash the contents of a file | * FNV512file: hash the contents of a file | |||
| * FNV512fileBasis: also takes an offset_basis parameter | * FNV512fileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV512init: initializes an FNV1024 context | * FNV512init: initializes an FNV1024 context | |||
| * FNV512initBasis: initializes an FNV1024 context with a | * FNV512initBasis: initializes an FNV1024 context with a | |||
| * provided 128-byte vector basis | * provided 128-byte vector basis | |||
| * FNV512blockin: hash in a specified length byte vector | * FNV512blockin: hash in a specified length byte vector | |||
| * FNV512stringin: hash in a zero-terminated string not | * FNV512stringin: hash in a zero-terminated string not | |||
| * including the terminating zero | * including the terminating zero | |||
| * FMNV512filein: hash in the contents of a file | * FNV512filein: hash in the contents of a file | |||
| * FNV512result: returns the hash value | * FNV512result: returns the hash value | |||
| * | * | |||
| * Hash is returned as an array of 8-bit unsigned integers | * Hash is returned as an array of 8-bit unsigned integers | |||
| */ | */ | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| extern "C" { | extern "C" { | |||
| #endif | #endif | |||
| /* FNV512 */ | /* FNV512 */ | |||
| skipping to change at line 3715 ¶ | skipping to change at line 4199 ¶ | |||
| extern int FNV512result ( FNV512context * const, | extern int FNV512result ( FNV512context * const, | |||
| uint8_t out[FNV512size] ); | uint8_t out[FNV512size] ); | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| } | } | |||
| #endif | #endif | |||
| #endif /* _FNV512_H_ */ | #endif /* _FNV512_H_ */ | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <sourcecode type="C" markers="true" name="FNV512.c"> | <!-- [rfced] Section 8.2.5: Should the two instances of | |||
| <![CDATA[ | "FNV1024 context" be "FNV512 context" in these lines, and should | |||
| "128-byte" be "64-byte"? | ||||
| Original: | ||||
| * FNV512init: initializes an FNV1024 context | ||||
| * FNV512initBasis: initializes an FNV1024 context with a | ||||
| * provided 128-byte vector basis --> | ||||
| <sourcecode type="c" markers="true" name="FNV512.c"><![CDATA[ | ||||
| //**************************** FNV512.c **************************// | //**************************** FNV512.c **************************// | |||
| //******************* See RFC NNNN for details *******************// | //******************* See RFC 9923 for details. ******************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| /* This file implements the FNV (Fowler, Noll, Vo) non-cryptographic | /* This file implements the FNV (Fowler/Noll/Vo) non-cryptographic | |||
| * hash function FNV-1a for 512-bit hashes. | * hash function FNV-1a for 512-bit hashes. | |||
| */ | */ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV512.h" | #include "FNV512.h" | |||
| //***************************************************************** | //***************************************************************** | |||
| // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | |||
| skipping to change at line 3781 ¶ | skipping to change at line 4273 ¶ | |||
| FNV512context ctx; | FNV512context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV512init ( &ctx )) ) | if ( (error = FNV512init ( &ctx )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV512blockin ( &ctx, vin, length)) ) | if ( (error = FNV512blockin ( &ctx, vin, length)) ) | |||
| return error; | return error; | |||
| return FNV512result ( &ctx, out ); | return FNV512result ( &ctx, out ); | |||
| } /* end FNV512block */ | } /* end FNV512block */ | |||
| /* FNV512 hash a counted block with a non-standard basis (64/32-bit) | /* FNV512 hash a counted block (64/32-bit) | |||
| * with a non-standard basis | ||||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV512blockBasis ( const void *vin, | int FNV512blockBasis ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV512size], | uint8_t out[FNV512size], | |||
| const uint8_t basis[FNV512size] ) { | const uint8_t basis[FNV512size] ) { | |||
| FNV512context ctx; | FNV512context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV512initBasis ( &ctx, basis )) ) | if ( (error = FNV512initBasis ( &ctx, basis )) ) | |||
| return error; | return error; | |||
| skipping to change at line 3868 ¶ | skipping to change at line 4361 ¶ | |||
| fclose(fp); | fclose(fp); | |||
| return error; | return error; | |||
| } | } | |||
| error = ferror(fp); | error = ferror(fp); | |||
| fclose(fp); | fclose(fp); | |||
| if (error) return fnvBadParam; | if (error) return fnvBadParam; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV512filein */ | } /* end FNV512filein */ | |||
| //***************************************************************** | //***************************************************************** | |||
| // START VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | // START VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | |||
| //***************************************************************** | //***************************************************************** | |||
| #ifdef FNV_64bitIntegers | #ifdef FNV_64bitIntegers | |||
| /* 512-bit FNV_prime = 2^344 + 2^8 + 0x57 = | /* 512-bit FNV_prime = 2^344 + 2^8 + 0x57 = | |||
| 0x0000000000000000 0000000000000000 | 0x0000000000000000 0000000000000000 | |||
| 0000000001000000 0000000000000000 | 0000000001000000 0000000000000000 | |||
| 0000000000000000 0000000000000000 | 0000000000000000 0000000000000000 | |||
| 0000000000000000 0000000000000157 */ | 0000000000000000 0000000000000157 */ | |||
| #define FNV512primeX 0x0157 | #define FNV512primeX 0x0157 | |||
| #define FNV512shift 24 | #define FNV512shift 24 | |||
| skipping to change at line 4022 ¶ | skipping to change at line 4515 ¶ | |||
| out[4*i+1] = ctx->Hash[i] >> 16; | out[4*i+1] = ctx->Hash[i] >> 16; | |||
| out[4*i+2] = ctx->Hash[i] >> 8; | out[4*i+2] = ctx->Hash[i] >> 8; | |||
| out[4*i+3] = ctx->Hash[i]; | out[4*i+3] = ctx->Hash[i]; | |||
| ctx -> Hash[i] = 0; | ctx -> Hash[i] = 0; | |||
| } | } | |||
| ctx->Computed = FNVemptied+FNV512state; | ctx->Computed = FNVemptied+FNV512state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV512result */ | } /* end FNV512result */ | |||
| //***************************************************************** | //***************************************************************** | |||
| // END VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | // END VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | |||
| //***************************************************************** | //***************************************************************** | |||
| #else /* FNV_64bitIntegers */ | #else /* FNV_64bitIntegers */ | |||
| //***************************************************************** | //***************************************************************** | |||
| // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //***************************************************************** | //***************************************************************** | |||
| /* 512-bit FNV_prime = 2^344 + 2^8 + 0x57 = | /* 512-bit FNV_prime = 2^344 + 2^8 + 0x57 = | |||
| 0x00000000 00000000 00000000 00000000 | 0x00000000 00000000 00000000 00000000 | |||
| 00000000 01000000 00000000 00000000 | 00000000 01000000 00000000 00000000 | |||
| 00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000 | |||
| 00000000 00000000 00000000 00000157 */ | 00000000 00000000 00000000 00000157 */ | |||
| #define FNV512primeX 0x0157 | #define FNV512primeX 0x0157 | |||
| #define FNV512shift 8 | #define FNV512shift 8 | |||
| skipping to change at line 4176 ¶ | skipping to change at line 4669 ¶ | |||
| out[2*i] = ctx->Hash[i] >> 8; | out[2*i] = ctx->Hash[i] >> 8; | |||
| out[2*i+1] = ctx->Hash[i]; | out[2*i+1] = ctx->Hash[i]; | |||
| ctx->Hash[i] = 0; | ctx->Hash[i] = 0; | |||
| } | } | |||
| ctx->Computed = FNVemptied+FNV512state; | ctx->Computed = FNVemptied+FNV512state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV512result */ | } /* end FNV512result */ | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| //***************************************************************** | //***************************************************************** | |||
| // END VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // END VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //***************************************************************** | //***************************************************************** | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| </section> | </section> | |||
| <section> | <section> | |||
| <name>FNV1024 Code</name> | <name>FNV1024 Code</name> | |||
| <t>The header and C source for 1024-bit FNV-1a providing a byte | <t>The following code is the header and C source for 1024-bit FNV-1a providing a byte | |||
| vector hash.</t> | vector hash.</t> | |||
| <sourcecode type="C" markers="true" name="FNV1024.h"> | <sourcecode type="c" markers="true" name="FNV1024.h"><![CDATA[ | |||
| <![CDATA[ | ||||
| //*********************** FNV1024.h ***********************// | //*********************** FNV1024.h ***********************// | |||
| //************* See RFC NNNN for details. *****************// | //************* See RFC 9923 for details. *****************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| #ifndef _FNV1024_H_ | #ifndef _FNV1024_H_ | |||
| #define _FNV1024_H_ | #define _FNV1024_H_ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| skipping to change at line 4241 ¶ | skipping to change at line 4733 ¶ | |||
| #else | #else | |||
| /* version if 64-bit integers NOT supported */ | /* version if 64-bit integers NOT supported */ | |||
| typedef struct FNV1024context_s { | typedef struct FNV1024context_s { | |||
| int Computed; /* state */ | int Computed; /* state */ | |||
| uint16_t Hash[FNV1024size/2]; | uint16_t Hash[FNV1024size/2]; | |||
| } FNV1024context; | } FNV1024context; | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| /* Function Prototypes: | /* Function Prototypes: | |||
| * | * | |||
| * FNV1024string: hash a zero-terminated string not including | * FNV1024string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV1024stringBasis: also takes an offset_basis parameter | * FNV1024stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV1024block: hash a specified length byte vector | * FNV1024block: hash a specified length byte vector | |||
| * FNV1024blockBasis: also takes an offset_basis parameter | * FNV1024blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV1024file: hash the contents of a file | * FNV1024file: hash the contents of a file | |||
| * FNV1024fileBasis: also takes an offset_basis parameter | * FNV1024fileBasis: also takes an offset_basis parameter | |||
| skipping to change at line 4307 ¶ | skipping to change at line 4799 ¶ | |||
| extern int FNV1024result ( FNV1024context * const, | extern int FNV1024result ( FNV1024context * const, | |||
| uint8_t out[FNV1024size] ); | uint8_t out[FNV1024size] ); | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| } | } | |||
| #endif | #endif | |||
| #endif /* _FNV1024_H_ */ | #endif /* _FNV1024_H_ */ | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <sourcecode type="C" markers="true" name="FNV1024.c"> | <sourcecode type="c" markers="true" name="FNV1024.c"><![CDATA[ | |||
| <![CDATA[ | ||||
| //************************** FNV1024.c **************************// | //************************** FNV1024.c **************************// | |||
| //****************** See RFC NNNN for details *******************// | //****************** See RFC 9923 for details. ******************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| /* This file implements the FNV (Fowler, Noll, Vo) non-cryptographic | /* This file implements the FNV (Fowler/Noll/Vo) non-cryptographic | |||
| * hash function FNV-1a for 1024-bit hashes. | * hash function FNV-1a for 1024-bit hashes. | |||
| */ | */ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV1024.h" | #include "FNV1024.h" | |||
| //***************************************************************** | //***************************************************************** | |||
| // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | |||
| skipping to change at line 4421 ¶ | skipping to change at line 4912 ¶ | |||
| FNV1024context e1024Context; | FNV1024context e1024Context; | |||
| int error; | int error; | |||
| if ( !out ) | if ( !out ) | |||
| return fnvNull; | return fnvNull; | |||
| if ( (error = FNV1024initBasis (&e1024Context, basis)) ) | if ( (error = FNV1024initBasis (&e1024Context, basis)) ) | |||
| return error; | return error; | |||
| if ( (error = FNV1024filein (&e1024Context, fname)) ) | if ( (error = FNV1024filein (&e1024Context, fname)) ) | |||
| return error; | return error; | |||
| return FNV1024result ( &e1024Context, out ); | return FNV1024result ( &e1024Context, out ); | |||
| } /* end FMV1024fileBasis */ | } /* end FNV1024fileBasis */ | |||
| /* hash in the contents of a file | /* hash in the contents of a file | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV1024filein ( FNV1024context * const e1024Context, | int FNV1024filein ( FNV1024context * const e1024Context, | |||
| const char *fname ) { | const char *fname ) { | |||
| FILE *fp; | FILE *fp; | |||
| long int i; | long int i; | |||
| char buf[1024]; | char buf[1024]; | |||
| int error; | int error; | |||
| skipping to change at line 4504 ¶ | skipping to change at line 4995 ¶ | |||
| if ( !ctx ) | if ( !ctx ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i<FNV1024size/4; ++i ) | for ( int i=0; i<FNV1024size/4; ++i ) | |||
| ctx->Hash[i] = FNV1024basis[i]; | ctx->Hash[i] = FNV1024basis[i]; | |||
| ctx->Computed = FNVinited+FNV1024state; | ctx->Computed = FNVinited+FNV1024state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV1024init */ | } /* end FNV1024init */ | |||
| /* initialize context with a provided 128-byte vector basis (64-bit) | /* initialize context with a provided 128-byte vector basis (64-bit) | |||
| ******************************************************************/ | *******************************************************************/ | |||
| int FNV1024initBasis ( FNV1024context * const ctx, | int FNV1024initBasis ( FNV1024context * const ctx, | |||
| const uint8_t basis[FNV1024size] ) { | const uint8_t basis[FNV1024size] ) { | |||
| if ( !ctx || !basis ) | if ( !ctx || !basis ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i < FNV1024size/4; ++i ) { | for ( int i=0; i < FNV1024size/4; ++i ) { | |||
| uint32_t temp = *basis++<<24; | uint32_t temp = *basis++<<24; | |||
| temp += *basis++<<16; | temp += *basis++<<16; | |||
| temp += *basis++<<8; | temp += *basis++<<8; | |||
| ctx->Hash[i] = temp + *basis++; | ctx->Hash[i] = temp + *basis++; | |||
| } | } | |||
| skipping to change at line 4623 ¶ | skipping to change at line 5114 ¶ | |||
| out[4*i+1] = ctx->Hash[i] >> 16; | out[4*i+1] = ctx->Hash[i] >> 16; | |||
| out[4*i+2] = ctx->Hash[i] >> 8; | out[4*i+2] = ctx->Hash[i] >> 8; | |||
| out[4*i+3] = ctx->Hash[i]; | out[4*i+3] = ctx->Hash[i]; | |||
| ctx -> Hash[i] = 0; | ctx -> Hash[i] = 0; | |||
| } | } | |||
| ctx->Computed = FNVemptied+FNV1024state; | ctx->Computed = FNVemptied+FNV1024state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV1024result */ | } /* end FNV1024result */ | |||
| //****************************************************************// | //****************************************************************// | |||
| // END VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | // END VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | |||
| //***************************************************************// | //****************************************************************// | |||
| #else /* FNV_64bitIntegers */ | #else /* FNV_64bitIntegers */ | |||
| //***************************************************************// | //****************************************************************// | |||
| // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //***************************************************************// | //****************************************************************// | |||
| /* version for when you only have 32-bit arithmetic | /* version for when you only have 32-bit arithmetic | |||
| ******************************************************************/ | ******************************************************************/ | |||
| /* | /* | |||
| 1024-bit FNV_prime = 2^680 + 2^8 + 0x8d = | 1024-bit FNV_prime = 2^680 + 2^8 + 0x8d = | |||
| 0x00000000 00000000 00000000 00000000 | 0x00000000 00000000 00000000 00000000 | |||
| 00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000 | |||
| 00000000 00000000 00000100 00000000 | 00000000 00000000 00000100 00000000 | |||
| 00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000 | |||
| skipping to change at line 4673 ¶ | skipping to change at line 5164 ¶ | |||
| if ( !ctx ) | if ( !ctx ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i<FNV1024size/2; ++i ) | for ( int i=0; i<FNV1024size/2; ++i ) | |||
| ctx->Hash[i] = FNV1024basis[i]; | ctx->Hash[i] = FNV1024basis[i]; | |||
| ctx->Computed = FNVinited+FNV1024state; | ctx->Computed = FNVinited+FNV1024state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV1024init */ | } /* end FNV1024init */ | |||
| /* initialize context with a provided 128-byte vector basis (32-bit) | /* initialize context with a provided 128-byte vector basis (32-bit) | |||
| ******************************************************************/ | *******************************************************************/ | |||
| int FNV1024initBasis ( FNV1024context * const ctx, | int FNV1024initBasis ( FNV1024context * const ctx, | |||
| const uint8_t basis[FNV1024size] ) { | const uint8_t basis[FNV1024size] ) { | |||
| if ( !ctx || !basis ) | if ( !ctx || !basis ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i < FNV1024size/2; ++i ) { | for ( int i=0; i < FNV1024size/2; ++i ) { | |||
| uint32_t temp = *basis++; | uint32_t temp = *basis++; | |||
| ctx->Hash[i] = ( temp<<8 ) + *basis++; | ctx->Hash[i] = ( temp<<8 ) + *basis++; | |||
| } | } | |||
| ctx->Computed = FNVinited+FNV1024state; | ctx->Computed = FNVinited+FNV1024state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| skipping to change at line 4789 ¶ | skipping to change at line 5280 ¶ | |||
| out[2*i] = ctx->Hash[i] >> 8; | out[2*i] = ctx->Hash[i] >> 8; | |||
| out[2*i+1] = ctx->Hash[i]; | out[2*i+1] = ctx->Hash[i]; | |||
| ctx->Hash[i] = 0; | ctx->Hash[i] = 0; | |||
| } | } | |||
| ctx->Computed = FNVemptied+FNV1024state; | ctx->Computed = FNVemptied+FNV1024state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV1024result */ | } /* end FNV1024result */ | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| //****************************************************************// | //****************************************************************// | |||
| // END VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // END VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //****************************************************************// | //****************************************************************// | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section> <!-- 8.3 --> | <section anchor="sec-8.3"> | |||
| <name>FNV Test Code</name> | <name>FNV Test Code</name> | |||
| <t>Below is source code for a test driver with a command line | <t>Below is source code for a test driver with a command line | |||
| interface documented in Section 8.1.3. By default, with no command | interface as documented in <xref target="sec-8.1.3"/>. By default, with no comma nd | |||
| line arguments, it runs tests of all FNV lengths.</t> | line arguments, it runs tests of all FNV lengths.</t> | |||
| <sourcecode type="C" markers="true" name="main.c"> | <sourcecode type="c" markers="true" name="main.c"><![CDATA[ | |||
| <![CDATA[ | ||||
| //************************* Main.c **************************// | //************************* Main.c **************************// | |||
| //*************** See RFC NNNN for details. *****************// | //*************** See RFC 9923 for details. *****************// | |||
| /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | /* Copyright (c) 2016, 2024, 2025 IETF Trust and the persons | |||
| * identified as authors of the code. All rights reserved. | * identified as authors of the code. All rights reserved. | |||
| * See fnv-private.h for terms of use and redistribution. | * See fnv-private.h for terms of use and redistribution. | |||
| */ | */ | |||
| #include <ctype.h> | #include <ctype.h> | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include <stdlib.h> | #include <stdlib.h> | |||
| #include <string.h> | #include <string.h> | |||
| #include <unistd.h> | #include <unistd.h> | |||
| #include <errno.h> | #include <errno.h> | |||
| /* To do a thorough test you need to run with | /* To do a thorough test, you need to run with | |||
| * FNV_64bitIntegers defined and with it undefined | * FNV_64bitIntegers defined and with it undefined | |||
| */ | */ | |||
| #include "FNVconfig.h" | #include "FNVconfig.h" | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV32.h" | #include "FNV32.h" | |||
| #include "FNV64.h" | #include "FNV64.h" | |||
| #include "FNV128.h" | #include "FNV128.h" | |||
| #include "FNV256.h" | #include "FNV256.h" | |||
| #include "FNV512.h" | #include "FNV512.h" | |||
| #include "FNV1024.h" | #include "FNV1024.h" | |||
| skipping to change at line 4844 ¶ | skipping to change at line 5334 ¶ | |||
| const char *errteststring = "foo"; | const char *errteststring = "foo"; | |||
| int Terr = -1; /* Total errors */ | int Terr = -1; /* Total errors */ | |||
| int verbose = 0; /* verbose flag */ | int verbose = 0; /* verbose flag */ | |||
| enum { FNV32selected = 0, FNV64selected, FNV128selected, | enum { FNV32selected = 0, FNV64selected, FNV128selected, | |||
| FNV256selected, FNV512selected, FNV1024selected, | FNV256selected, FNV512selected, FNV1024selected, | |||
| FNVnone = -1 } selected = FNVnone; | FNVnone = -1 } selected = FNVnone; | |||
| #define NTestBytes 3 | #define NTestBytes 3 | |||
| const uint8_t errtestbytes[NTestBytes] = { (uint8_t)1, | const uint8_t errtestbytes[NTestBytes] = { (uint8_t)1, | |||
| (uint8_t)2, (uint8_t)3 }; | (uint8_t)2, (uint8_t)3 }; | |||
| // initial teststring is null so initial result is offset_basis | // initial teststring is null, so initial result is offset_basis | |||
| const char *teststring[] = { | const char *teststring[] = { | |||
| "", | "", | |||
| "a", | "a", | |||
| "foobar", | "foobar", | |||
| "Hello!\x01\xFF\xED" | "Hello!\x01\xFF\xED" | |||
| }; | }; | |||
| #define NTstrings (sizeof(teststring)/sizeof(char *)) | #define NTstrings (sizeof(teststring)/sizeof(char *)) | |||
| // due to FNV-1 versus FNV1a, xor in final backslash separately | // due to FNV-1 versus FNV1a, xor in final backslash separately | |||
| const char BasisString[] = "chongo <Landon Curt Noll> /\\../"; | const char BasisString[] = "chongo <Landon Curt Noll> /\\../"; | |||
| FNV32context e32Context; | FNV32context e32Context; | |||
| uint32_t eUint32 = 42; | uint32_t eUint32 = 42; | |||
| #ifdef FNV_64bitIntegers | #ifdef FNV_64bitIntegers | |||
| uint64_t eUint64 = 42; | uint64_t eUint64 = 42; | |||
| #endif | #endif | |||
| FNV64context e64Context; | FNV64context e64Context; | |||
| FNV128context e128Context; | FNV128context e128Context; | |||
| FNV256context e256Context; | FNV256context e256Context; | |||
| FNV512context e512Context; | FNV512context e512Context; | |||
| FNV1024context e1024Context; | FNV1024context e1024Context; | |||
| uint8_t hash[FNV1024size]; /* largest size needed */ | uint8_t hash[FNV1024size]; /* largest size needed */ | |||
| uint8_t FakeBasis[FNV1024size]; | uint8_t FakeBasis[FNV1024size]; | |||
| uint8_t ZeroBasis[FNV1024size]; | uint8_t ZeroBasis[FNV1024size]; | |||
| char tempFileNameTemplate[] = "tmp.XXXXXXXXXX"; | char tempFileNameTemplate[] = "tmp.XXXXXXXXXX"; | |||
| const char *tempFileName = 0; | const char *tempFileName = 0; | |||
| //**************************************************************** | //**************************************************************** | |||
| // local prototypes in alphabetic order | // local prototypes in alphabetical order | |||
| //**************************************************************** | //**************************************************************** | |||
| void CommonTest ( void ); | void CommonTest ( void ); | |||
| void ErrTestReport ( void ); | void ErrTestReport ( void ); | |||
| int find_selected(const char *optarg); | int find_selected(const char *optarg); | |||
| void HexPrint ( int count, const uint8_t *ptr ); | void HexPrint ( int count, const uint8_t *ptr ); | |||
| void TestAll ( void ); | void TestAll ( void ); | |||
| void Test32 ( void ); | void Test32 ( void ); | |||
| void Test64 ( void ); | void Test64 ( void ); | |||
| void Test128 ( void ); | void Test128 ( void ); | |||
| void Test256 ( void ); | void Test256 ( void ); | |||
| skipping to change at line 4958 ¶ | skipping to change at line 5448 ¶ | |||
| FakeBasis[i] = (uint8_t)i; | FakeBasis[i] = (uint8_t)i; | |||
| } | } | |||
| if ( argc == 1 ) { // if no arguments | if ( argc == 1 ) { // if no arguments | |||
| TestAll(); | TestAll(); | |||
| if ( tempFileName ) | if ( tempFileName ) | |||
| unlink(tempFileName); | unlink(tempFileName); | |||
| exit(0); | exit(0); | |||
| } | } | |||
| // process command line options | // process command line options | |||
| // ***************************************************************** | //***************************************************************** | |||
| while ((option = getopt(argc, (char *const *)argv, ":af:ht:u:v")) | while ((option = getopt(argc, (char *const *)argv, ":af:ht:u:v")) | |||
| != -1) { | != -1) { | |||
| if ( verbose ) | if ( verbose ) | |||
| printf ( "Got option %c\n", option ); | printf ( "Got option %c\n", option ); | |||
| switch ( option ) { | switch ( option ) { | |||
| case 'a': // run all tests | case 'a': // run all tests | |||
| TestAll(); | TestAll(); | |||
| break; | break; | |||
| case 'f': // followed by name of file to hash | case 'f': // followed by name of file to hash | |||
| if ( selected == FNVnone ) { | if ( selected == FNVnone ) { | |||
| printf ( "No hash size selected.\n" ); | printf ( "No hash size selected.\n" ); | |||
| break; | break; | |||
| } | } | |||
| printf ( "FNV-%i Hash of contents of file '%s':\n", | printf ( "FNV-%i Hash of contents of file '%s':\n", | |||
| funcmap[selected].length, optarg ); | funcmap[selected].length, optarg ); | |||
| if ( funcmap[selected].Filefunc ( optarg, hash )) | if ( funcmap[selected].Filefunc ( optarg, hash )) | |||
| skipping to change at line 5029 ¶ | skipping to change at line 5519 ¶ | |||
| return 1; | return 1; | |||
| } /* end switch */ | } /* end switch */ | |||
| } /* end while */ | } /* end while */ | |||
| if ( ( option == -1 ) && verbose ) | if ( ( option == -1 ) && verbose ) | |||
| printf ( "No more options.\n" ); | printf ( "No more options.\n" ); | |||
| // Through all the options, now, if a size is set, encrypt any | // Through all the options, now, if a size is set, encrypt any | |||
| // other tokens on the command line | // other tokens on the command line | |||
| //****************************************************** | //****************************************************** | |||
| for ( i = optind; i < argc; ++i ) { | for ( i = optind; i < argc; ++i ) { | |||
| int rc; // return code | int rc; // return code | |||
| if ( selected == FNVnone ) { | if ( selected == FNVnone ) { | |||
| printf ( "No hash size selected.\n" ); | printf ( "No hash size selected.\n" ); | |||
| break; // out of for | break; // out of for | |||
| } | } | |||
| rc = funcmap[selected].Stringfunc(argv[i], hash); | rc = funcmap[selected].Stringfunc(argv[i], hash); | |||
| if ( rc ) | if ( rc ) | |||
| printf ( "FNV-%i of '%s' returns error %i\n", | printf ( "FNV-%i of '%s' returns error %i\n", | |||
| funcmap[selected].length, | funcmap[selected].length, | |||
| argv[i], rc ); | argv[i], rc ); | |||
| skipping to change at line 5087 ¶ | skipping to change at line 5577 ¶ | |||
| funcName, name, actual, expect ); | funcName, name, actual, expect ); | |||
| ++Terr; /* increment error count */ | ++Terr; /* increment error count */ | |||
| } | } | |||
| return actual; | return actual; | |||
| } /* end TestR */ | } /* end TestR */ | |||
| //**************************************************************** | //**************************************************************** | |||
| // General byte vector return value test | // General byte vector return value test | |||
| //**************************************************************** | //**************************************************************** | |||
| void TestNValue ( const char *subfunc, | void TestNValue ( const char *subfunc, | |||
| const char *string, //usually what was hashed | const char *string, // usually what was hashed | |||
| int N, | int N, | |||
| const uint8_t was[N], | const uint8_t was[N], | |||
| const uint8_t should[N] ) { | const uint8_t should[N] ) { | |||
| if ( memcmp ( was, should, N) != 0 ) { | if ( memcmp ( was, should, N ) != 0 ) { | |||
| ++Terr; | ++Terr; | |||
| printf ( "%s %s of '%s'", | printf ( "%s %s of '%s'", | |||
| funcName, subfunc, string ); | funcName, subfunc, string ); | |||
| printf ( " computed " ); | printf ( " computed " ); | |||
| HexPrint ( N, was ); | HexPrint ( N, was ); | |||
| printf ( ", expected " ); | printf ( ", expected " ); | |||
| HexPrint ( N, should ); | HexPrint ( N, should ); | |||
| printf ( ".\n" ); | printf ( ".\n" ); | |||
| } | } | |||
| else if ( verbose ) { | else if ( verbose ) { | |||
| skipping to change at line 5197 ¶ | skipping to change at line 5687 ¶ | |||
| funcmap[selected].Blockfunc ( errtestbytes, 1, | funcmap[selected].Blockfunc ( errtestbytes, 1, | |||
| (uint8_t *)0 ) ); | (uint8_t *)0 ) ); | |||
| TestR ( "blk1b", fnvNull, | TestR ( "blk1b", fnvNull, | |||
| funcmap[selected].BlockBasisfunc ( (uint8_t *)0, 1, | funcmap[selected].BlockBasisfunc ( (uint8_t *)0, 1, | |||
| hash, FakeBasis ) ); | hash, FakeBasis ) ); | |||
| TestR ( "blk2b", fnvBadParam, | TestR ( "blk2b", fnvBadParam, | |||
| funcmap[selected].BlockBasisfunc ( errtestbytes, -1, | funcmap[selected].BlockBasisfunc ( errtestbytes, -1, | |||
| hash, FakeBasis ) ); | hash, FakeBasis ) ); | |||
| TestR ( "blk3b", fnvNull, | TestR ( "blk3b", fnvNull, | |||
| funcmap[selected].BlockBasisfunc ( errtestbytes, 1, | funcmap[selected].BlockBasisfunc ( errtestbytes, 1, | |||
| (uint8_t *)0 , FakeBasis ) ); | (uint8_t *)0, FakeBasis ) ); | |||
| TestR ( "blk4b", fnvNull, | TestR ( "blk4b", fnvNull, | |||
| funcmap[selected].BlockBasisfunc ( errtestbytes, 1, | funcmap[selected].BlockBasisfunc ( errtestbytes, 1, | |||
| hash, (uint8_t *)0 ) ); | hash, (uint8_t *)0 ) ); | |||
| TestR ( "file1", fnvNull, | TestR ( "file1", fnvNull, | |||
| funcmap[selected].Filefunc ( (char *)0, hash )); | funcmap[selected].Filefunc ( (char *)0, hash )); | |||
| TestR ( "file2", fnvNull, | TestR ( "file2", fnvNull, | |||
| funcmap[selected].Filefunc ( "foo.txt", (uint8_t *)0 )); | funcmap[selected].Filefunc ( "foo.txt", (uint8_t *)0 )); | |||
| TestR ( "file1b", fnvNull, | TestR ( "file1b", fnvNull, | |||
| funcmap[selected].FileBasisfunc ( (char *)0, hash, | funcmap[selected].FileBasisfunc ( (char *)0, hash, | |||
| FakeBasis )); | FakeBasis )); | |||
| skipping to change at line 5271 ¶ | skipping to change at line 5761 ¶ | |||
| STRIN ( &CTX, errteststring ) ); | STRIN ( &CTX, errteststring ) ); | |||
| #define TestFilein(FLIN,CTX,CTXT) \ | #define TestFilein(FLIN,CTX,CTXT) \ | |||
| TestR ( "file1", fnvNull, FLIN ( (CTXT *)0, errteststring ) );\ | TestR ( "file1", fnvNull, FLIN ( (CTXT *)0, errteststring ) );\ | |||
| TestR ( "file2", fnvNull, FLIN ( &CTX, (char *)0 ) ); \ | TestR ( "file2", fnvNull, FLIN ( &CTX, (char *)0 ) ); \ | |||
| TestR ( "file3", fnvStateError, \ | TestR ( "file3", fnvStateError, \ | |||
| FLIN ( &CTX, errteststring ) ); | FLIN ( &CTX, errteststring ) ); | |||
| #define TestResult(RSLT,CTX,CTXT) \ | #define TestResult(RSLT,CTX,CTXT) \ | |||
| TestR ( "result1", fnvNull, RSLT ( (CTXT *)0, hash ) ); \ | TestR ( "result1", fnvNull, RSLT ( (CTXT *)0, hash ) ); \ | |||
| TestR ( "result2", fnvNull, RSLT ( &CTX, (uint8_t *)0 ) ); \ | TestR ( "result2", fnvNull, RSLT ( &CTX, (uint8_t *)0 ) ); \ | |||
| TestR ( "result3", fnvStateError, \ | TestR ( "result3", fnvStateError, \ | |||
| FNV128result ( &e128Context, hash ) ); | FNV128result ( &e128Context, hash ) ); | |||
| // test return values for INT versions including non-std basis | // test return values for INT versions including non-std basis | |||
| //************************************************************* | //************************************************************* | |||
| #define TestINT(STRINT,STRINTB,BLKINT,BLKINTB,INITINTB, \ | #define TestINT(STRINT,STRINTB,BLKINT,BLKINTB,INITINTB, \ | |||
| INTV,INTVT,ctxT) \ | INTV,INTVT,ctxT) \ | |||
| TestR ( "string1i", fnvNull, STRINT ( (char *)0, &INTV ) ); \ | TestR ( "string1i", fnvNull, STRINT ( (char *)0, &INTV ) ); \ | |||
| TestR ( "string2i", fnvNull, \ | TestR ( "string2i", fnvNull, \ | |||
| STRINT ( errteststring, (INTVT *)0 ) ); \ | STRINT ( errteststring, (INTVT *)0 ) ); \ | |||
| TestR ("string3i", fnvNull, STRINTB ((char *)0, &INTV, INTV));\ | TestR ("string3i", fnvNull, STRINTB ((char *)0, &INTV, INTV));\ | |||
| TestR ( "string4i", fnvNull, \ | TestR ( "string4i", fnvNull, \ | |||
| skipping to change at line 5301 ¶ | skipping to change at line 5791 ¶ | |||
| BLKINTB ( (uint8_t *)0, 1, &INTV, INTV ) ); \ | BLKINTB ( (uint8_t *)0, 1, &INTV, INTV ) ); \ | |||
| TestR ( "block5i", fnvBadParam, \ | TestR ( "block5i", fnvBadParam, \ | |||
| BLKINTB ( errtestbytes, -1, &INTV, INTV ) ); \ | BLKINTB ( errtestbytes, -1, &INTV, INTV ) ); \ | |||
| TestR ( "block6i", fnvNull, \ | TestR ( "block6i", fnvNull, \ | |||
| BLKINTB ( errtestbytes, 1, (INTVT *)0, INTV ) ); \ | BLKINTB ( errtestbytes, 1, (INTVT *)0, INTV ) ); \ | |||
| TestR ("initBasis1i", fnvNull, INITINTB ( (ctxT *)0, INTV )); | TestR ("initBasis1i", fnvNull, INITINTB ( (ctxT *)0, INTV )); | |||
| #define TestINTrf(RSLTINT,FILEINT,FILEINTB, \ | #define TestINTrf(RSLTINT,FILEINT,FILEINTB, \ | |||
| ctx,ctxT,INTV,INTVT) \ | ctx,ctxT,INTV,INTVT) \ | |||
| TestR ( "result1i", fnvNull, RSLTINT ( (ctxT *)0, &INTV ) ); \ | TestR ( "result1i", fnvNull, RSLTINT ( (ctxT *)0, &INTV ) ); \ | |||
| TestR ( "result2i", fnvNull, RSLTINT ( &ctx, (INTVT *)0 ) ); \ | TestR ( "result2i", fnvNull, RSLTINT ( &ctx, (INTVT *)0 ) ); \ | |||
| TestR ( "result3i", fnvStateError, RSLTINT ( &ctx, &INTV ) );\ | TestR ( "result3i", fnvStateError, RSLTINT ( &ctx, &INTV ) ); \ | |||
| TestR ( "file1i", fnvNull, FILEINT ( (char *)0, &INTV )); \ | TestR ( "file1i", fnvNull, FILEINT ( (char *)0, &INTV )); \ | |||
| TestR ( "file2i", fnvNull, FILEINT ( "foo.txt", (INTVT *)0 ));\ | TestR ( "file2i", fnvNull, FILEINT ( "foo.txt", (INTVT *)0 ));\ | |||
| TestR ("file3i", fnvNull, FILEINTB ( (char *)0, &INTV, INTV));\ | TestR ("file3i", fnvNull, FILEINTB ( (char *)0, &INTV, INTV));\ | |||
| TestR ( "file4i", fnvNull, \ | TestR ( "file4i", fnvNull, \ | |||
| FILEINTB ( "foo.txt", (INTVT *)0, INTV )); | FILEINTB ( "foo.txt", (INTVT *)0, INTV )); | |||
| // test to calculate standard basis from basis zero FNV-1 | // test to calculate standard basis from basis zero FNV-1 | |||
| // depends on zero basis making the initial multiply a no-op | // depends on zero basis making the initial multiply a no-op | |||
| //***************************** | //***************************** | |||
| #define BasisZero(STRING,SIZ,VALUE) \ | #define BasisZero(STRING,SIZ,VALUE) \ | |||
| skipping to change at line 6059 ¶ | skipping to change at line 6549 ¶ | |||
| FNV1024result, FNV1024initBasis, | FNV1024result, FNV1024initBasis, | |||
| FNV1024stringin,FNV1024size,FNV1024svalues) | FNV1024stringin,FNV1024size,FNV1024svalues) | |||
| /* now try testing file hash */ | /* now try testing file hash */ | |||
| TestFILEHash(FNV1024file,FNV1024svalues,FNV1024size) | TestFILEHash(FNV1024file,FNV1024svalues,FNV1024size) | |||
| } | } | |||
| ValueTestReport (); | ValueTestReport (); | |||
| } /* end Test1024 */ | } /* end Test1024 */ | |||
| ]]> | ]]> | |||
| </sourcecode> | </sourcecode> | |||
| <!-- [rfced] Section 8.3: | ||||
| a) Should the two instances of "follow by" be "followed by"? If no, | ||||
| are they instructions and some words are missing (e.g., | ||||
| "follow the ______ by size of ...")? | ||||
| We ask because of "case 'f': // followed by name of file to hash" | ||||
| a few lines earlier. | ||||
| Original: | ||||
| case 't': // follow by size of FNV to test, 0->all | ||||
| ... | ||||
| case 'u': // follow by size of FNV to use | ||||
| b) Should the spacing be adjusted here as suggested? | ||||
| Original: | ||||
| FNV32INTfile ( | ||||
| WriteTemp(teststring[i], iLen), | ||||
| &eUint32 ) | ||||
| ); | ||||
| ... | ||||
| FNV64INTfile ( | ||||
| WriteTemp(teststring[i], iLen), | ||||
| &eUint64 ) | ||||
| ); | ||||
| Suggested: | ||||
| FNV32INTfile ( WriteTemp(teststring[i], iLen), | ||||
| &eUint32 ) ); | ||||
| ... | ||||
| FNV64INTfile ( WriteTemp(teststring[i], iLen), | ||||
| &eUint64 ) ); --> | ||||
| </section> | </section> | |||
| <section> <!-- 8.4 --> | <section anchor="sec-8.4"> | |||
| <name>Makefile</name> | <name>Makefile</name> | |||
| <t>Below is a simple makefile to produce and run the test program or | <t>Below is a simple makefile to produce and run the test program or | |||
| to provide a library with all the FNV functions supplied in it.</t> | to provide a library with all the FNV functions supplied in it.</t> | |||
| <t>WARNING: When actually using the following as a makefile, the | <t>WARNING: When actually using the following as a makefile, the | |||
| five character sequence "<TAB>" must be changed to a tab (0x09) | five-character sequence "<TAB>" must be changed to a tab (0x09) | |||
| character!</t> | character!</t> | |||
| <sourcecode type="makefile" markers="true" name="makefile"> | <sourcecode type="makefile" markers="true" name="makefile"><![CDATA[ | |||
| # Makefile for fnv | # Makefile for fnv | |||
| # If you extract this file from RFC NNNN, the five character sequence | # If you extract this file from RFC 9923, the five-character sequence | |||
| # <TAB> below must be replace with a tab (0x09) character. | # <TAB> below must be replaced with a tab (0x09) character. | |||
| explanation: | explanation: | |||
| <TAB>@echo Choose one of the following make targets: | <TAB>@echo Choose one of the following make targets: | |||
| <TAB>@echo make FNVhash -- test program | <TAB>@echo make FNVhash -- test program | |||
| <TAB>@echo make libfnv.a -- library you can use | <TAB>@echo make libfnv.a -- library you can use | |||
| <TAB>@echo make clean -- removes all of the built targets | <TAB>@echo make clean -- removes all of the built targets | |||
| SRC=FNV1024.c FNV128.c FNV256.c FNV32.c FNV512.c FNV64.c | SRC=FNV1024.c FNV128.c FNV256.c FNV32.c FNV512.c FNV64.c | |||
| HDR=FNV32.h FNV64.h FNV128.h FNV256.h FNV512.h FNV1024.h \ | HDR=FNV32.h FNV64.h FNV128.h FNV256.h FNV512.h FNV1024.h \ | |||
| <TAB>FNVErrorCodes.h FNVconfig.h fnv-private.h | <TAB>FNVErrorCodes.h FNVconfig.h fnv-private.h | |||
| OBJ=$(SRC:.c=.o) | OBJ=$(SRC:.c=.o) | |||
| CFLAGS=-Wall | CFLAGS=-Wall | |||
| AR=ar | AR=ar | |||
| ARFLAGS= rcs | ARFLAGS= rcs | |||
| FNVhash: libfnv.a main.c | FNVhash: libfnv.a main.c | |||
| <TAB>$(CC) $(CFLAGS) -o FNVhash main.c libfnv.a | <TAB>$(CC) $(CFLAGS) -o FNVhash main.c libfnv.a | |||
| libfnv.a: $(SRC) $(HDR) | libfnv.a: $(SRC) $(HDR) | |||
| <TAB>rm -f libfnv.a *.o | <TAB>rm -f libfnv.a *.o | |||
| <TAB>$(CC) $(CFLAGS) -c $(SRC) | <TAB>$(CC) $(CFLAGS) -c $(SRC) | |||
| <TAB>$(AR) $(ARFLAGS) libfnv.a $(OBJ) | <TAB>$(AR) $(ARFLAGS) libfnv.a $(OBJ) | |||
| clean: | clean: | |||
| <TAB>rm -rf libfnv.a FNVhash *.o | <TAB>rm -rf libfnv.a FNVhash *.o | |||
| </sourcecode> | ]]></sourcecode> | |||
| <!-- [rfced] Section 8.4: Would you like to order the list of .c | ||||
| files by FNV size (and by their placement in the body of the | ||||
| document), as was done for the "HDR=" line? | ||||
| We have the same question re. the list of .h files in the <TAB> line. | ||||
| Original: | ||||
| SRC=FNV1024.c FNV128.c FNV256.c FNV32.c FNV512.c FNV64.c | ||||
| ... | ||||
| <TAB>FNVErrorCodes.h FNVconfig.h fnv-private.h | ||||
| Possibly: | ||||
| SRC=FNV32.c FNV64.c FNV128.c FNV256.c FNV512.c FNV1024.c | ||||
| ... | ||||
| <TAB>FNVconfig.h FNVErrorCodes.h fnv-private.h --> | ||||
| </section> | </section> | |||
| </section> <!-- 8. --> | </section> | |||
| <section anchor="iana"> <!-- 9. --> | <section anchor="iana"> | |||
| <name>IANA Considerations</name> | <name>IANA Considerations</name> | |||
| <t>This document requires no IANA Actions.</t> | <t>This document has no IANA actions.</t> | |||
| </section> <!-- 9. --> | </section> | |||
| </middle> | </middle> | |||
| <!-- ____________________BACK_MATTER____________________ --> | ||||
| <back> | <back> | |||
| <displayreference target="I-D.ietf-bfd-secure-sequence-numbers" to="ISAAC-Auth"/ | ||||
| > | ||||
| <references> | ||||
| <name>References</name> | ||||
| <references> | <references> | |||
| <name>Normative References</name> | <name>Normative References</name> | |||
| <reference anchor="C"> | <reference anchor="C"> | |||
| <front> | <front> | |||
| <title>The C Programming Language, 2nd Edition</title> | <title>The C Programming Language, 2nd Edition</title> | |||
| <author fullname="Brian W. Kernighan" initials="B." | <author fullname="Brian W. Kernighan" initials="B. W." | |||
| surname="Kernighan"> | surname="Kernighan"> | |||
| <organization>AT&T Bell Laboratories</organization> | <organization>AT&T Bell Laboratories</organization> | |||
| </author> | </author> | |||
| <author fullname="Denis M. Ritchie" initials="D." | <author fullname="Dennis M. Ritchie" initials="D. M." | |||
| surname="Ritchie"> | surname="Ritchie"> | |||
| <organization>AT&T Bell Laboratories</organization> | <organization>AT&T Bell Laboratories</organization> | |||
| </author> | </author> | |||
| <date year="1978"/> | <date year="1988"/> | |||
| </front> | </front> | |||
| <seriesInfo name="ISBN-10" value="0-13-110362-8"/> | <seriesInfo name="ISBN-10" value="0-13-110362-8"/> | |||
| <seriesInfo name="ISBN-13" value="978-0131103627"/> | <seriesInfo name="ISBN-13" value="978-0131103627"/> | |||
| </reference> | </reference> | |||
| <xi:include | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.0020.xml" | |||
| href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.0020.xml"/> | /> | |||
| <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" | ||||
| /> | ||||
| <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" | ||||
| /> | ||||
| </references> | </references> | |||
| <references> | <references> | |||
| <name>Informative References</name> | <name>Informative References</name> | |||
| <reference anchor="BASIC" | <reference anchor="BASIC" target="http://www.isthe.com/chongo/tech/comp/fnv/inde | |||
| target="http://www.isthe.com/chongo/tech/comp/fnv/index.html#PowerBASIC"> | x.html#PowerBASIC"> | |||
| <front> | <front> | |||
| <title>FNV32 PowerBASIC in line x86 assembler</title> | <title>FNV32 PowerBASIC inline x86 assembler</title> | |||
| <author fullname="Wayne Diamond" initials="W." | <author fullname="Wayne Diamond" initials="W." | |||
| surname="Diamond"/> | surname="Diamond"/> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="BFDseq" | <!-- draft-ietf-bfd-secure-sequence-numbers (IESG Evaluation::AD Followup) --> | |||
| target="draft-ietf-bfd-secure-sequence-numbers-09.txt"> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-bfd | |||
| <front> | -secure-sequence-numbers.xml"/> | |||
| <title>Secure BFD Sequence Numbers</title> | ||||
| <author fullname="Mahesh Jethanandani" initials="M." | ||||
| surname="Jethanandani"> | ||||
| <organization>Kloud Services</organization> | ||||
| <address> | ||||
| <email>mjethanandani@gmail.com</email> | ||||
| </address> | ||||
| </author> | ||||
| <author fullname="Sonal Agarwal" initials="S." | ||||
| surname="Agarwal"> | ||||
| <organization>Cisco Systems, Inc</organization> | ||||
| <address> | ||||
| <email>agarwaso@cisco.com</email> | ||||
| <uri>www.cisco.com</uri> | ||||
| </address> | ||||
| </author> | ||||
| <author fullname="Ashesh Mishra" initials="A." | ||||
| surname="Mishra"> | ||||
| <organization>O3b Networks</organization> | ||||
| <address> | ||||
| <email>mishra.ashesh@gmail.com</email> | ||||
| </address> | ||||
| </author> | ||||
| <author fullname="Ankur Saxena" initials="A." | ||||
| surname="Saxena"> | ||||
| <organization>Ciena Corporation</organization> | ||||
| <address> | ||||
| <email>ankurpsaxena@gmail.com</email> | ||||
| </address> | ||||
| </author> | ||||
| <author fullname="Alan DeKok" initials="A." | ||||
| surname="DeKok"> | ||||
| <organization>Network RADIUS SARL</organization> | ||||
| <address> | ||||
| <email>aland@freeradius.org</email> | ||||
| </address> | ||||
| </author> | ||||
| <date year="2022" month="March" day="22"/> | ||||
| </front> | ||||
| </reference> | ||||
| <reference anchor="calc" | <reference anchor="calc" target="http://www.isthe.com/chongo/tech/comp/calc/inde | |||
| target="http://www.isthe.com/chongo/tech/comp/calc/index.html"> | x.html"> | |||
| <front> | <front> | |||
| <title>Calc - C-style arbitrary precision calculator</title> | <title>Calc - C-style arbitrary precision calculator</title> | |||
| <author fullname="David I. Bell" initials="D." | <author fullname="David I. Bell" initials="D." | |||
| surname="Bell"/> | surname="Bell"/> | |||
| <author fullname="Landon Curt Noll" initials="L." | <author fullname="Landon Curt Noll" initials="L." | |||
| surname="Noll"/> | surname="Noll"/> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="Cohesia" | <!-- [rfced] References: We do not see David Bell mentioned on the | |||
| target="http://www.cohesia.com/"> | page provided for [calc]. Please confirm that this listing is | |||
| correct. | ||||
| Original: | ||||
| [calc] Bell, D. and L. Noll, "Calc - C-style arbitrary precision | ||||
| calculator", | ||||
| <http://www.isthe.com/chongo/tech/comp/calc/index.html>. --> | ||||
| <reference anchor="Cohesia" target="http://www.cohesia.com/"> | ||||
| <front> | <front> | |||
| <title>Cohesia website</title> | <title>Cohesia website</title> | |||
| <author> | <author> | |||
| <organization>Cohesia</organization> | <organization>Cohesia</organization> | |||
| </author> | </author> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="deliantra" | <!-- [rfced] References: The provided link for [Cohesia] steers to | |||
| target="http://www.deliantra.net/"> | <https://cohesia.com/>, which is a business financing site. We could | |||
| not find a relationship to the bullet item in Section 1.2. Should a | ||||
| different website be listed here? | ||||
| Original: | ||||
| * [Cohesia] MASS project server collision avoidance, | ||||
| ... | ||||
| [Cohesia] Cohesia, "Cohesia website", <http://www.cohesia.com/>. --> | ||||
| <reference anchor="deliantra" target="http://www.deliantra.net/"> | ||||
| <front> | <front> | |||
| <title>Deliantra MMORPG</title> | <title>Deliantra MMORPG</title> | |||
| <author> | <author> | |||
| <organization>The Deliantra Team</organization> | <organization>The Deliantra Team</organization> | |||
| </author> | </author> | |||
| <date year="2016"/> | <date year="2016"/> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <!-- [rfced] References: We see "NOTICE (2022-10-16): ...", re. a | ||||
| new server, at the top of the provided page for [deliantra]. Should | ||||
| this listing be updated to reflect the notice or was this a temporary | ||||
| situation that no longer applies? | ||||
| Original: | ||||
| [deliantra] | ||||
| The Deliantra Team, "Deliantra MMORPG", 2016, | ||||
| <http://www.deliantra.net/>. | ||||
| Possibly (if the notice is still relevant): | ||||
| [deliantra] | ||||
| The Deliantra Team, "Deliantra MMORPG", 16 October | ||||
| 2022, <http://www.deliantra.net/>. --> | ||||
| <reference anchor="fasmlab" | <reference anchor="fasmlab" | |||
| target="https://sourceforge.net/projects/fasmlab/"> | target="https://sourceforge.net/projects/fasmlab/"> | |||
| <front> | <front> | |||
| <title>Integrated Development Environment</title> | <title>Integrated Development Environments</title> | |||
| <author> | <author> | |||
| <organization>Fasmlab</organization> | <organization>Fasmlab</organization> | |||
| </author> | </author> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="FIPS202" | <reference anchor="FIPS202" target="https://nvlpubs.nist.gov/nistpubs/FI | |||
| target="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf"> | PS/NIST.FIPS.202.pdf"> | |||
| <front> | <front> | |||
| <title>SHA-3 Standard: Permutation-Based Hash and Extendable | <title>SHA-3 Standard: Permutation-Based Hash and Extendable-Output | |||
| Output Functions</title> | Functions</title> | |||
| <author> | <author> | |||
| <organization>National Institute of Standards and | <organization abbrev="NIST">National Institute of Standards and Te | |||
| Technology</organization> | chnology (NIST) | |||
| </author> | </organization> | |||
| <date year="2015" month="8"/> | </author> | |||
| </front> | <date month="August" year="2015"/> | |||
| <seriesInfo name="Federal Information Processing Standards | </front> | |||
| Publicsation" value="FIPS PUB 202"/> | <seriesInfo name="FIPS PUB" value="202"/> | |||
| <seriesInfo name="DOI" | <seriesInfo name="DOI" value="10.6028/NIST.FIPS.202"/> | |||
| value="http://dx.doi.org/10.6028/NIST.FIPS.202"/> | </reference> | |||
| </reference> | ||||
| <reference anchor="flatassembler" | <reference anchor="flatassembler" | |||
| target="https://flatassembler.net/"> | target="https://flatassembler.net/"> | |||
| <front> | <front> | |||
| <title>flat assembler, Assembly language resources</title> | <title>flat assembler: Assembly language resources</title> | |||
| <author fullname="Tomasz Grysztar" initials="T." | <author fullname="Tomasz Grysztar" initials="T." | |||
| surname="Grysztar"/> | surname="Grysztar"/> | |||
| <date year="2025"/> | <date year="2025"/> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="FNV" | <reference anchor="FNV" | |||
| target="http://www.isthe.com/chongo/tech/comp/fnv/index.html"> | target="http://www.isthe.com/chongo/tech/comp/fnv/index.html"> | |||
| <front> | <front> | |||
| <title>FNV website</title> | <title>FNV website</title> | |||
| <author> | <author> | |||
| <organization>Fowler-Noll-Vo</organization> | <organization>Fowler-Noll-Vo</organization> | |||
| </author> | </author> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <!-- [rfced] References: Would you like us to change "Fowler-Noll-Vo" | ||||
| in the listing for [FNV] to "Fowler, G., Noll, L., and Vo, K." or | ||||
| perhaps "Noll, L."? Is "Fowler-Noll-Vo" considered an organization | ||||
| in this case? | ||||
| Original: | ||||
| [FNV] Fowler-Noll-Vo, "FNV website", | ||||
| <http://www.isthe.com/chongo/tech/comp/fnv/index.html>. --> | ||||
| <reference anchor="Fortran" | <reference anchor="Fortran" | |||
| target="https://stdlib.fortran-lang.org/"> | target="https://stdlib.fortran-lang.org/"> | |||
| <front> | <front> | |||
| <title>A community driven standard library for (modern) | <title>A community driven standard library for (modern) | |||
| Fortran</title> | Fortran</title> | |||
| <author> | <author> | |||
| <organization>Fortran Standard Library</organization> | <organization>Fortran Standard Library</organization> | |||
| </author> | </author> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="FragCache" | <reference anchor="FragCache" | |||
| target="https://www.slideshare.net/slideshow/improving-running-components-at-twi tter/1141786 | target="https://www.slideshare.net/slideshow/improving-running-components-at-twi tter/1141786 | |||
| "> | "> | |||
| <front> | <front> | |||
| <title>Improving Running Components at Twitter (see slide 31)</title> | <title>Improving Running Components at Twitter</title> | |||
| <author fullname="Evan Waever" initials="E." | <author fullname="Evan Waever" initials="E." | |||
| surname="Weaver"/> | surname="Weaver"/> | |||
| <date year="2009"/> | <date year="2009"/> | |||
| </front> | </front> | |||
| <refcontent>Slide 31</refcontent> | ||||
| </reference> | </reference> | |||
| <reference anchor="FreeBSD" | <reference anchor="FreeBSD" | |||
| target="http://www.freebsd.org/releases/4.3R/notes.html"> | target="https://www.freebsd.org/releases/4.3R/notes.html"> | |||
| <front> | <front> | |||
| <title>FreeBSD 4.3 Release Notes</title> | <title>FreeBSD 4.3 Release Notes</title> | |||
| <author> | <author> | |||
| <organization>The Free BSD Project</organization> | <organization>The Free BSD Project</organization> | |||
| </author> | </author> | |||
| <date year="2025"/> | <date year="2025"/> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <!-- [rfced] References: We see "Last modified on: February 21, 2021 | ||||
| by Danilo G. Baio" on the bottom of the provided page for [FreeBSD]. | ||||
| Should this listing be updated to reflect the "Last modified" date | ||||
| and possibly include "Baio, D. G."? | ||||
| Original: | ||||
| [FreeBSD] The Free BSD Project, "FreeBSD 4.3 Release Notes", 2025, | ||||
| <http://www.freebsd.org/releases/4.3R/notes.html>. --> | ||||
| <reference anchor="FRET" | <reference anchor="FRET" | |||
| target="https://fret.sourceforge.net/"> | target="https://fret.sourceforge.net/"> | |||
| <front> | <front> | |||
| <title>FRET helps understand file formats</title> | <title>FRET: helping understand file formats</title> | |||
| <author fullname="Michael McCarthy" initials="M." | <author fullname="Michael McCarthy" initials="M." | |||
| surname="McCarthy"/> | surname="McCarthy"/> | |||
| <date year="2006" month="1" day="19"/> | <date year="2006" month="January" day="19"/> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="GolfHash" | <reference anchor="GolfHash" | |||
| target="https://golf-lang.com/new-hash.html"> | target="https://golf-lang.com/new-hash.html"> | |||
| <front> | <front> | |||
| <title>Golf Language Hash Tables</title> | <title>Golf Language Hash Tables</title> | |||
| <author> | <author> | |||
| <organization>Gliim LLC</organization> | <organization>Gliim LLC</organization> | |||
| </author> | </author> | |||
| <date year="2025"/> | <date year="2025"/> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="IEEE" target="http:www.ieee.org"> | <!-- [rfced] References: The provided URL for [GolfHash] steers to | |||
| <https://rimstone-lang.com/>, and we see "Golf is now RimStone | ||||
| (2025-10-02)". May we change the citation string to "[RimStone]" | ||||
| and update the URL? | ||||
| Original: | ||||
| * Golf language hash tables [GolfHash], | ||||
| ... | ||||
| [GolfHash] Gliim LLC, "Golf Language Hash Tables", 2025, | ||||
| <https://golf-lang.com/new-hash.html>. | ||||
| Possibly: | ||||
| * Golf language hash tables [RimStone], | ||||
| ... | ||||
| [RimStone] Gliim LLC, "Golf Language Hash Tables", 2025, | ||||
| <https://rimstone-lang.com/>. --> | ||||
| <reference anchor="IEEE" target="https://www.ieee.org/"> | ||||
| <front> | <front> | |||
| <title>IEEE website</title> | <title>IEEE website</title> | |||
| <author> | <author> | |||
| <organization>Institute for Electrical and Electronics | <organization>Institute for Electrical and Electronics | |||
| Engineers</organization> | Engineers</organization> | |||
| </author> | </author> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="IEEE8021Qbp"> | <reference anchor="IEEE8021Qbp"> | |||
| <front> | <front> | |||
| <title>Media Access Control (MAC) Bridges and Virtual Bridged | <title>Media Access Control (MAC) Bridges and Virtual Bridged | |||
| Local Area Networks - Equal Cost Multiple Path (ECMP)</title> | Local Area Networks - Equal Cost Multiple Path (ECMP)</title> | |||
| <author surname="IEEE 802.1"/> | <author surname="IEEE 802.1"/> | |||
| <date year="2014" month="April" day="7"/> | <date year="2014" month="April" day="7"/> | |||
| </front> | </front> | |||
| <seriesInfo name="IEEE Std" value="802.1Qbp-2014"/> | <seriesInfo name="IEEE Std" value="802.1Qbp-2014"/> | |||
| </reference> | </reference> | |||
| <!-- [rfced] References: Regarding [IEEE8021Qbp]: A Google search | ||||
| for "IEEE Std 802.1Qbp" yields several "hits", but | ||||
| <https://standards.ieee.org/ieee/802.1Qbp/5217/> and | ||||
| <https://ieeexplore.ieee.org/document/6783684> (1) show titles that | ||||
| include "Amendment 22:" and (2) list this standard as "Superseded". | ||||
| Please let us know how, or if, this listing should be updated. | ||||
| Original: | ||||
| [IEEE8021Qbp] | ||||
| "Media Access Control (MAC) Bridges and Virtual Bridged | ||||
| Local Area Networks - Equal Cost Multiple Path (ECMP)", | ||||
| IEEE Std 802.1Qbp-2014, 7 April 2014. --> | ||||
| <reference anchor="IEN137" | <reference anchor="IEN137" | |||
| target="https://www.rfc-editor.org/ien/ien137.txt"> | target="https://www.rfc-editor.org/ien/ien137.txt"> | |||
| <front> | <front> | |||
| <title>On Holy Wars and A Plea For Peace</title> | <title>On Holy Wars and A Plea For Peace</title> | |||
| <author fullname="Danny Cohen" initials="D." | <author fullname="Danny Cohen" initials="D." | |||
| surname="Cohen"> | surname="Cohen"> | |||
| <organization>USC/ISI</organization> | <organization>USC/ISI</organization> | |||
| </author> | </author> | |||
| <date year="1980" month="4" day="1"/> | <date year="1980" month="April" day="1"/> | |||
| </front> | </front> | |||
| <seriesInfo name="IEN" value="137"/> | <refcontent>IEN 137</refcontent> | |||
| </reference> | </reference> | |||
| <reference anchor="IPv6flow" | <reference anchor="IPv6flow" | |||
| target="https://researchspace.auckland.ac.nz/bitstream/handle/2292/13240/flowhas hRep.pdf"> | target="https://researchspace.auckland.ac.nz/bitstream/handle/2292/13240/flowhas hRep.pdf"> | |||
| <front> | <front> | |||
| <title>Comparing Hash Function Algorithms for the IPv6 Flow | <title>Comparing Hash Function Algorithms for the IPv6 Flow | |||
| Label</title> | Label</title> | |||
| <author fullname="Lewis Anderson" initials="L." | <author fullname="Lewis Anderson" initials="L." | |||
| surname="Anderson"> | surname="Anderson"> | |||
| <organization>The University of Auckland</organization> | <organization>The University of Auckland</organization> | |||
| skipping to change at line 6394 ¶ | skipping to change at line 6969 ¶ | |||
| <author fullname="Brian E. Carpenter" initials="B." | <author fullname="Brian E. Carpenter" initials="B." | |||
| surname="Carpenter"> | surname="Carpenter"> | |||
| <organization>The University of Auckland, Department of Computer | <organization>The University of Auckland, Department of Computer | |||
| Science</organization> | Science</organization> | |||
| <address> | <address> | |||
| <email>brain@cs.auckland.ac.nz</email> | <email>brain@cs.auckland.ac.nz</email> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <date year="2012" month="March"/> | <date year="2012" month="March"/> | |||
| </front> | </front> | |||
| <seriesInfo name="University of Auckland Department of Computer | <refcontent>University of Auckland Department of Computer Science Technical Re | |||
| Science Technical Report" value="2012-002"/> | port 2012-002</refcontent> | |||
| <seriesInfo name="ISSN" value="1173-3500"/> | <seriesInfo name="ISSN" value="1173-3500"/> | |||
| </reference> | </reference> | |||
| <!-- [rfced] References: The provided URL for [IPv6flow] yields | ||||
| either "Hmm. We're having trouble finding that site. We can't | ||||
| connect to the server at rsnode-app-prod" or "502 Bad Gateway". | ||||
| However, <https://www.cs.auckland.ac.nz/~brian/flowhashRep.pdf> | ||||
| provides what appears to be the same paper. Would this URL be | ||||
| considered stable? If yes, could we update this listing as follows? | ||||
| Original: | ||||
| [IPv6flow] Anderson, L., Brownlee, N., and B. Carpenter, "Comparing | ||||
| Hash Function Algorithms for the IPv6 Flow Label", | ||||
| University of Auckland Department of Computer Science | ||||
| Technical Report 2012-002, ISSN 1173-3500, March 2012, | ||||
| <https://researchspace.auckland.ac.nz/bitstream/ | ||||
| handle/2292/13240/flowhashRep.pdf>. | ||||
| Possibly: | ||||
| [IPv6flow] Anderson, L., Brownlee, N., and B. E. Carpenter, | ||||
| "Comparing Hash Function Algorithms for the IPv6 Flow | ||||
| Label", University of Auckland Department of Computer | ||||
| Science Technical Report 2012-002, ISSN 1173-3500, March | ||||
| 2012, | ||||
| <https://www.cs.auckland.ac.nz/~brian/flowhashRep.pdf>. --> | ||||
| <reference anchor="LCN2" | <reference anchor="LCN2" | |||
| target="https://github.com/lcn2/fnv"> | target="https://github.com/lcn2/fnv"> | |||
| <front> | <front> | |||
| <title>lcn2 / fnv</title> | <title>lcn2 / fnv</title> | |||
| <author fullname="Landon Curt Noll" initials="L." | <author fullname="Landon Curt Noll" initials="L." | |||
| surname="Noll"> | surname="Noll"> | |||
| <organization>Cisco</organization> | <organization>Cisco</organization> | |||
| </author> | </author> | |||
| <author fullname="Cody Boone Ferguson" initials="C." | <author fullname="Cody Boone Ferguson" initials="C." | |||
| surname="Ferguson"/> | surname="Ferguson"/> | |||
| <date month="November" day="19" year="2025"/> | ||||
| </front> | </front> | |||
| <refcontent>commit 953444c</refcontent> | ||||
| </reference> | </reference> | |||
| <reference anchor="Leprechaun" | <reference anchor="Leprechaun" | |||
| target="http://www.sanmayce.com/Downloads/"> | target="http://www.sanmayce.com/Downloads/"> | |||
| <front> | <front> | |||
| <title>Sanmayce project 'Underdog Way'</title> | <title>Sanmayce project 'Underdog Way'</title> | |||
| <author> | <author> | |||
| <organization>Sanmayce project</organization> | <organization>Sanmayce project</organization> | |||
| </author> | </author> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="libstr" | <reference anchor="libsir" | |||
| target="https://github.com/aremmell/libsir"> | target="https://github.com/aremmell/libsir"> | |||
| <front> | <front> | |||
| <title>libstr logging library</title> | <title>libsir logging library</title> | |||
| <author initials="R." surname="Lederman"/> | <author initials="R." surname="Lederman"/> | |||
| <author initials="J." surname="Johnson"/> | <author initials="J." surname="Johnson"/> | |||
| <date month="December" day="03" year="2025"/> | ||||
| </front> | </front> | |||
| <refcontent>commit 0ae0173</refcontent> | ||||
| </reference> | </reference> | |||
| <reference anchor="memcache" | <reference anchor="memcache" | |||
| target="http://pecl.php.net/package/memcache"> | target="https://pecl.php.net/package/memcache"> | |||
| <front> | <front> | |||
| <title>PHP memcached extension</title> | <title>PHP memcached extension</title> | |||
| <author initials="A." surname="Dovgal"> | <author initials="A." surname="Dovgal"> | |||
| <organization>The PHP Group</organization> | <organization>The PHP Group</organization> | |||
| </author> | </author> | |||
| <author initials="P." surname="Joye"> | <author initials="P." surname="Joye"> | |||
| <organization>The PHP Group</organization> | <organization>The PHP Group</organization> | |||
| </author> | </author> | |||
| <author initials="H." surname="Radtke"> | <author initials="H." surname="Radtke"> | |||
| <organization>The PHP Group</organization> | <organization>The PHP Group</organization> | |||
| </author> | </author> | |||
| <author initials="M." surname="Johansson"> | <author initials="M." surname="Johansson"> | |||
| <organization>The PHP Group</organization> | <organization>The PHP Group</organization> | |||
| </author> | </author> | |||
| <author initials="T." surname="Srnka"> | <author initials="T." surname="Srnka"> | |||
| <organization>The PHP Group</organization> | <organization>The PHP Group</organization> | |||
| </author> | </author> | |||
| <date year="2023" month="4" day="30"/> | <date year="2023" month="April" day="30"/> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <referencegroup anchor="NCHF"> | <referencegroup anchor="NCHF"> | |||
| <reference anchor="NCHF1" | <reference anchor="NCHF1" target="https://cacm.acm.org/practice/questioning-th | |||
| target="https://cacm.acm.org/practice/questioning-the-criteria-for-evaluat | e-criteria-for-evaluating-non-cryptographic-hash-functions/"> | |||
| ing-non-cryptographic-hash-functions/"> | ||||
| <front> | <front> | |||
| <title>Questioning the Criteria for Evaluating Non-Cryptographic | <title>Questioning the Criteria for Evaluating Non-Cryptographic | |||
| Hash Functions</title> | Hash Functions</title> | |||
| <author fullname="Catherine Hayes" initials="C." surname="Hayes"> | <author fullname="Catherine Hayes" initials="C." surname="Hayes"> | |||
| <organization>Maynooth University</organization> | <organization>Maynooth University</organization> | |||
| </author> | </author> | |||
| <author fullname="David Malone" initials="D." surname="Malone"> | <author fullname="David Malone" initials="D." surname="Malone"> | |||
| <organization>Maynooth University</organization> | <organization>Maynooth University</organization> | |||
| </author> | </author> | |||
| <date year="2025" month="1" day="15"/> | <date year="2025" month="February"/> | |||
| </front> | </front> | |||
| <refcontent>Communications of the ACM, Vol. 68 No. 2, pp. 46-51</refcontent> | ||||
| <seriesInfo name="DOI" value="10.1145/3704255"/> | <seriesInfo name="DOI" value="10.1145/3704255"/> | |||
| </reference> | </reference> | |||
| <reference anchor="NCHF2" | <reference anchor="NCHF2" | |||
| target="https://ieeexplore.ieee.org/abstract/document/10603139"> | target="https://ieeexplore.ieee.org/abstract/document/10603139"> | |||
| <front> | <front> | |||
| <title>An Evaluation of FNV Non-Cryptographic Hash | <title>An Evaluation of FNV Non-Cryptographic Hash | |||
| Functions</title> | Functions</title> | |||
| <author fullname="Catherine Hayes" initials="C." surname="Hayes"> | <author fullname="Catherine Hayes" initials="C." surname="Hayes"> | |||
| <organization>Maynooth University</organization> | <organization>Maynooth University</organization> | |||
| </author> | </author> | |||
| <author fullname="David Malone" initials="D." surname="Malone"> | <author fullname="David Malone" initials="D." surname="Malone"> | |||
| <organization>Maynooth University</organization> | <organization>Maynooth University</organization> | |||
| </author> | </author> | |||
| <date year="2024" month="June"/> | <date year="2024" month="June"/> | |||
| </front> | </front> | |||
| <refcontent>Proceedings of the 35th Irish Signals and Systems Conference (ISSC )</refcontent> | ||||
| <seriesInfo name="DOI" | <seriesInfo name="DOI" | |||
| value="10.1109/ISSC61953.2024.10603139"/> | value="10.1109/ISSC61953.2024.10603139"/> | |||
| </reference> | </reference> | |||
| </referencegroup> | </referencegroup> | |||
| <xi:include | <xi:include | |||
| href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.3174.xml"/> | href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3174.xml"/> | |||
| <xi:include | <xi:include | |||
| href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.6194.xml"/> | href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6194.xml"/> | |||
| <xi:include | <xi:include | |||
| href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.6234.xml"/> | href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6234.xml"/> | |||
| <xi:include | <xi:include | |||
| href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.6437.xml"/> | href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6437.xml"/> | |||
| <xi:include | <xi:include | |||
| href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.7357.xml"/> | href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7357.xml"/> | |||
| <xi:include | <xi:include | |||
| href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.7873.xml"/> | href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7873.xml"/> | |||
| <xi:include | <xi:include | |||
| href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.8200.xml"/> | href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8200.xml"/> | |||
| <reference anchor="twistylists" | <reference anchor="twistylists" | |||
| target="https://twistylists.blogspot.com/"> | target="https://twistylists.blogspot.com/"> | |||
| <front> | <front> | |||
| <title>A no-sort namespace engine</title> | <title>twistylists: A no-sort namespace engine; developers invited</title> | |||
| <author> | <author fullname="Dave Zethmayr" initials="D." surname="Zethmayr"> | |||
| <organization>twistylists</organization> | <organization/> | |||
| </author> | </author> | |||
| <date year="2012"/> | <date month="November" day="6" year="2012"/> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <reference anchor="Vely" | <reference anchor="Vely" | |||
| target="https://www.linuxlinks.com/vely-general-purpose-framework/"> | target="https://www.linuxlinks.com/vely-general-purpose-framework/"> | |||
| <front> | <front> | |||
| <title>Vely - general purpose framework</title> | <title>Vely - general purpose framework</title> | |||
| <author fullname="Sergio Mijatovic" initials="S." | <author fullname="Sergio Mijatovic" initials="S." | |||
| surname="Mijatovic"/> | surname="Mijatovic"/> | |||
| <date month="October" day="26" year="2023"/> | ||||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <!-- [rfced] References: On the provided page for [Vely], we see | ||||
| "Steve Emms" near the top of the page and "Website: No longer | ||||
| publicly developed" further down, past the bullet list and just | ||||
| above "Developer: Sergio Mijatovic". | ||||
| Also, on the provided page several commenters have noted that some | ||||
| relevant pages have been taken down. Will this citation still be | ||||
| helpful to readers, or should it be updated? | ||||
| Original: | ||||
| [Vely] Mijatovic, S., "Vely - general purpose framework", | ||||
| <https://www.linuxlinks.com/vely-general-purpose- | ||||
| framework/>. --> | ||||
| <reference anchor="Vortetty" | <reference anchor="Vortetty" | |||
| target="https://github.com/Vortetty/gba-rtx"> | target="https://github.com/Vortetty/gba-rtx"> | |||
| <front> | <front> | |||
| <title>Raytracing for the gba</title> | <title>Raytracing for the gba</title> | |||
| <author surname="Vortetty"/> | <author surname="Vortetty"/> | |||
| <date month="February" day="26" year="2025"/> | ||||
| </front> | </front> | |||
| <refcontent>commit f8bf009</refcontent> | ||||
| </reference> | </reference> | |||
| <!-- [rfced] References: We could not see how [Vortetty] is related | ||||
| to pseudorandom number generation. Please confirm that the citation | ||||
| and reference listing will be clear to readers. | ||||
| Original: | ||||
| * to help seeding a pseudo random number generator [Vortetty], | ||||
| ... | ||||
| [Vortetty] "Raytracing for the gba", | ||||
| <https://github.com/Vortetty/gba-rtx>. --> | ||||
| </references> | ||||
| </references> | </references> | |||
| <section anchor="Effort"> <!-- Appendix A --> | <section anchor="Effort"> | |||
| <name>Work Comparison with SHA-1 and SHA-256</name> | <name>Work Comparison with SHA-1 and SHA-256</name> | |||
| <t>This appendix provides a simplistic rough comparison of the level | <t>This appendix provides a simplistic rough comparison of the level | |||
| of effort required to compute FNV-1a, SHA-1 <xref | of effort required to compute FNV-1a, SHA-1 <xref | |||
| target="RFC3174"/>, and SHA-256 <xref target="RFC6234"/> for short | target="RFC3174"/>, and SHA-256 <xref target="RFC6234"/> for short | |||
| messages, that is, those less than around 50 bytes. Some CPUs may have | messages -- that is, those less than around 50 bytes. Some CPUs may have | |||
| special instructions or other hardware to accelerate certain | special instructions or other hardware to accelerate certain | |||
| cryptographic operations so, if performance is particularly important | cryptographic operations, so if performance is particularly important | |||
| for an application, benchmarking on the target platform would be | for an application, benchmarking on the target platform would be | |||
| appropriate.</t> | appropriate.</t> | |||
| <t>Ignoring transfer of control and conditional tests and equating all | <t>Ignoring transfer of control and conditional tests, and equating all | |||
| logical and arithmetic operations, FNV requires 2 operations per byte, | logical and arithmetic operations, FNV requires two operations per byte: | |||
| an XOR and a multiply.</t> | an XOR operation and a multiply operation. | |||
| <!-- [rfced] Appendix A: We had trouble at first following the | ||||
| "and" relationships in this sentence. We updated per the | ||||
| "Ignoring SHA-1's ..." and "Ignoring SHA-256's" sentences that | ||||
| appear two and three paragraphs below this sentence. | ||||
| Also, as it appears that two items are listed here (the XOR and | ||||
| multiply operations, per 'the "xor" and multiply operations' in | ||||
| Section 2) rather than three items, we updated this sentence | ||||
| accordingly. If anything is incorrect, please clarify. | ||||
| Original: | ||||
| Ignoring transfer of control and conditional tests and equating all | ||||
| logical and arithmetic operations, FNV requires 2 operations per | ||||
| byte, an XOR and a multiply. | ||||
| Currently: | ||||
| Ignoring transfer of control and conditional tests, and equating all | ||||
| logical and arithmetic operations, FNV requires two operations per | ||||
| byte: an XOR operation and a multiply operation. --> | ||||
| </t> | ||||
| <t>SHA-1 and SHA-256 are actually designed to accept a bit vector | <t>SHA-1 and SHA-256 are actually designed to accept a bit vector | |||
| input although almost all computer uses apply them to an integer | input, although almost all computer uses apply them to an integer | |||
| number of bytes. They both process blocks of 512 bits (64 bytes) and | number of bytes. They both process blocks of 512 bits (64 bytes), and | |||
| we estimate the effort involved in processing a full block. There is | we estimate the effort involved in processing a full block. There is | |||
| some overhead per message to indicate message termination and | some overhead per message to indicate message termination and | |||
| size. Assuming the message is an even number of bytes, this overhead | size. Assuming that the message is an even number of bytes, this overhead | |||
| would be 9 bytes for SHA-1 and 17 bytes for SHA-256. So, assuming the | would be 9 bytes for SHA-1 and 17 bytes for SHA-256. So, assuming that the | |||
| message with that overhead fits into one block, the message would be | message with that overhead fits into one block, the message would be | |||
| up to 55 bytes for SHA-1 or up to 47 bytes for SHA-256.</t> | up to 55 bytes for SHA-1 or up to 47 bytes for SHA-256.</t> | |||
| <t>SHA-1 is a relatively weak cryptographic hash function producing a | <t>SHA-1 is a relatively weak cryptographic hash function producing a | |||
| 160-bit hash. It has been partially broken <xref | 160-bit hash. It has been partially broken <xref | |||
| target="RFC6194"/>. Ignoring SHA-1's initial set up, transfer of | target="RFC6194"/>. Ignoring SHA-1's initial setup, transfer of | |||
| control, and conditional tests, but counting all logical and | control, and conditional tests, but counting all logical and | |||
| arithmetic operations, including counting indexing as an addition, | arithmetic operations, including counting indexing as an addition, | |||
| SHA-1 requires 1,744 operations per 64 bytes block or 31.07 operations | SHA-1 requires 1,744 operations per 64-byte block or 31.07 operations | |||
| per byte for a message of 55 bytes. By this rough measure, it is a | per byte for a message of 55 bytes. By this rough measure, it is a | |||
| little over 15.5 times the effort of FNV.</t> | little over 15.5 times the effort of FNV. | |||
| <!-- [rfced] Appendix A: We see from Google searches (e.g., a search | ||||
| for "Is SHA-1 broken?") that SHA-1 has apparently been fully broken. | ||||
| Would you like to update this text accordingly? | ||||
| Original (the previous sentence is included for context): | ||||
| SHA-1 is a relatively weak cryptographic hash function producing a | ||||
| 160-bit hash. It has been partially broken [RFC6194]. | ||||
| Possibly: | ||||
| SHA-1 [RFC6194] is a relatively weak cryptographic hash function | ||||
| producing a 160-bit hash. In recent years, it has been broken. --> | ||||
| </t> | ||||
| <t>SHA-256 is, at the time of publication, considered to be a stronger | <t>SHA-256 is, at the time of publication, considered to be a stronger | |||
| cryptographic hash function than SHA-1. Ignoring SHA-256's initial set | cryptographic hash function than SHA-1. Ignoring SHA-256's initial setup, transf | |||
| up, transfer of control, and conditional tests, but counting all | er of control, and conditional tests, but counting all | |||
| logical and arithmetic operations, SHA-1 requires 2,058 operations per | logical and arithmetic operations, SHA-1 requires 2,058 operations per | |||
| 64 bytes block or 48.79 operations per byte for a message of 47 | 64-byte block or 48.79 operations per byte for a message of 47 | |||
| byte. By this rough measure, it is over 24 times the effort of | bytes. By this rough measure, it is over 24 times the effort of | |||
| FNV.</t> | FNV.</t> | |||
| <t>However, FNV is commonly used for short inputs so a comparison for | <t>However, FNV is commonly used for short inputs, so doing a comparison of | |||
| such inputs is relevant. Using the above comparison method, for inputs | such inputs is relevant. Using the above comparison method, for inputs | |||
| of N bytes, where N is <= 55 so SHA-1 will take one block, the | of N bytes, where N is <= 55 so SHA-1 will take one block, the | |||
| ratio of the effort for SHA-1 to the effort for FNV will be 872/N. | ratio of the effort for SHA-1 to the effort for FNV will be 872/N. | |||
| For inputs of N bytes, where N is <= 47 so SHA-256 will take one | For inputs of N bytes, where N is <= 47 so SHA-256 will take one | |||
| block, the ratio of the effort for SHA-256 to the effort for FNV will | block, the ratio of the effort for SHA-256 to the effort for FNV will | |||
| be 1029/N. Some examples are given below.</t> | be 1029/N. Some examples are given below.</t> | |||
| <table> | <table> | |||
| <thead> | <thead> | |||
| <tr><td>Example</td><td align="right">Length in Bytes</td><td | <tr><th>Example</th><th align="right">Length in Bytes</th> | |||
| align="right">SHA-1 Effort Relative to FNV Effort</td><td | <th align="right">SHA-1 Effort Relative to FNV Effort</th> | |||
| align="right">SHA-256 Effort Relative to FNV Effort</td></tr> | <th align="right">SHA-256 Effort Relative to FNV Effort</th></tr> | |||
| </thead> | </thead> | |||
| <tbody> | <tbody> | |||
| <tr><td>IPv4 address</td><td align="right">4</td><td | <tr><td>IPv4 address</td><td align="right">4</td><td | |||
| align="right">218</td><td align="right">514</td></tr> | align="right">218</td><td align="right">514</td></tr> | |||
| <tr><td>MAC address</td><td align="right">6</td><td | <tr><td>MAC address</td><td align="right">6</td><td | |||
| align="right">145</td><td align="right">171</td></tr> | align="right">145</td><td align="right">171</td></tr> | |||
| <tr><td>IPv6 address</td><td align="right">16</td><td | <tr><td>IPv6 address</td><td align="right">16</td><td | |||
| align="right">54</td><td align="right">64</td></tr> | align="right">54</td><td align="right">64</td></tr> | |||
| </tbody> | </tbody> | |||
| </table> | </table> | |||
| </section> <!-- Appendix A --> | </section> | |||
| <section> <!-- Appendix B --> | <section> | |||
| <name>Previous IETF FNV Code</name> | <name>Previous IETF FNV Code</name> | |||
| <t>FNV-1a was referenced in draft-ietf-tls-cached-info-08.txt that has | <t>FNV-1a was referenced in draft-ietf-tls-cached-info-08 | |||
| since expired. Below is the Java code for FNV64 from that TLS draft | (which was ultimately published as RFC 7924, but RFC 7924 no longer contains the | |||
| included with the kind permission of the author:</t> | code below). Herein, we provide the Java code for FNV64 from that earlier draft | |||
| , included with the kind permission of the author: | ||||
| <sourcecode type="java" markers="true"> | <!-- [rfced] Appendix B: Because (1) draft-ietf-tls-cached-info-08 | |||
| did not expire (version -09 had been uploaded to the Datatracker about | ||||
| 3 months after version -08, per | ||||
| <https://datatracker.ietf.org/doc/rfc7924/history/>) and (2) this | ||||
| draft was ultimately published as RFC 7924 | ||||
| (https://www.rfc-editor.org/info/rfc7924) (which we see no longer | ||||
| contains the code in question), we updated this text accordingly. | ||||
| Please review, and let us know if further clarifications are needed. | ||||
| Also, we see that the code in this document is somewhat different | ||||
| than the code provided in draft-ietf-tls-cached-info-08. | ||||
| For example: | ||||
| In this document: | ||||
| static public BigInteger getFNV1aToByte(byte[] inp) { | ||||
| In draft-ietf-tls-cached-info-08: | ||||
| static public BigInteger getFNV1a64Digest (String inpString) { | ||||
| Should this be somehow clarified for readers? If yes, please provide | ||||
| the text. | ||||
| Original: | ||||
| FNV-1a was referenced in draft-ietf-tls-cached-info-08.txt that has | ||||
| since expired. Below is the Java code for FNV64 from that TLS draft | ||||
| included with the kind permission of the author: | ||||
| Currently: | ||||
| FNV-1a was referenced in draft-ietf-tls-cached-info-08 | ||||
| (which was ultimately published as RFC 7924, but RFC 7924 no longer | ||||
| contains the code below). Herein, we provide the Java code for FNV64 | ||||
| from that earlier draft, included with the kind permission of the | ||||
| author: --> | ||||
| </t> | ||||
| <!-- [LB] Marking sourcecode, including the "Java code sample ..." | ||||
| header, as DNE; pulled from draft-ietf-tls-cached-info-08 | ||||
| (2010 precursor to RFC 7924 (published in 2016)). The code here | ||||
| doesn't match the code in draft-ietf-tls-cached-info-08, though, | ||||
| so AQed to see if the differences should be mentioned in some way. --> | ||||
| <!-- Begin DNE code --> | ||||
| <sourcecode type="java" markers="true"><![CDATA[ | ||||
| /* | /* | |||
| * Java code sample, implementing 64 bit FNV-1a | * Java code sample, implementing 64 bit FNV-1a | |||
| * By Stefan Santesson | * By Stefan Santesson | |||
| */ | */ | |||
| import java.math.BigInteger; | import java.math.BigInteger; | |||
| public class FNV { | public class FNV { | |||
| static public BigInteger getFNV1aToByte(byte[] inp) { | static public BigInteger getFNV1aToByte(byte[] inp) { | |||
| BigInteger m = new BigInteger("2").pow(64); | BigInteger m = new BigInteger("2").pow(64); | |||
| BigInteger fnvPrime = new BigInteger("1099511628211"); | BigInteger fnvPrime = new BigInteger("1099511628211"); | |||
| BigInteger fnvOffsetBasis = | BigInteger fnvOffsetBasis = | |||
| new BigInteger("14695981039346656037"); | new BigInteger("14695981039346656037"); | |||
| BigInteger digest = fnvOffsetBasis; | BigInteger digest = fnvOffsetBasis; | |||
| for (byte b : inp) { | for (byte b : inp) { | |||
| digest = digest.xor(BigInteger.valueOf((int) b & 255)); | digest = digest.xor(BigInteger.valueOf((int) b & 255)); | |||
| digest = digest.multiply(fnvPrime).mod(m); | digest = digest.multiply(fnvPrime).mod(m); | |||
| } | } | |||
| return digest; | return digest; | |||
| } | } | |||
| } | } | |||
| </sourcecode> | ]]></sourcecode> | |||
| <!-- End DNE code --> | ||||
| </section> | ||||
| <section> | ||||
| <name>Change History</name> | ||||
| <t>RFC Editor Note: Please delete this appendix on publication.</t> | ||||
| <section> | ||||
| <name>From -00 to -01</name> | ||||
| <ol> | ||||
| <li>Add Security Considerations section on why FNV is | ||||
| non-cryptographic.</li> | ||||
| <li>Add Appendix A on a work factor comparison with SHA-1.</li> | ||||
| <li>Add Appendix B concerning previous IETF draft referenced to | ||||
| FNV.</li> | ||||
| <li>Minor editorial changes.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -01 to -02</name> | ||||
| <ol> | ||||
| <li>Correct FNV_Prime determination criteria and add note as to why | ||||
| s < 5 and s > 10 are not considered.</li> | ||||
| <li>Add acknowledgements list.</li> | ||||
| <li>Add a couple of references.</li> | ||||
| <li>Minor editorial changes.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -02 to -05</name> | ||||
| <ol> | ||||
| <li>Minor addition to Section 6, point 3.</li> | ||||
| <li>Add Twitter as a use example and IPv6 flow hash study | ||||
| reference.</li> | ||||
| <li>Minor editorial changes.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -05 to -08</name> | ||||
| <ol> | ||||
| <li>Add code subsections.</li> | ||||
| <li>Update Author info.</li> | ||||
| <li>Minor edits.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -08 to -09</name> | ||||
| <ol> | ||||
| <li>Change reference for ASCII to <xref target="RFC0020"/>.</li> | ||||
| <li>Add more details on history of the string used to compute | ||||
| offset_basis.</li> | ||||
| <li>Re-write "Work Factor" part of Section 6 to be more | ||||
| precise.</li> | ||||
| <li>Minor editorial changes.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -09 to -10</name> | ||||
| <ol> | ||||
| <li>Inclusion of initial partial version of code and some | ||||
| documentation about the code, Section 9.</li> | ||||
| <li>Insertion of new Section 4 on hashing values.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -10 to -12</name> | ||||
| <t>Changes based on code improvements primarily from Tony Hansen who | ||||
| has been added as an author. Changes based on comments from Mukund | ||||
| Sivaraman and Roman Donchenko.</t> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -12 to -13</name> | ||||
| <t>Fixed bug in pseudocode in Section 2.3.</t> | ||||
| <t>Change code to eliminate the BigEndian flag and so there are | ||||
| separate byte vector output routines for FNV32 and FNV64, equivalent | ||||
| to the other routines, and integer output routines for cases where | ||||
| Endian-ness consistency is not required.</t> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -13 to -17</name> | ||||
| <ol> | ||||
| <li>Update an author address</li> | ||||
| <li>Update an author affiliation.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -17 to -19</name> | ||||
| <ol> | ||||
| <li>Add reference to draft-ietf-bfd-secure-sequence-numbers.</li> | ||||
| <li>Add references to the following, each of which uses FNV: RFC | ||||
| 7357, RFC 7873, and IEEE Std. 802.1Qbp-2014</li> | ||||
| <li>Update author information</li> | ||||
| <li>Minor editorial changes.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -19 to -20</name> | ||||
| <t>Convert to XML v3. Fix code for longer FNV hashes.</t> | ||||
| </section> | </section> | |||
| <section> | ||||
| <name>From -20 to -21</name> | ||||
| <t>Update Twitter to X. Minor Editorial changes.</t> | ||||
| </section> | <section anchor="Acknowledgements" numbered="false"> | |||
| <section> | <name>Acknowledgements</name> | |||
| <name>From -21 to -22</name> | <t>The contributions of the following, listed in alphabetical order, | |||
| are gratefully acknowledged:</t> | ||||
| <t>Update Landon's email. Minor Editorial changes. Update to | <t><contact fullname="Roman Donchenko"/>, <contact fullname="Frank | |||
| substantially improved code.</t> | Ellermann"/>, <contact fullname="Stephen Farrell"/>, <contact fullname="Tony | |||
| Finch"/>, <contact fullname="Paul Hoffman"/>, <contact fullname="Charlie Kaufm | ||||
| an"/>, <contact fullname="Eliot | ||||
| Lear"/>, <contact fullname="Bob Moskowitz"/>, <contact fullname="Gayle | ||||
| Noble"/>, <contact fullname="Stefan Santesson"/>, <contact fullname="Mukund | ||||
| Sivaraman"/>, | ||||
| and <contact fullname="Paul Wouters"/>. | ||||
| </section> | <!-- [rfced] Acknowledgements section: As the names were mostly | |||
| <section> | listed in alphabetical order, we moved Paul Hoffman's name so that it | |||
| <name>From -22 to -23</name> | is listed between Tony Finch and Charlie Kaufman. Please let us know | |||
| any concerns. | ||||
| <ol> | Original: | |||
| <li>Author info update.</li> | Roman Donchenko, Frank Ellermann, Stephen Farrell, Tony Finch, | |||
| <li>Make byte vector returning versions of | Charlie Kaufman, Eliot Lear, Bob Moskowitz, Gayle Noble, Stefan | |||
| functions available for all sizes.</li> | Santesson, Mukund Sivaraman, Paul Hoffman, and Paul Wouters. | |||
| <li>Remove BigEndian code due to difficulty in finding someone to | ||||
| test it. This only affects multi-byte integer returns and correct | ||||
| results can always be obtained by using the byte vector return | ||||
| versions of functions.</li> | ||||
| </ol> | ||||
| </section> | Currently: | |||
| <section> | Roman Donchenko, Frank Ellermann, Stephen Farrell, Tony Finch, Paul | |||
| <name>From -23 to -25</name> | Hoffman, Charlie Kaufman, Eliot Lear, Bob Moskowitz, Gayle Noble, | |||
| Stefan Santesson, Mukund Sivaraman, and Paul Wouters. --> | ||||
| <ol> | </t> | |||
| <li>Correct some errors in comments in the code, fix some | ||||
| omissions and add testing for the file hashing code, and other | ||||
| code polishing</li> | ||||
| <li>Minor editorial changes.</li> | ||||
| </ol> | ||||
| </section> | </section> | |||
| <section> | ||||
| <name>From -25 to -28</name> | ||||
| <ol> | </back> | |||
| <li>Add autodetect in FNVconfig.h of target support for 64-bit | ||||
| integers.</li> | ||||
| <li>Add discussion of what source files are needed for particular | ||||
| uses.</li> | ||||
| <li>Fix code so it compiles properly if all .c files are | ||||
| concatenated as well as when they are compiled separately.</li> | ||||
| <li>Add makefile section.</li> | ||||
| <li>Fix some problems with &gt; and >.</li> | ||||
| <li>Minor editorial improvements.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section> | ||||
| <name>From -28 to -29</name> | ||||
| <t>Responding to some IETF Last Call Comments: minor re-organization | ||||
| of Introduction and addition to the Introduction of a some | ||||
| non-applicability considerations. Minor editorial improvements.</t> | ||||
| </section> | <!-- [rfced] Please review the "Inclusive Language" portion of the | |||
| <section> | online Style Guide at | |||
| <name>From -29 to -30</name> | <https://www.rfc-editor.org/styleguide/part2/#inclusive_language>, | |||
| and let us know if any changes are needed. Updates of this nature | ||||
| typically result in more precise language, which is helpful for | ||||
| readers. | ||||
| <ol> | Note that our script did not flag any words in particular, but this | |||
| <li>Reorganize Section 1 and add to it a subsection on the | should still be reviewed as a best practice. --> | |||
| applicability of non-cryptographic hash functions.</li> | ||||
| <li>Rewrite and expand <xref target="bang"/> on inducing | ||||
| collisions.</li> | ||||
| <li>Add material on parallelization to the section on hashing | ||||
| multiple values.</li> | ||||
| <li>Add a reference to IEN 137 on Endian-ness.</li> | ||||
| <li>Minor editorial improvements.</li> | ||||
| <li>Minor coding changes including adding function calls | ||||
| supporting variant offset_basis values and reducing the size of | ||||
| main.c through the use of C pre-processor macros.</li> | ||||
| </ol> | ||||
| </section> | <!-- [rfced] Please let us know if any changes are needed for the | |||
| <section> | following: | |||
| <name>From -30 to -31</name> | ||||
| <ol> | a) The following terms were used inconsistently in this document. | |||
| <li>Add more uses of FNV to <xref target="Uses"/>.</li> | We chose to use the latter forms. Please let us know any objections. | |||
| <li>Fix instructions for reporting uses of FNV.</li> | ||||
| <li>Minor editing changes.</li> | ||||
| </ol> | ||||
| </section> | power of two / power of 2 (We also changed "power-of-two" to | |||
| <section> | "power-of-2".) | |||
| <name>From -31 to -32</name> | ||||
| <ol> | b) The following terms appear to be used inconsistently in this | |||
| <li>Move purpose sentence for this draft from the beginning of | document. Please let us know which form is preferred. | |||
| Section 6 to the Introduction.</li> | ||||
| <li>Minor editing changes.</li> | ||||
| </ol> | ||||
| </section> | " 256, 512, and 1024\n"); / "256, 512, and 1024\n" ); | |||
| <section> | (spacing in back-to-back printf statements) | |||
| <name>From -32 to -33</name> | ||||
| <ol> | 64-bit Integers / 64-bit integers (back-to-back printf statements | |||
| <li>Edit based on Independent Submissions Editor review. Includes | in Section 8.3) | |||
| moving around some material, creation of the Historical Notes | (We suggest lowercase "integers", per usage in the rest of | |||
| Appendix, add additional uses including references for some uses, | this document.) | |||
| etc.</li> | ||||
| <li>Add <xref target="C"/>, <xref target="LCN2"/>, and <xref | ||||
| target="Vely"/> to References.</li> | ||||
| <li>Minor editing changes.</li> | ||||
| </ol> | ||||
| </section> | flow ID / Flow ID (text in Section 4) (We asked about this | |||
| <section> | inconsistency earlier, so this might have been resolved already.) | |||
| <name>From -33 to -34</name> | ||||
| <t>Add "This work is not an Internet standard and is not the result | FNV Prime(s) / FNV_Prime(s) / FNV_prime | |||
| of consensus of the IETF community." to the Introduction.</t> | (e.g., "Size FNV Prime" and "32-bit FNV_Prime = ..." (Table 1), | |||
| "32-bit FNV_prime = ..." (Section 8.2.1), and similar ones | ||||
| throughout Section 8.2) | ||||
| </section> | little endian (adj.) (e.g., "little endian format", | |||
| <section> | "little endian byte vector") / | |||
| <name>From -34 to -35</name> | little-endian (e.g., "big endian or other non-little-endian | |||
| machines") | ||||
| <t>Update based on reviews as follows:</t> | Suggested: little-endian format, little-endian byte vector, | |||
| big-endian machines or other non-little-endian machines | ||||
| <ol> | one bits (noun) / one-bits (noun) (If you wish to use the | |||
| <li>Add references to SHA3 <xref target="FIPS202"/>.</li> | hyphen, should "one bit" used as a noun in Section 2.1 also be | |||
| <li>Slightly simplify the wording of <xref | hyphenated?) | |||
| target="applicability"/>.</li> | ||||
| <li>Add <xref target="NCHF"/> reference group.</li> | ||||
| <li>Make it clear that the Section 2 pseudocode uses modulus | ||||
| arithmetic mod 2**HashSize.</li> | ||||
| <li>Mention in Section 8 that some other source code might be | ||||
| more optimized.</li> | ||||
| <li>Mention in Appendix A that some CPUs may have hardware that | ||||
| accelerates some cryptographic operations and, if performance is | ||||
| important for a particular application, benchmarking on the target | ||||
| platform would be appropriate.</li> | ||||
| <li>Augment Appendix A with rough computational effort estimates | ||||
| for SHA-256 as well as SHA-1 and reformat examples as a table.</li> | ||||
| <li>Minor editing changes.</li> | ||||
| </ol> | ||||
| </section> | Extra space after "+" sign (5 instances): | |||
| ctx->Hash[i] = ( temp<<8 ) + *basis++; | ||||
| ctx->Hash[i] = ( temp<<8 ) + (*basis++); | ||||
| as compared to | ||||
| ctx->Hash[i] = temp + *basis++; | ||||
| </section> | printf( (2 instances) / printf ( (33 instances) | |||
| <section anchor="Acknowledgements" numbered="false"> | TestNValue (" (2 instances) / TestNValue ( " (16 instances) | |||
| <name>Acknowledgements</name> | ||||
| <t>The contributions of the following, listed is alphabetic order, | TestR ( " (84 instances) / TestR (" (7 instances) | |||
| are gratefully acknowledged:</t> | ||||
| <t>Roman Donchenko, Frank Ellermann, Stephen Farrell, Tony Finch, | Verbose flag (3 instances) / verbose flag (1 instance) | |||
| Charlie Kaufman, Eliot Lear, Bob Moskowitz, Gayle Noble, Stefan | ||||
| Santesson, Mukund Sivaraman, Paul Hoffman, and Paul Wouters.</t> | ||||
| </section> | XOR folding / xor folding (in running text) | |||
| (We also see "xor data folding".) | ||||
| </back> | "xor" (operations) ("the "xor" and multiply operations") / | |||
| XOR (operations) ("operations per byte, an XOR and a multiply") --> | ||||
| </rfc> | </rfc> | |||
| End of changes. 401 change blocks. | ||||
| 836 lines changed or deleted | 1408 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. | ||||