rfc9496.original.xml | rfc9496.xml | |||
---|---|---|---|---|
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | |||
<!DOCTYPE rfc [ | ||||
<!ENTITY nbsp " "> | ||||
<!ENTITY zwsp "​"> | ||||
<!ENTITY nbhy "‑"> | ||||
<!ENTITY wj "⁠"> | ||||
]> | ||||
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Process or - mmark.miek.nl" --> | <!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Process or - mmark.miek.nl" --> | |||
<rfc version="3" ipr="trust200902" docName="draft-irtf-cfrg-ristretto255-decaf44 8-07" submissionType="IETF" category="info" xml:lang="en" xmlns:xi="http://www.w 3.org/2001/XInclude" indexInclude="true" consensus="true"> | <rfc version="3" ipr="trust200902" docName="draft-irtf-cfrg-ristretto255-decaf44 8-08" submissionType="IRTF" category="info" xml:lang="en" xmlns:xi="http://www.w 3.org/2001/XInclude" indexInclude="true" consensus="true" sortRefs="true" number ="9496"> | |||
<front> | <front> | |||
<title abbrev="ristretto255-decaf448">The ristretto255 and decaf448 Groups</titl e><seriesInfo value="draft-irtf-cfrg-ristretto255-decaf448-07" stream="IETF" sta tus="informational" name="Internet-Draft"></seriesInfo> | <title abbrev="ristretto255-decaf448">The ristretto255 and decaf448 Groups</titl e><seriesInfo value="9496" name="RFC"></seriesInfo> | |||
<author initials="H." surname="de Valence" fullname="Henry de Valence"><organiza tion></organization><address><postal><street></street> | <author initials="H." surname="de Valence" fullname="Henry de Valence"><organiza tion></organization><address><postal><street></street> | |||
</postal><email>ietf@hdevalence.ca</email> | </postal><email>ietf@hdevalence.ca</email> | |||
</address></author><author initials="J." surname="Grigg" fullname="Jack Grigg">< organization></organization><address><postal><street></street> | </address></author><author initials="J." surname="Grigg" fullname="Jack Grigg">< organization></organization><address><postal><street></street> | |||
</postal><email>ietf@jackgrigg.com</email> | </postal><email>ietf@jackgrigg.com</email> | |||
</address></author><author initials="M." surname="Hamburg" fullname="Mike Hambur g"><organization></organization><address><postal><street></street> | </address></author><author initials="M." surname="Hamburg" fullname="Mike Hambur g"><organization></organization><address><postal><street></street> | |||
</postal><email>ietf@shiftleft.org</email> | </postal><email>ietf@shiftleft.org</email> | |||
</address></author><author initials="I." surname="Lovecruft" fullname="Isis Love cruft"><organization></organization><address><postal><street></street> | </address></author><author initials="I." surname="Lovecruft" fullname="Isis Love cruft"><organization></organization><address><postal><street></street> | |||
</postal><email>ietf@en.ciph.re</email> | </postal><email>ietf@en.ciph.re</email> | |||
</address></author><author initials="G." surname="Tankersley" fullname="George T ankersley"><organization></organization><address><postal><street></street> | </address></author><author initials="G." surname="Tankersley" fullname="George T ankersley"><organization></organization><address><postal><street></street> | |||
</postal><email>ietf@gtank.cc</email> | </postal><email>ietf@gtank.cc</email> | |||
</address></author><author initials="F." surname="Valsorda" fullname="Filippo Va lsorda"><organization></organization><address><postal><street></street> | </address></author><author initials="F." surname="Valsorda" fullname="Filippo Va lsorda"><organization></organization><address><postal><street></street> | |||
</postal><email>ietf@filippo.io</email> | </postal><email>ietf@filippo.io</email> | |||
</address></author><date/> | </address></author><date year="2023" month="December"></date> | |||
<area>Internet</area> | ||||
<workgroup>Crypto Forum Research Group</workgroup> | <workgroup>Crypto Forum</workgroup> | |||
<keyword>cryptographic group</keyword> | ||||
<keyword>cryptography</keyword> | ||||
<keyword>Curve25519</keyword> | ||||
<keyword>ecc</keyword> | ||||
<keyword>edwards448</keyword> | ||||
<keyword>elliptic curve</keyword> | ||||
<keyword>elliptic curve cryptography</keyword> | ||||
<keyword>nonmalleable encodings</keyword> | ||||
<keyword>prime-order</keyword> | ||||
<keyword>prime order</keyword> | ||||
<abstract> | <abstract> | |||
<t>This memo specifies two prime-order groups, ristretto255 and decaf448, | <t>This memo specifies two prime-order groups, ristretto255 and decaf448, | |||
suitable for safely implementing higher-level and complex | suitable for safely implementing higher-level and complex | |||
cryptographic protocols. The ristretto255 group can be implemented | cryptographic protocols. The ristretto255 group can be implemented | |||
using Curve25519, allowing existing Curve25519 implementations to be | using Curve25519, allowing existing Curve25519 implementations to be | |||
reused and extended to provide a prime-order group. Likewise, the | reused and extended to provide a prime-order group. Likewise, the | |||
decaf448 group can be implemented using edwards448.</t> | decaf448 group can be implemented using edwards448.</t> | |||
<t>This document is a product of the Crypto Forum Research Group (CFRG) in the I RTF.</t> | <t>This document is a product of the Crypto Forum Research Group (CFRG) in the I RTF.</t> | |||
</abstract> | </abstract> | |||
</front> | </front> | |||
<middle> | <middle> | |||
<section anchor="introduction"><name>Introduction</name> | <section anchor="introduction"><name>Introduction</name> | |||
<t>Decaf <xref target="Decaf"></xref> is a technique for constructing prime-orde r groups | <t>Decaf <xref target="Decaf"></xref> is a technique for constructing prime-orde r groups | |||
with non-malleable encodings from non-prime-order elliptic curves. | with nonmalleable encodings from non-prime-order elliptic curves. | |||
Ristretto extends this technique to support cofactor-8 curves such as | Ristretto extends this technique to support cofactor-8 curves such as | |||
Curve25519 <xref target="RFC7748"></xref>. In particular, this allows an existin g | Curve25519 <xref target="RFC7748"></xref>. In particular, this allows an existin g | |||
Curve25519 library to provide a prime-order group with only a thin | Curve25519 library to provide a prime-order group with only a thin | |||
abstraction layer.</t> | abstraction layer.</t> | |||
<t>Many group-based cryptographic protocols require the number of | <t>Many group-based cryptographic protocols require the number of | |||
elements in the group (the group order) to be prime. Prime-order | elements in the group (the group order) to be prime. Prime-order | |||
groups are useful because every non-identity element of the group | groups are useful because every non-identity element of the group | |||
is a generator of the entire group. This means the group has a | is a generator of the entire group. This means the group has a | |||
cofactor of 1, and all elements are equivalent from the perspective | cofactor of 1, and all elements are equivalent from the perspective | |||
of Discrete Log Hardness.</t> | of hardness of the discrete logarithm problem.</t> | |||
<t>Edwards curves provide a number of implementation benefits for | <t>Edwards curves provide a number of implementation benefits for | |||
cryptography, such as complete addition formulas with no exceptional | cryptography. These benefits include formulas for curve operations | |||
points and formulas among the fastest known for curve operations. | that are among the fastest currently known, and for which the | |||
addition formulas are complete with no exceptional points. | ||||
However, the group of points on the curve is not of prime order, | However, the group of points on the curve is not of prime order, | |||
i.e., it has a cofactor larger than 1. | i.e., it has a cofactor larger than 1. This abstraction mismatch is | |||
This abstraction mismatch is usually handled by means of ad-hoc | usually handled, if it is handled at all, by means of ad hoc protocol | |||
protocol tweaks, such as multiplying by the cofactor in an | tweaks such as multiplying by the cofactor in an appropriate place.</t> | |||
appropriate place, or not at all.</t> | ||||
<t>Even for simple protocols such as signatures, these tweaks can cause | <t>Even for simple protocols such as signatures, these tweaks can cause | |||
subtle issues. For instance, Ed25519 implementations may have | subtle issues. For instance, Ed25519 implementations may have | |||
different validation behavior between batched and singleton | different validation behavior between batched and singleton | |||
verification, and at least as specified in <xref target="RFC8032"></xref>, the s et of | verification, and at least as specified in <xref target="RFC8032"></xref>, the s et of | |||
valid signatures is not defined by the standard.</t> | valid signatures is not defined precisely <xref target="Ed25519ValidCrit"></xref >.</t> | |||
<t>For more complex protocols, careful analysis is required as the | <t>For more complex protocols, careful analysis is required as the | |||
original security proofs may no longer apply, and the tweaks for one | original security proofs may no longer apply, and the tweaks for one | |||
protocol may have disastrous effects when applied to another (for | protocol may have disastrous effects when applied to another (for | |||
instance, the octuple-spend vulnerability in <xref target="MoneroVuln"></xref>). </t> | instance, the octuple-spend vulnerability described in <xref target="MoneroVuln" ></xref>).</t> | |||
<t>Decaf and Ristretto fix this abstraction mismatch in one place for | <t>Decaf and Ristretto fix this abstraction mismatch in one place for | |||
all protocols, providing an abstraction to protocol implementors that | all protocols, providing an abstraction to protocol implementors that | |||
matches the abstraction commonly assumed in protocol specifications, | matches the abstraction commonly assumed in protocol specifications | |||
while still allowing the use of high-performance curve | while still allowing the use of high-performance curve | |||
implementations internally. The abstraction layer imposes minor | implementations internally. The abstraction layer imposes minor | |||
overhead, and only in the encoding and decoding phases.</t> | overhead but only in the encoding and decoding phases.</t> | |||
<t>While Ristretto is a general method, and can be used in conjunction | <t>While Ristretto is a general method and can be used in conjunction | |||
with any Edwards curve with cofactor 4 or 8, this document specifies | with any Edwards curve with cofactor 4 or 8, this document specifies | |||
the ristretto255 group, which can be implemented using Curve25519, | the ristretto255 group, which can be implemented using Curve25519, | |||
and the decaf448 group, which can be implemented using edwards448.</t> | and the decaf448 group, which can be implemented using edwards448.</t> | |||
<t>There are other elliptic curves that can be used internally to | <t>There are other elliptic curves that can be used internally to | |||
implement ristretto255 or decaf448, and those implementations would be | implement ristretto255 or decaf448; those implementations would be | |||
interoperable with a Curve25519- or edwards448-based one, but those | interoperable with one based on Curve25519 or edwards448, but those | |||
constructions are out-of-scope for this document.</t> | constructions are out of scope for this document.</t> | |||
<t>The Ristretto construction is described and justified in detail at | <t>The Ristretto construction is described and justified in detail at | |||
<xref target="RistrettoGroup"></xref>.</t> | <xref target="RistrettoGroup"></xref>.</t> | |||
<t>This document represents the consensus of the Crypto Forum Research Group (CF RG). | <t>This document represents the consensus of the Crypto Forum Research Group (CF RG). | |||
This document is not an IETF product and is not a standard.</t> | This document is not an IETF product and is not a standard.</t> | |||
</section> | </section> | |||
<section anchor="notation-and-conventions-used-in-this-document"><name>Notation and Conventions Used In This Document</name> | <section anchor="notation-and-conventions-used-in-this-document"><name>Notation and Conventions Used in This Document</name> | |||
<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>& quot;, "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", | <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>& quot;, "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", | |||
"<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "< bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</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 | "<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> <xre f target="RFC8174"></xref> | are to be interpreted as described in BCP 14 <xref target="RFC2119"></xref> <xre f target="RFC8174"></xref> | |||
when, and only when, they appear in all capitals, as shown here.</t> | when, and only when, they appear in all capitals, as shown here.</t> | |||
<t>Readers are cautioned that the term "Curve25519" has varying | <t>Readers are cautioned that the term "Curve25519" has varying | |||
interpretations in the literature, and that the canonical meaning of the | interpretations in the literature and that the canonical meaning of the | |||
term has shifted over time. Originally it referred to a specific | term has shifted over time. Originally, it referred to a specific | |||
Diffie-Hellman key exchange mechanism. Over time, use shifted, and | Diffie-Hellman key exchange mechanism. Use shifted over time, and | |||
"Curve25519" has been used to refer to either the abstract underlying | "Curve25519" has been used to refer to the abstract underlying | |||
curve, or its concrete representation in Montgomery form, or the | curve, its concrete representation in Montgomery form, or the | |||
specific Diffie-Hellman mechanism. This document uses the term | specific Diffie-Hellman mechanism. This document uses the term | |||
"Curve25519" to refer to the abstract underlying curve, as recommended | "Curve25519" to refer to the abstract underlying curve, as recommended | |||
in <xref target="Naming"></xref>. The abstract Edwards form of the curve we refe r to here | in <xref target="Naming"></xref>. The abstract Edwards form of the curve we refe r to here | |||
as "Curve25519" is in <xref target="RFC7748"></xref> referred to as &q | as "Curve25519" is referred to in <xref target="RFC7748"></xref> as &q | |||
uot;edwards25519" | uot;edwards25519", | |||
and its isogenous Montgomery form is referred to as "curve25519".</t> | and the Montgomery form that is isogenous to the Edwards form is | |||
referred to in <xref target="RFC7748"></xref> as "curve25519".</t> | ||||
<t>Elliptic curve points in this document are represented in extended | <t>Elliptic curve points in this document are represented in extended | |||
Edwards coordinates in the <tt>(x, y, z, t)</tt> format <xref target="Twisted">< /xref>, also called | Edwards coordinates in the <tt>(x, y, z, t)</tt> format <xref target="Twisted">< /xref>, also called | |||
extended homogeneous coordinates in Section 5.1.4 of <xref target="RFC8032"></xr | extended homogeneous coordinates in <xref target="RFC8032" sectionFormat="of" se | |||
ef>. Field | ction="5.1.4"></xref>. Field | |||
elements are values modulo p, the Curve25519 prime 2^255 - 19 or the | elements are values modulo p, the Curve25519 prime 2<sup>255</sup> - 19 or the | |||
edwards448 prime 2^448 - 2^224 - 1, as specified in Sections 4.1 and | edwards448 prime 2<sup>448</sup> - 2<sup>224</sup> - 1, as specified in Sections | |||
4.2 of <xref target="RFC7748"></xref>, respectively. All formulas specify field | <xref target="RFC7748" sectionFormat="bare" section="4.1"></xref> and <xref targ | |||
operations | et="RFC7748" sectionFormat="bare" section="4.2"></xref> of <xref target="RFC7748 | |||
unless otherwise noted. The symbol ^ denotes exponentiation.</t> | "></xref>, respectively. All | |||
formulas specify field operations unless otherwise noted. The symbol | ||||
<tt>^</tt> denotes exponentiation.</t> | ||||
<t>The <tt>|</tt> symbol represents a constant-time logical OR.</t> | <t>The <tt>|</tt> symbol represents a constant-time logical OR.</t> | |||
<t>The notation <tt>array[A:B]</tt> means the elements of <tt>array</tt> from <t t>A</tt> | <t>The notation <tt>array[A:B]</tt> means the elements of <tt>array</tt> from <t t>A</tt> | |||
to <tt>B-1</tt>. That is, it is exclusive of <tt>B</tt>. Arrays are indexed | to <tt>B-1</tt>. That is, it is exclusive of <tt>B</tt>. Arrays are indexed | |||
starting from 0.</t> | starting from 0.</t> | |||
<t>A byte is an 8-bit entity (also known as "octet") and a byte string | <t>A byte is an 8-bit entity (also known as "octet"), and a byte strin g | |||
is an ordered sequence of bytes. An N-byte string is a byte string of | is an ordered sequence of bytes. An N-byte string is a byte string of | |||
N bytes in length.</t> | N bytes in length.</t> | |||
<t>Element encodings are presented as hex encoded byte strings with | <t>Element encodings are presented as hex-encoded byte strings with | |||
whitespace added for readability.</t> | whitespace added for readability.</t> | |||
<section anchor="negative-field-elements"><name>Negative field elements</name> | <section anchor="negative-field-elements"><name>Negative Field Elements</name> | |||
<t>As in <xref target="RFC8032"></xref>, given a field element e, define <tt>IS_ NEGATIVE(e)</tt> as | <t>As in <xref target="RFC8032"></xref>, given a field element e, define <tt>IS_ NEGATIVE(e)</tt> as | |||
TRUE if the least non-negative integer representing e is odd, and | TRUE if the least nonnegative integer representing e is odd and | |||
FALSE if it is even. This <bcp14>SHOULD</bcp14> be implemented in constant time. </t> | FALSE if it is even. This <bcp14>SHOULD</bcp14> be implemented in constant time. </t> | |||
</section> | </section> | |||
<section anchor="constant-time-operations"><name>Constant time operations</name> | <section anchor="constant-time-operations"><name>Constant-Time Operations</name> | |||
<t>We assume that the field element implementation supports the following | <t>We assume that the field element implementation supports the following | |||
operations, which <bcp14>SHOULD</bcp14> be implemented in constant time:</t> | operations, which <bcp14>SHOULD</bcp14> be implemented in constant time:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li><tt>CT_EQ(u, v)</tt>: return TRUE if u = v, FALSE otherwise.</li> | <li><tt>CT_EQ(u, v)</tt>: return TRUE if u = v, FALSE otherwise.</li> | |||
<li><tt>CT_SELECT(v IF cond ELSE u)</tt>: return v if cond is TRUE, else return u.</li> | <li><tt>CT_SELECT(v IF cond ELSE u)</tt>: return v if cond is TRUE, else return u.</li> | |||
<li><tt>CT_ABS(u)</tt>: return -u if IS_NEGATIVE(u), else return u.</li> | <li><tt>CT_ABS(u)</tt>: return -u if <tt>IS_NEGATIVE(u)</tt>, else return u.</li > | |||
</ul> | </ul> | |||
<t>Note that <tt>CT_ABS</tt> <bcp14>MAY</bcp14> be implemented as:</t> | <t>Note that <tt>CT_ABS</tt> <bcp14>MAY</bcp14> be implemented as:</t> | |||
<artwork>CT_SELECT(-u IF IS_NEGATIVE(u) ELSE u) | <artwork><![CDATA[CT_SELECT(-u IF IS_NEGATIVE(u) ELSE u) | |||
</artwork> | ]]></artwork> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="interface"><name>The group abstraction</name> | <section anchor="interface"><name>The Group Abstraction</name> | |||
<t>Ristretto and Decaf implement an abstract prime-order group interface | <t>Ristretto and Decaf implement an abstract prime-order group interface | |||
that exposes only the behavior that is useful to higher-level protocols, | that exposes only the behavior that is useful to higher-level protocols, | |||
without leaking curve-related details and pitfalls.</t> | without leaking curve-related details and pitfalls.</t> | |||
<t>Each abstract group exposes operations on abstract element and abstract | <t>Each abstract group exposes operations on abstract element and abstract | |||
scalar types. The operations defined on these types include: decoding, encoding, | scalar types. The operations defined on these types include: decoding, encoding, | |||
equality, addition, negation, subtraction and (multi-)scalar multiplication. | equality, addition, negation, subtraction, and (multi-)scalar multiplication. | |||
Each abstract group also exposes a deterministic function to derive abstract | Each abstract group also exposes a deterministic function to derive abstract | |||
elements from fixed-length byte strings. A description of each of these | elements from fixed-length byte strings. A description of each of these | |||
operations is below.</t> | operations is below.</t> | |||
<t>Decoding is a function from byte strings to abstract elements with | <t>Decoding is a function from byte strings to abstract elements with | |||
built-in validation, so that only the canonical encodings of valid | built-in validation, so that only the canonical encodings of valid | |||
elements are accepted. The built-in validation avoids the need for | elements are accepted. The built-in validation avoids the need for | |||
explicit invalid curve checks.</t> | explicit invalid curve checks.</t> | |||
<t>Encoding is a function from abstract elements to byte strings. Internally, | <t>Encoding is a function from abstract elements to byte strings. Internally, | |||
an abstract element might have more than one possible representation -- for | an abstract element might have more than one possible representation; for | |||
example, the implementation might use projective coordinates. When encoding, | example, the implementation might use projective coordinates. When encoding, | |||
all equivalent representations of the same element are encoded as identical | all equivalent representations of the same element are encoded as identical | |||
byte strings. Decoding the output of the encoding function always | byte strings. Decoding the output of the encoding function always | |||
succeeds and returns an equivalent element to the encoding input.</t> | succeeds and returns an element equivalent to the encoding input.</t> | |||
<t>The equality check reports whether two representations of an abstract | <t>The equality check reports whether two representations of an abstract | |||
element are equivalent.</t> | element are equivalent.</t> | |||
<t>The element derivation function maps deterministically from byte strings of | <t>The element derivation function maps deterministically from byte strings of | |||
a fixed length to abstract elements. It has two important properties. First, | a fixed length to abstract elements. It has two important properties. First, | |||
if the input is a uniformly random byte string, then the output is (within | if the input is a uniformly random byte string, then the output is (within | |||
a negligible statistical distance of) a uniformly random abstract group | a negligible statistical distance of) a uniformly random abstract group | |||
element. This means the function is suitable for selecting random group | element. This means the function is suitable for selecting random group | |||
elements.</t> | elements.</t> | |||
<t>Second, although the element derivation function is many-to-one and therefore | <t>Second, although the element derivation function is many-to-one and therefore | |||
not strictly invertible, it is not pre-image resistent. On the contrary, | not strictly invertible, it is not pre-image resistant. On the contrary, | |||
given an arbitrary abstract group element <tt>P</tt>, there is an efficient algo rithm | given an arbitrary abstract group element <tt>P</tt>, there is an efficient algo rithm | |||
to randomly sample from byte strings that map to <tt>P</tt>. In some contexts t his | to randomly sample from byte strings that map to <tt>P</tt>. In some contexts, this | |||
property would be a weakness, but it is important in some contexts: in particula r, | property would be a weakness, but it is important in some contexts: in particula r, | |||
it means that a combination of a cryptographic hash function and the element | it means that a combination of a cryptographic hash function and the element | |||
derivation function is suitable for use in algorithms such as | derivation function is suitable to define encoding functions such as | |||
<tt>hash_to_curve</tt> <xref target="draft-irtf-cfrg-hash-to-curve-16"></xref>.< | <tt>hash_to_ristretto255</tt> (<xref target="RFC9380" sectionFormat="of" section | |||
/t> | ="B"></xref>) and <tt>hash_to_decaf448</tt> | |||
(<xref target="RFC9380" sectionFormat="of" section="C"></xref>).</t> | ||||
<t>Addition is the group operation. The group has an identity element and | <t>Addition is the group operation. The group has an identity element and | |||
prime order l. Adding together l copies of the same element gives the | prime order <tt>l</tt>. Adding together <tt>l</tt> copies of the same element gi ves the | |||
identity. Adding the identity element to | identity. Adding the identity element to | |||
any element returns that element unchanged. Negation returns an element | any element returns that element unchanged. Negation returns an element | |||
that added to the negation input returns the identity element. | that, when added to the negation input, gives the identity element. | |||
Subtraction is the addition of a negated element, and scalar | Subtraction is the addition of a negated element, and scalar | |||
multiplication is the repeated addition of an element.</t> | multiplication is the repeated addition of an element.</t> | |||
</section> | </section> | |||
<section anchor="ristretto255"><name>ristretto255</name> | <section anchor="ristretto255"><name>ristretto255</name> | |||
<t>ristretto255 is an instantiation of the abstract prime-order group | <t>ristretto255 is an instantiation of the abstract prime-order group | |||
interface defined in <xref target="interface"></xref>. This document describes h ow to | interface defined in <xref target="interface"></xref>. This document describes h ow to | |||
implement the ristretto255 prime-order group using Curve25519 points as | implement the ristretto255 prime-order group using Curve25519 points as | |||
internal representations.</t> | internal representations.</t> | |||
<t>A "ristretto255 group element" is the abstract element of the prime | <t>A "ristretto255 group element" is the abstract element of the | |||
order group. An "element encoding" is the unique reversible encoding | prime-order group. An "element encoding" is the unique reversible enco | |||
ding | ||||
of a group element. An "internal representation" is a point on the | of a group element. An "internal representation" is a point on the | |||
curve used to implement ristretto255. Each group element can have | curve used to implement ristretto255. Each group element can have | |||
multiple equivalent internal representations.</t> | multiple equivalent internal representations.</t> | |||
<t>Encoding, decoding, equality, and the element derivation function are defined in | <t>Encoding, decoding, equality, and the element derivation function are defined in | |||
<xref target="functions255"></xref>. Element addition, subtraction, negation, an d scalar | <xref target="functions255"></xref>. Element addition, subtraction, negation, an d scalar | |||
multiplication are implemented by applying the corresponding operations | multiplication are implemented by applying the corresponding operations | |||
directly to the internal representation.</t> | directly to the internal representation.</t> | |||
<t>The group order is the same as the order of the Curve25519 prime-order subgro up:</t> | <t>The group order is the same as the order of the Curve25519 prime-order subgro up:</t> | |||
<artwork>l = 2^252 + 27742317777372353535851937790883648493 | <artwork><![CDATA[l = 2^252 + 27742317777372353535851937790883648493 | |||
</artwork> | ]]></artwork> | |||
<t>Since ristretto255 is a prime-order group, every element except the | <t>Since ristretto255 is a prime-order group, every element except the | |||
identity is a generator, but for interoperability a canonical generator | identity is a generator. However, for interoperability, a canonical | |||
is selected, which can be internally represented by the Curve25519 | generator is selected, which can be internally represented by the | |||
basepoint, enabling reuse of existing precomputation for scalar | Curve25519 base point, enabling reuse of existing precomputation for | |||
multiplication. This is its encoding as produced by the function | scalar multiplication. The encoding of this canonical generator, as | |||
specified in <xref target="encoding255"></xref>:</t> | produced by the function specified in <xref target="encoding255"></xref>, is:</t | |||
> | ||||
<artwork>e2f2ae0a 6abc4e71 a884a961 c500515f 58e30b6a a582dd8d b6a65945 e08d2d76 | <artwork><![CDATA[e2f2ae0a 6abc4e71 a884a961 c500515f 58e30b6a a582dd8d b6a65945 | |||
</artwork> | e08d2d76 | |||
]]></artwork> | ||||
<section anchor="constants255"><name>Implementation constants</name> | <section anchor="constants255"><name>Implementation Constants</name> | |||
<t>This document references the following constant field element values | <t>This document references the following constant field element values | |||
that are used for the implementation of group operations.</t> | that are used for the implementation of group operations.</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li><t><tt>D</tt> = 370957059346694393431380835087545651895421138798432190163887 85533085940283555</t> | <li><t><tt>D</tt> = 370957059346694393431380835087545651895421138798432190163887 85533085940283555</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>This is the Edwards d parameter for Curve25519, as specified in Section 4.1 of <xref target="RFC7748"></xref>.</li> | <li>This is the Edwards d parameter for Curve25519, as specified in <xref target ="RFC7748" sectionFormat="of" section="4.1"></xref>.</li> | |||
</ul></li> | </ul></li> | |||
<li><tt>SQRT_M1</tt> = 196811613767075059568070793049885420154460665159238901627 44021073123829784752</li> | <li><tt>SQRT_M1</tt> = 196811613767075059568070793049885420154460665159238901627 44021073123829784752</li> | |||
<li><tt>SQRT_AD_MINUS_ONE</tt> = 25063068953384623474111414158702152701244531502 492656460079210482610430750235</li> | <li><tt>SQRT_AD_MINUS_ONE</tt> = 25063068953384623474111414158702152701244531502 492656460079210482610430750235</li> | |||
<li><tt>INVSQRT_A_MINUS_D</tt> = 54469307008909316920995813868745141605393597292 927456921205312896311721017578</li> | <li><tt>INVSQRT_A_MINUS_D</tt> = 54469307008909316920995813868745141605393597292 927456921205312896311721017578</li> | |||
<li><tt>ONE_MINUS_D_SQ</tt> = 11598430216687798791937755218555866479373577597154 17654439879720876111806838</li> | <li><tt>ONE_MINUS_D_SQ</tt> = 11598430216687798791937755218555866479373577597154 17654439879720876111806838</li> | |||
<li><tt>D_MINUS_ONE_SQ</tt> = 40440834346308536858101042469323190826248399146238 708352240133220865137265952</li> | <li><tt>D_MINUS_ONE_SQ</tt> = 40440834346308536858101042469323190826248399146238 708352240133220865137265952</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
<section anchor="sqrtratio255"><name>Square root of a ratio of field elements</n | <section anchor="sqrtratio255"><name>Square Root of a Ratio of Field Elements</n | |||
ame> | ame> | |||
<t>The following function is defined on field elements, and is used to | <t>The following function is defined on field elements and is used to | |||
implement other ristretto255 functions. This function is only used internally | implement other ristretto255 functions. This function is only used internally | |||
to implement some of the group operations.</t> | to implement some of the group operations.</t> | |||
<t>On input field elements u and v, the function <tt>SQRT_RATIO_M1(u, v)</tt> re turns:</t> | <t>On input field elements u and v, the function <tt>SQRT_RATIO_M1(u, v)</tt> re turns:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li><tt>(TRUE, +sqrt(u/v))</tt> if u and v are non-zero, and u/v is square;</li> | <li><tt>(TRUE, +sqrt(u/v))</tt> if u and v are nonzero and u/v is square in the field;</li> | |||
<li><tt>(TRUE, zero)</tt> if u is zero;</li> | <li><tt>(TRUE, zero)</tt> if u is zero;</li> | |||
<li><tt>(FALSE, zero)</tt> if v is zero and u is non-zero;</li> | <li><tt>(FALSE, zero)</tt> if v is zero and u is nonzero; and</li> | |||
<li><tt>(FALSE, +sqrt(SQRT_M1*(u/v)))</tt> if u and v are non-zero, and u/v is | <li><tt>(FALSE, +sqrt(SQRT_M1*(u/v)))</tt> if u and v are nonzero and u/v is | |||
non-square (so <tt>SQRT_M1*(u/v)</tt> is square),</li> | non-square in the field (so <tt>SQRT_M1*(u/v)</tt> is square in the field),</li> | |||
</ul> | </ul> | |||
<t>where <tt>+sqrt(x)</tt> indicates the non-negative square root of x in the | <t>where <tt>+sqrt(x)</tt> indicates the nonnegative square root of x in the | |||
field.</t> | field.</t> | |||
<t>The computation is similar to Section 5.1.3 of <xref target="RFC8032"></xref> | <t>The computation is similar to what is described in <xref target="RFC8032" sec | |||
, with the | tionFormat="of" section="5.1.3"></xref>, with the | |||
difference that if the input is non-square, the function returns a | difference that, if the input is non-square, the function returns a | |||
result with a defined relationship to the inputs. This result is used | result with a defined relationship to the inputs. This result is used | |||
for efficient implementation of the derivation function. The function | for efficient implementation of the derivation function. The function | |||
can be refactored from an existing Ed25519 implementation.</t> | can be refactored from an existing Ed25519 implementation.</t> | |||
<t><tt>SQRT_RATIO_M1(u, v)</tt> is defined as follows:</t> | <t><tt>SQRT_RATIO_M1(u, v)</tt> is defined as follows:</t> | |||
<artwork>r = (u * v^3) * (u * v^7)^((p-5)/8) // Note: (p - 5) / 8 is an integer. | <artwork><![CDATA[r = (u * v^3) * (u * v^7)^((p-5)/8) // Note: (p - 5) / 8 is an integer. | |||
check = v * r^2 | check = v * r^2 | |||
correct_sign_sqrt = CT_EQ(check, u) | correct_sign_sqrt = CT_EQ(check, u) | |||
flipped_sign_sqrt = CT_EQ(check, -u) | flipped_sign_sqrt = CT_EQ(check, -u) | |||
flipped_sign_sqrt_i = CT_EQ(check, -u*SQRT_M1) | flipped_sign_sqrt_i = CT_EQ(check, -u*SQRT_M1) | |||
r_prime = SQRT_M1 * r | r_prime = SQRT_M1 * r | |||
r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r) | r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r) | |||
// Choose the nonnegative square root. | // Choose the nonnegative square root. | |||
r = CT_ABS(r) | r = CT_ABS(r) | |||
was_square = correct_sign_sqrt | flipped_sign_sqrt | was_square = correct_sign_sqrt | flipped_sign_sqrt | |||
return (was_square, r) | return (was_square, r) | |||
</artwork> | ]]></artwork> | |||
</section> | </section> | |||
<section anchor="functions255"><name>ristretto255 group operations</name> | <section anchor="functions255"><name>ristretto255 Group Operations</name> | |||
<t>This section describes the implementation of the external functions | <t>This section describes the implementation of the external functions | |||
exposed by the ristretto255 prime-order group.</t> | exposed by the ristretto255 prime-order group.</t> | |||
<section anchor="decoding255"><name>Decode</name> | <section anchor="decoding255"><name>Decode</name> | |||
<t>All elements are encoded as 32-byte strings. Decoding proceeds as follows:</t > | <t>All elements are encoded as 32-byte strings. Decoding proceeds as follows:</t > | |||
<ol spacing="compact"> | <ol spacing="compact"> | |||
<li><t>First, interpret the string as an unsigned integer s in little-endian | <li>Interpret the string as an unsigned integer s in little-endian | |||
representation. If the length of the string is not 32 bytes, or if | representation. If the length of the string is not 32 bytes or if | |||
the resulting value is >= p, decoding fails.</t> | the resulting value is >= p, decoding fails.</li> | |||
</ol> | ||||
<ul spacing="compact"> | <aside><t>Note: Unlike the field element decoding described in <xref target="RFC | |||
<li>Note: unlike <xref target="RFC7748"></xref> field element decoding, the most | 7748"></xref>, the most significant | |||
significant | ||||
bit is not masked, and non-canonical values are rejected. | bit is not masked, and non-canonical values are rejected. | |||
The test vectors in <xref target="invalid255"></xref> exercise these edge cases. | The test vectors in <xref target="invalid255"></xref> exercise these edge cases. | |||
</li> | </t> | |||
</ul></li> | </aside> | |||
<ol spacing="compact" start="2"> | ||||
<li>If <tt>IS_NEGATIVE(s)</tt> returns TRUE, decoding fails.</li> | <li>If <tt>IS_NEGATIVE(s)</tt> returns TRUE, decoding fails.</li> | |||
<li>Process s as follows:</li> | <li>Process s as follows:</li> | |||
</ol> | </ol> | |||
<artwork>ss = s^2 | <artwork><![CDATA[ss = s^2 | |||
u1 = 1 - ss | u1 = 1 - ss | |||
u2 = 1 + ss | u2 = 1 + ss | |||
u2_sqr = u2^2 | u2_sqr = u2^2 | |||
v = -(D * u1^2) - u2_sqr | v = -(D * u1^2) - u2_sqr | |||
(was_square, invsqrt) = SQRT_RATIO_M1(1, v * u2_sqr) | (was_square, invsqrt) = SQRT_RATIO_M1(1, v * u2_sqr) | |||
den_x = invsqrt * u2 | den_x = invsqrt * u2 | |||
den_y = invsqrt * den_x * v | den_y = invsqrt * den_x * v | |||
x = CT_ABS(2 * s * den_x) | x = CT_ABS(2 * s * den_x) | |||
y = u1 * den_y | y = u1 * den_y | |||
t = x * y | t = x * y | |||
</artwork> | ]]></artwork> | |||
<ol spacing="compact" start="4"> | <ol spacing="compact" start="4"> | |||
<li>If was_square is FALSE, or <tt>IS_NEGATIVE(t)</tt> returns TRUE, or y = | <li>If was_square is FALSE, <tt>IS_NEGATIVE(t)</tt> returns TRUE, or y = | |||
0, decoding fails. Otherwise, return the group element represented | 0, decoding fails. Otherwise, return the group element represented | |||
by the internal representation <tt>(x, y, 1, t)</tt> as the result of | by the internal representation <tt>(x, y, 1, t)</tt> as the result of | |||
decoding.</li> | decoding.</li> | |||
</ol> | </ol> | |||
</section> | </section> | |||
<section anchor="encoding255"><name>Encode</name> | <section anchor="encoding255"><name>Encode</name> | |||
<t>A group element with internal representation <tt>(x0, y0, z0, t0)</tt> is | <t>A group element with internal representation <tt>(x0, y0, z0, t0)</tt> is | |||
encoded as follows:</t> | encoded as follows:</t> | |||
<ol spacing="compact"> | <ol spacing="compact"> | |||
<li>Process the internal representation into a field element s as follows:</li> | <li>Process the internal representation into a field element s as follows:</li> | |||
</ol> | </ol> | |||
<artwork>u1 = (z0 + y0) * (z0 - y0) | <artwork><![CDATA[u1 = (z0 + y0) * (z0 - y0) | |||
u2 = x0 * y0 | u2 = x0 * y0 | |||
// Ignore was_square since this is always square. | // Ignore was_square since this is always square. | |||
(_, invsqrt) = SQRT_RATIO_M1(1, u1 * u2^2) | (_, invsqrt) = SQRT_RATIO_M1(1, u1 * u2^2) | |||
den1 = invsqrt * u1 | den1 = invsqrt * u1 | |||
den2 = invsqrt * u2 | den2 = invsqrt * u2 | |||
z_inv = den1 * den2 * t0 | z_inv = den1 * den2 * t0 | |||
ix0 = x0 * SQRT_M1 | ix0 = x0 * SQRT_M1 | |||
skipping to change at line 354 ¶ | skipping to change at line 375 ¶ | |||
// Conditionally rotate x and y. | // Conditionally rotate x and y. | |||
x = CT_SELECT(iy0 IF rotate ELSE x0) | x = CT_SELECT(iy0 IF rotate ELSE x0) | |||
y = CT_SELECT(ix0 IF rotate ELSE y0) | y = CT_SELECT(ix0 IF rotate ELSE y0) | |||
z = z0 | z = z0 | |||
den_inv = CT_SELECT(enchanted_denominator IF rotate ELSE den2) | den_inv = CT_SELECT(enchanted_denominator IF rotate ELSE den2) | |||
y = CT_SELECT(-y IF IS_NEGATIVE(x * z_inv) ELSE y) | y = CT_SELECT(-y IF IS_NEGATIVE(x * z_inv) ELSE y) | |||
s = CT_ABS(den_inv * (z - y)) | s = CT_ABS(den_inv * (z - y)) | |||
</artwork> | ]]></artwork> | |||
<ol spacing="compact" start="2"> | <ol spacing="compact" start="2"> | |||
<li>Return the 32-byte little-endian encoding of s. More specifically, | <li>Return the 32-byte little-endian encoding of s. More specifically, | |||
this is the encoding of the canonical representation of s as an integer | this is the encoding of the canonical representation of s as an integer | |||
between 0 and p-1, inclusive.</li> | between 0 and p-1, inclusive.</li> | |||
</ol> | </ol> | |||
<t>Note that decoding and then re-encoding a valid group element will | <t>Note that decoding and then re-encoding a valid group element will | |||
yield an identical byte string.</t> | yield an identical byte string.</t> | |||
</section> | </section> | |||
<section anchor="equals255"><name>Equals</name> | <section anchor="equals255"><name>Equals</name> | |||
<t>The equality function returns TRUE when two internal representations | <t>The equality function returns TRUE when two internal representations | |||
correspond to the same group element. Note that internal representations | correspond to the same group element. Note that internal representations | |||
<bcp14>MUST NOT</bcp14> be compared in any other way than specified here.</t> | <bcp14>MUST NOT</bcp14> be compared in any way other than specified here.</t> | |||
<t>For two internal representations <tt>(x1, y1, z1, t1)</tt> and <tt>(x2, y2, z 2, t2)</tt>, | <t>For two internal representations <tt>(x1, y1, z1, t1)</tt> and <tt>(x2, y2, z 2, t2)</tt>, | |||
if</t> | if</t> | |||
<artwork>(x1 * y2 == y1 * x2) | (y1 * y2 == x1 * x2) | <artwork><![CDATA[CT_EQ(x1 * y2, y1 * x2) | CT_EQ(y1 * y2, x1 * x2) | |||
</artwork> | ]]></artwork> | |||
<t>evaluates to TRUE, then return TRUE. Otherwise, return FALSE.</t> | <t>evaluates to TRUE, then return TRUE. Otherwise, return FALSE.</t> | |||
<t>Note that the equality function always returns TRUE when applied to an | <t>Note that the equality function always returns TRUE when applied to an | |||
internal representation and to the internal representation obtained by | internal representation and to the internal representation obtained by | |||
encoding and then re-decoding it. However, the internal | encoding and then re-decoding it. However, the internal | |||
representations themselves might not be identical.</t> | representations themselves might not be identical.</t> | |||
<t>Implementations <bcp14>MAY</bcp14> also perform byte comparisons on the encod ings | <t>Implementations <bcp14>MAY</bcp14> also perform constant-time byte comparison s on the encodings | |||
of group elements (produced by <xref target="encoding255"></xref>) for an equiva lent, although | of group elements (produced by <xref target="encoding255"></xref>) for an equiva lent, although | |||
less efficient, result.</t> | less efficient, result.</t> | |||
</section> | </section> | |||
<section anchor="from_bytes_uniform255"><name>Element derivation</name> | <section anchor="from_bytes_uniform255"><name>Element Derivation</name> | |||
<t>The element derivation function operates on 64-byte strings. | <t>The element derivation function operates on 64-byte strings. | |||
To obtain such an input from an arbitrary-length byte string, applications | To obtain such an input from an arbitrary-length byte string, applications | |||
should use a domain-separated hash construction, the choice of which | should use a domain-separated hash construction, the choice of which | |||
is out-of-scope for this document.</t> | is out of scope for this document.</t> | |||
<t>The element derivation function on an input string b proceeds as follows:</t> | <t>The element derivation function on an input string b proceeds as follows:</t> | |||
<ol spacing="compact"> | <ol spacing="compact"> | |||
<li>Compute P1 as <tt>MAP(b[0:32])</tt>.</li> | <li>Compute P1 as <tt>MAP(b[0:32])</tt>.</li> | |||
<li>Compute P2 as <tt>MAP(b[32:64])</tt>.</li> | <li>Compute P2 as <tt>MAP(b[32:64])</tt>.</li> | |||
<li>Return P1 + P2.</li> | <li>Return P1 + P2.</li> | |||
</ol> | </ol> | |||
<t>The MAP function is defined on 32-byte strings as:</t> | <t>The MAP function is defined on 32-byte strings as:</t> | |||
<ol> | <ol spacing="compact"> | |||
<li><t>First, mask the most significant bit in the final byte of the string, | <li><t>Mask the most significant bit in the final byte of the string, | |||
and interpret the string as an unsigned integer r in little-endian | and interpret the string as an unsigned integer r in little-endian | |||
representation. Reduce r modulo p to obtain a field element t.</t> | representation. Reduce r modulo p to obtain a field element t.</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>Masking the most significant bit is equivalent to interpreting the | <li>Masking the most significant bit is equivalent to interpreting the | |||
whole string as an unsigned integer in little-endian representation and then | whole string as an unsigned integer in little-endian representation and then | |||
reducing it modulo 2^255.</li> | reducing it modulo 2<sup>255</sup>.</li> | |||
<li>Note: similarly to <xref target="RFC7748"></xref> field element decoding, an | ||||
d unlike | ||||
field element decoding in <xref target="decoding255"></xref>, the most significa | ||||
nt bit | ||||
is masked, and non-canonical values are accepted.</li> | ||||
</ul></li> | </ul></li> | |||
<li><t>Process t as follows:</t> | ||||
</li> | ||||
</ol> | </ol> | |||
<artwork>r = SQRT_M1 * t^2 | <aside><t>Note: Similar to the field element decoding described in <xref target= | |||
"RFC7748"></xref>, and unlike | ||||
the field element decoding described in <xref target="decoding255"></xref>, the | ||||
most significant bit | ||||
is masked, and non-canonical values are accepted.</t> | ||||
</aside> | ||||
<ol spacing="compact" start="2"> | ||||
<li>Process t as follows:</li> | ||||
</ol> | ||||
<artwork><![CDATA[r = SQRT_M1 * t^2 | ||||
u = (r + 1) * ONE_MINUS_D_SQ | u = (r + 1) * ONE_MINUS_D_SQ | |||
v = (-1 - r*D) * (r + D) | v = (-1 - r*D) * (r + D) | |||
(was_square, s) = SQRT_RATIO_M1(u, v) | (was_square, s) = SQRT_RATIO_M1(u, v) | |||
s_prime = -CT_ABS(s*t) | s_prime = -CT_ABS(s*t) | |||
s = CT_SELECT(s IF was_square ELSE s_prime) | s = CT_SELECT(s IF was_square ELSE s_prime) | |||
c = CT_SELECT(-1 IF was_square ELSE r) | c = CT_SELECT(-1 IF was_square ELSE r) | |||
N = c * (r - 1) * D_MINUS_ONE_SQ - v | N = c * (r - 1) * D_MINUS_ONE_SQ - v | |||
w0 = 2 * s * v | w0 = 2 * s * v | |||
w1 = N * SQRT_AD_MINUS_ONE | w1 = N * SQRT_AD_MINUS_ONE | |||
w2 = 1 - s^2 | w2 = 1 - s^2 | |||
w3 = 1 + s^2 | w3 = 1 + s^2 | |||
</artwork> | ]]></artwork> | |||
<ol spacing="compact" start="3"> | <ol spacing="compact" start="3"> | |||
<li>Return the group element represented by the internal representation | <li>Return the group element represented by the internal representation | |||
<tt>(w0*w3, w2*w1, w1*w3, w0*w2)</tt>.</li> | <tt>(w0*w3, w2*w1, w1*w3, w0*w2)</tt>.</li> | |||
</ol> | </ol> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="scalar-field"><name>Scalar field</name> | <section anchor="scalar-field"><name>Scalar Field</name> | |||
<t>The scalars for the ristretto255 group are integers modulo the order l | <t>The scalars for the ristretto255 group are integers modulo the order <tt>l</t | |||
t> | ||||
of the ristretto255 group. Note that this is the same scalar field as | of the ristretto255 group. Note that this is the same scalar field as | |||
Curve25519, allowing existing implementations to be reused.</t> | Curve25519, allowing existing implementations to be reused.</t> | |||
<t>Scalars are encoded as 32-byte strings in little-endian order. | <t>Scalars are encoded as 32-byte strings in little-endian order. | |||
Implementations <bcp14>SHOULD</bcp14> check that any scalar s falls in the range | Implementations <bcp14>SHOULD</bcp14> check that any scalar s falls in the range | |||
0 <= s < l when parsing them and reject non-canonical scalar | 0 <= s < <tt>l</tt> when parsing them and reject non-canonical scalar | |||
encodings. Implementations <bcp14>SHOULD</bcp14> reduce scalars modulo l when | encodings. Implementations <bcp14>SHOULD</bcp14> reduce scalars modulo <tt>l</tt | |||
> when | ||||
encoding them as byte strings. Omitting these strict range checks is | encoding them as byte strings. Omitting these strict range checks is | |||
<bcp14>NOT RECOMMENDED</bcp14> but is allowed to enable reuse of scalar | <bcp14>NOT RECOMMENDED</bcp14> but is allowed to enable reuse of scalar | |||
arithmetic implementations in existing Curve25519 libraries.</t> | arithmetic implementations in existing Curve25519 libraries.</t> | |||
<t>Given a uniformly distributed 64-byte string b, implementations can | <t>Given a uniformly distributed 64-byte string b, implementations can | |||
obtain a uniformly distributed scalar by interpreting the 64-byte | obtain a uniformly distributed scalar by interpreting the 64-byte | |||
string as a 512-bit unsigned integer in little-endian order and reducing the | string as a 512-bit unsigned integer in little-endian order and reducing the | |||
integer modulo l, as in <xref target="RFC8032"></xref>. To obtain such an input from an | integer modulo <tt>l</tt>, as in <xref target="RFC8032"></xref>. To obtain such an input from an | |||
arbitrary-length byte string, applications should use a domain-separated | arbitrary-length byte string, applications should use a domain-separated | |||
hash construction, the choice of which is out-of-scope for this document.</t> | hash construction, the choice of which is out of scope for this document.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="decaf448"><name>decaf448</name> | <section anchor="decaf448"><name>decaf448</name> | |||
<t>decaf448 is an instantiation of the abstract prime-order group | <t>decaf448 is an instantiation of the abstract prime-order group | |||
interface defined in <xref target="interface"></xref>. This document describes h ow to | interface defined in <xref target="interface"></xref>. This document describes h ow to | |||
implement the decaf448 prime-order group using edwards448 points as | implement the decaf448 prime-order group using edwards448 points as | |||
internal representations.</t> | internal representations.</t> | |||
<t>A "decaf448 group element" is the abstract element of the prime ord er | <t>A "decaf448 group element" is the abstract element of the prime-ord er | |||
group. An "element encoding" is the unique reversible encoding of a | group. An "element encoding" is the unique reversible encoding of a | |||
group element. An "internal representation" is a point on the curve | group element. An "internal representation" is a point on the curve | |||
used to implement decaf448. Each group element can have multiple | used to implement decaf448. Each group element can have multiple | |||
equivalent internal representations.</t> | equivalent internal representations.</t> | |||
<t>Encoding, decoding, equality, and the element derivation functions are define d in | <t>Encoding, decoding, equality, and the element derivation functions are define d in | |||
<xref target="functions448"></xref>. Element addition, subtraction, negation, an d scalar | <xref target="functions448"></xref>. Element addition, subtraction, negation, an d scalar | |||
multiplication are implemented by applying the corresponding operations | multiplication are implemented by applying the corresponding operations | |||
directly to the internal representation.</t> | directly to the internal representation.</t> | |||
<t>The group order is the same as the order of the edwards448 prime-order subgro up:</t> | <t>The group order is the same as the order of the edwards448 prime-order subgro up:</t> | |||
<artwork>l = 2^446 - | <artwork><![CDATA[l = 2^446 - | |||
13818066809895115352007386748515426880336692474882178609894547503885 | 13818066809895115352007386748515426880336692474882178609894547503885 | |||
</artwork> | ]]></artwork> | |||
<t>Since decaf448 is a prime-order group, every element except the | <t>Since decaf448 is a prime-order group, every element except the | |||
identity is a generator, but for interoperability a canonical generator | identity is a generator; however, for interoperability, a canonical | |||
is selected, which can be internally represented by the edwards448 | generator is selected. This generator can be internally represented | |||
basepoint, enabling reuse of existing precomputation for scalar | by 2*<tt>B</tt>, where <tt>B</tt> is the edwards448 base point, enabling reuse o | |||
multiplication. This is its encoding as produced by the function | f | |||
specified in <xref target="encoding448"></xref>:</t> | existing precomputation for scalar multiplication. The encoding of | |||
this canonical generator, as produced by the function specified in | ||||
<xref target="encoding448"></xref>, is:</t> | ||||
<artwork>66666666 66666666 66666666 66666666 66666666 66666666 66666666 | <artwork><![CDATA[66666666 66666666 66666666 66666666 66666666 66666666 66666666 | |||
33333333 33333333 33333333 33333333 33333333 33333333 33333333 | 33333333 33333333 33333333 33333333 33333333 33333333 33333333 | |||
</artwork> | ]]></artwork> | |||
<t>This repetitive constant is equal to <tt>1/sqrt(5)</tt> in decaf448's field, | <t>This repetitive constant is equal to <tt>1/sqrt(5)</tt> in decaf448's field, | |||
corresponding to the curve448 base point with x = 5.</t> | corresponding to the curve448 base point with x = 5.</t> | |||
<section anchor="constants448"><name>Implementation constants</name> | <section anchor="constants448"><name>Implementation Constants</name> | |||
<t>This document references the following constant field element values | <t>This document references the following constant field element values | |||
that are used for the implementation of group operations.</t> | that are used for the implementation of group operations.</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li><t><tt>D</tt> = 726838724295606890549323807888004534353641360687318060281490 199180612328166730772686396383698676545930088884461843637361053498018326358</t> | <li><t><tt>D</tt> = 726838724295606890549323807888004534353641360687318060281490 199180612328166730772686396383698676545930088884461843637361053498018326358</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>This is the Edwards d parameter for edwards448, as specified in | <li>This is the Edwards d parameter for edwards448, as specified in | |||
Section 4.2 of <xref target="RFC7748"></xref>, and is equal to -39081 in the fie ld.</li> | <xref target="RFC7748" sectionFormat="of" section="4.2"></xref>, and is equal to -39081 in the field.</li> | |||
</ul></li> | </ul></li> | |||
<li><tt>ONE_MINUS_D</tt> = 39082</li> | <li><tt>ONE_MINUS_D</tt> = 39082</li> | |||
<li><tt>ONE_MINUS_TWO_D</tt> = 78163</li> | <li><tt>ONE_MINUS_TWO_D</tt> = 78163</li> | |||
<li><tt>SQRT_MINUS_D</tt> = 9894423364773221976917700487692901912841757629552990 10740998895980437021160012578568021315638965153739277122320928458832269224175962 14</li> | <li><tt>SQRT_MINUS_D</tt> = 9894423364773221976917700487692901912841757629552990 10740998895980437021160012578568021315638965153739277122320928458832269224175962 14</li> | |||
<li><tt>INVSQRT_MINUS_D</tt> = 3150199139313896073371770383309510435224560728972 66928557328499619017160722351061360252776265186336876723201881398623946864393857 820716</li> | <li><tt>INVSQRT_MINUS_D</tt> = 3150199139313896073371770383309510435224560728972 66928557328499619017160722351061360252776265186336876723201881398623946864393857 820716</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
<section anchor="sqrtratio448"><name>Square root of a ratio of field elements</n | <section anchor="sqrtratio448"><name>Square Root of a Ratio of Field Elements</n | |||
ame> | ame> | |||
<t>The following function is defined on field elements, and is used to | <t>The following function is defined on field elements and is used to | |||
implement other decaf448 functions. This function is only used internally | implement other decaf448 functions. This function is only used internally | |||
to implement some of the group operations.</t> | to implement some of the group operations.</t> | |||
<t>On input field elements u and v, the function <tt>SQRT_RATIO_M1(u, v)</tt> re turns:</t> | <t>On input field elements u and v, the function <tt>SQRT_RATIO_M1(u, v)</tt> re turns:</t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li><tt>(TRUE, +sqrt(u/v))</tt> if u and v are non-zero, and u/v is square;</li> | <li><tt>(TRUE, +sqrt(u/v))</tt> if u and v are nonzero and u/v is square in the field;</li> | |||
<li><tt>(TRUE, zero)</tt> if u is zero;</li> | <li><tt>(TRUE, zero)</tt> if u is zero;</li> | |||
<li><tt>(FALSE, zero)</tt> if v is zero and u is non-zero;</li> | <li><tt>(FALSE, zero)</tt> if v is zero and u is nonzero; and</li> | |||
<li><tt>(FALSE, +sqrt(-u/v))</tt> if u and v are non-zero, and u/v is | <li><tt>(FALSE, +sqrt(-u/v))</tt> if u and v are nonzero and u/v is | |||
non-square (so <tt>-(u/v)</tt> is square),</li> | non-square in the field (so <tt>-(u/v)</tt> is square in the field),</li> | |||
</ul> | </ul> | |||
<t>where <tt>+sqrt(x)</tt> indicates the non-negative square root of x in | <t>where <tt>+sqrt(x)</tt> indicates the nonnegative square root of x in | |||
the field.</t> | the field.</t> | |||
<t>The computation is similar to Section 5.2.3 of <xref target="RFC8032"></xref> | <t>The computation is similar to what is described in <xref target="RFC8032" sec | |||
, with the | tionFormat="of" section="5.2.3"></xref>, with the | |||
difference that if the input is non-square, the function returns a | difference that, if the input is non-square, the function returns a | |||
result with a defined relationship to the inputs. This result is used | result with a defined relationship to the inputs. This result is used | |||
for efficient implementation of the derivation function. The function | for efficient implementation of the derivation function. The function | |||
can be refactored from an existing edwards448 implementation.</t> | can be refactored from an existing edwards448 implementation.</t> | |||
<t><tt>SQRT_RATIO_M1(u, v)</tt> is defined as follows:</t> | <t><tt>SQRT_RATIO_M1(u, v)</tt> is defined as follows:</t> | |||
<artwork>r = u * (u * v)^((p - 3) / 4) // Note: (p - 3) / 4 is an integer. | <artwork><![CDATA[r = u * (u * v)^((p - 3) / 4) // Note: (p - 3) / 4 is an integ er. | |||
check = v * r^2 | check = v * r^2 | |||
was_square = CT_EQ(check, u) | was_square = CT_EQ(check, u) | |||
// Choose the nonnegative square root. | // Choose the nonnegative square root. | |||
r = CT_ABS(r) | r = CT_ABS(r) | |||
return (was_square, r) | return (was_square, r) | |||
</artwork> | ]]></artwork> | |||
</section> | </section> | |||
<section anchor="functions448"><name>decaf448 group operations</name> | <section anchor="functions448"><name>decaf448 Group Operations</name> | |||
<t>This section describes the implementation of the external functions | <t>This section describes the implementation of the external functions | |||
exposed by the decaf448 prime-order group.</t> | exposed by the decaf448 prime-order group.</t> | |||
<section anchor="decoding448"><name>Decode</name> | <section anchor="decoding448"><name>Decode</name> | |||
<t>All elements are encoded as 56-byte strings. Decoding proceeds as follows:</t > | <t>All elements are encoded as 56-byte strings. Decoding proceeds as follows:</t > | |||
<ol spacing="compact"> | <ol spacing="compact"> | |||
<li><t>First, interpret the string as an unsigned integer s in little-endian | <li>Interpret the string as an unsigned integer s in little-endian | |||
representation. If the length of the string is not 56 bytes, or if | representation. If the length of the string is not 56 bytes or if | |||
the resulting value is >= p, decoding fails.</t> | the resulting value is >= p, decoding fails.</li> | |||
</ol> | ||||
<ul spacing="compact"> | <aside><t>Note: Unlike the field element decoding described in <xref target="RFC | |||
<li>Note: unlike <xref target="RFC7748"></xref> field element decoding, non-cano | 7748"></xref>, non-canonical | |||
nical | ||||
values are rejected. The test vectors in <xref target="invalid448"></xref> exerc ise | values are rejected. The test vectors in <xref target="invalid448"></xref> exerc ise | |||
these edge cases.</li> | these edge cases.</t> | |||
</ul></li> | </aside> | |||
<ol spacing="compact" start="2"> | ||||
<li>If <tt>IS_NEGATIVE(s)</tt> returns TRUE, decoding fails.</li> | <li>If <tt>IS_NEGATIVE(s)</tt> returns TRUE, decoding fails.</li> | |||
<li>Process s as follows:</li> | <li>Process s as follows:</li> | |||
</ol> | </ol> | |||
<artwork>ss = s^2 | <artwork><![CDATA[ss = s^2 | |||
u1 = 1 + ss | u1 = 1 + ss | |||
u2 = u1^2 - 4 * D * ss | u2 = u1^2 - 4 * D * ss | |||
(was_square, invsqrt) = SQRT_RATIO_M1(1, u2 * u1^2) | (was_square, invsqrt) = SQRT_RATIO_M1(1, u2 * u1^2) | |||
u3 = CT_ABS(2 * s * invsqrt * u1 * SQRT_MINUS_D) | u3 = CT_ABS(2 * s * invsqrt * u1 * SQRT_MINUS_D) | |||
x = u3 * invsqrt * u2 * INVSQRT_MINUS_D | x = u3 * invsqrt * u2 * INVSQRT_MINUS_D | |||
y = (1 - ss) * invsqrt * u1 | y = (1 - ss) * invsqrt * u1 | |||
t = x * y | t = x * y | |||
</artwork> | ]]></artwork> | |||
<ol spacing="compact" start="4"> | <ol spacing="compact" start="4"> | |||
<li>If was_square is FALSE then decoding fails. Otherwise, | <li>If was_square is FALSE, then decoding fails. Otherwise, | |||
return the group element represented by the internal representation | return the group element represented by the internal representation | |||
<tt>(x, y, 1, t)</tt> as the result of decoding.</li> | <tt>(x, y, 1, t)</tt> as the result of decoding.</li> | |||
</ol> | </ol> | |||
</section> | </section> | |||
<section anchor="encoding448"><name>Encode</name> | <section anchor="encoding448"><name>Encode</name> | |||
<t>A group element with internal representation <tt>(x0, y0, z0, t0)</tt> is | <t>A group element with internal representation <tt>(x0, y0, z0, t0)</tt> is | |||
encoded as follows:</t> | encoded as follows:</t> | |||
<ol spacing="compact"> | <ol spacing="compact"> | |||
<li>Process the internal representation into a field element s as follows:</li> | <li>Process the internal representation into a field element s as follows:</li> | |||
</ol> | </ol> | |||
<artwork>u1 = (x0 + t0) * (x0 - t0) | <artwork><![CDATA[u1 = (x0 + t0) * (x0 - t0) | |||
// Ignore was_square since this is always square. | // Ignore was_square since this is always square. | |||
(_, invsqrt) = SQRT_RATIO_M1(1, u1 * ONE_MINUS_D * x0^2) | (_, invsqrt) = SQRT_RATIO_M1(1, u1 * ONE_MINUS_D * x0^2) | |||
ratio = CT_ABS(invsqrt * u1 * SQRT_MINUS_D) | ratio = CT_ABS(invsqrt * u1 * SQRT_MINUS_D) | |||
u2 = INVSQRT_MINUS_D * ratio * z0 - t0 | u2 = INVSQRT_MINUS_D * ratio * z0 - t0 | |||
s = CT_ABS(ONE_MINUS_D * invsqrt * x0 * u2) | s = CT_ABS(ONE_MINUS_D * invsqrt * x0 * u2) | |||
</artwork> | ]]></artwork> | |||
<ol spacing="compact" start="2"> | <ol spacing="compact" start="2"> | |||
<li>Return the 56-byte little-endian encoding of s. More specifically, | <li>Return the 56-byte little-endian encoding of s. More specifically, | |||
this is the encoding of the canonical representation of s as an integer | this is the encoding of the canonical representation of s as an integer | |||
between 0 and p-1, inclusive.</li> | between 0 and p-1, inclusive.</li> | |||
</ol> | </ol> | |||
<t>Note that decoding and then re-encoding a valid group element will | <t>Note that decoding and then re-encoding a valid group element will | |||
yield an identical byte string.</t> | yield an identical byte string.</t> | |||
</section> | </section> | |||
<section anchor="equals448"><name>Equals</name> | <section anchor="equals448"><name>Equals</name> | |||
<t>The equality function returns TRUE when two internal representations | <t>The equality function returns TRUE when two internal representations | |||
correspond to the same group element. Note that internal representations | correspond to the same group element. Note that internal representations | |||
<bcp14>MUST NOT</bcp14> be compared in any other way than specified here.</t> | <bcp14>MUST NOT</bcp14> be compared in any way other than specified here.</t> | |||
<t>For two internal representations <tt>(x1, y1, z1, t1)</tt> and <tt>(x2, y2, z 2, t2)</tt>, | <t>For two internal representations <tt>(x1, y1, z1, t1)</tt> and <tt>(x2, y2, z 2, t2)</tt>, | |||
if</t> | if</t> | |||
<artwork>x1 * y2 == y1 * x2 | <artwork><![CDATA[CT_EQ(x1 * y2, y1 * x2) | |||
</artwork> | ]]></artwork> | |||
<t>evaluates to TRUE, then return TRUE. Otherwise, return FALSE.</t> | <t>evaluates to TRUE, then return TRUE. Otherwise, return FALSE.</t> | |||
<t>Note that the equality function always returns TRUE when applied to an | <t>Note that the equality function always returns TRUE when applied to an | |||
internal representation and to the internal representation obtained by | internal representation and to the internal representation obtained by | |||
encoding and then re-decoding it. However, the internal | encoding and then re-decoding it. However, the internal | |||
representations themselves might not be identical.</t> | representations themselves might not be identical.</t> | |||
<t>Implementations <bcp14>MAY</bcp14> also perform byte comparisons on the encod ings | <t>Implementations <bcp14>MAY</bcp14> also perform constant-time byte comparison s on the encodings | |||
of group elements (produced by <xref target="encoding448"></xref>) for an equiva lent, although | of group elements (produced by <xref target="encoding448"></xref>) for an equiva lent, although | |||
less efficient, result.</t> | less efficient, result.</t> | |||
</section> | </section> | |||
<section anchor="from_bytes_uniform448"><name>Element derivation</name> | <section anchor="from_bytes_uniform448"><name>Element Derivation</name> | |||
<t>The element derivation function operates on 112-byte strings. | <t>The element derivation function operates on 112-byte strings. | |||
To obtain such an input from an arbitrary-length byte string, applications | To obtain such an input from an arbitrary-length byte string, applications | |||
should use a domain-separated hash construction, the choice of which | should use a domain-separated hash construction, the choice of which | |||
is out-of-scope for this document.</t> | is out of scope for this document.</t> | |||
<t>The element derivation function on an input string b proceeds as follows:</t> | <t>The element derivation function on an input string b proceeds as follows:</t> | |||
<ol spacing="compact"> | <ol spacing="compact"> | |||
<li>Compute P1 as <tt>MAP(b[0:56])</tt>.</li> | <li>Compute P1 as <tt>MAP(b[0:56])</tt>.</li> | |||
<li>Compute P2 as <tt>MAP(b[56:112])</tt>.</li> | <li>Compute P2 as <tt>MAP(b[56:112])</tt>.</li> | |||
<li>Return P1 + P2.</li> | <li>Return P1 + P2.</li> | |||
</ol> | </ol> | |||
<t>The MAP function is defined on 56-byte strings as:</t> | <t>The MAP function is defined on 56-byte strings as:</t> | |||
<ol> | <ol spacing="compact"> | |||
<li><t>Interpret the string as an unsigned integer r in little-endian representa | <li>Interpret the string as an unsigned integer r in little-endian representatio | |||
tion. | n. | |||
Reduce r modulo p to obtain a field element t.</t> | Reduce r modulo p to obtain a field element t.</li> | |||
</ol> | ||||
<ul spacing="compact"> | <aside><t>Note: Similar to the field element decoding described in <xref target= | |||
<li>Note: similarly to <xref target="RFC7748"></xref> field element decoding, an | "RFC7748"></xref>, and unlike | |||
d unlike | the field element decoding described in <xref target="decoding448"></xref>, non- | |||
field element decoding in <xref target="decoding448"></xref>, non-canonical valu | canonical values are | |||
es are | accepted.</t> | |||
accepted.</li> | </aside> | |||
</ul></li> | ||||
<li><t>Process t as follows:</t> | <ol spacing="compact" start="2"> | |||
</li> | <li>Process t as follows:</li> | |||
</ol> | </ol> | |||
<artwork>r = -t^2 | <artwork><![CDATA[r = -t^2 | |||
u0 = d * (r-1) | u0 = d * (r-1) | |||
u1 = (u0 + 1) * (u0 - r) | u1 = (u0 + 1) * (u0 - r) | |||
(was_square, v) = SQRT_RATIO_M1(ONE_MINUS_TWO_D, (r + 1) * u1) | (was_square, v) = SQRT_RATIO_M1(ONE_MINUS_TWO_D, (r + 1) * u1) | |||
v_prime = CT_SELECT(v IF was_square ELSE t * v) | v_prime = CT_SELECT(v IF was_square ELSE t * v) | |||
sgn = CT_SELECT(1 IF was_square ELSE -1) | sgn = CT_SELECT(1 IF was_square ELSE -1) | |||
s = v_prime * (r + 1) | s = v_prime * (r + 1) | |||
w0 = 2 * CT_ABS(s) | w0 = 2 * CT_ABS(s) | |||
w1 = s^2 + 1 | w1 = s^2 + 1 | |||
w2 = s^2 - 1 | w2 = s^2 - 1 | |||
w3 = v_prime * s * (r - 1) * ONE_MINUS_TWO_D + sgn | w3 = v_prime * s * (r - 1) * ONE_MINUS_TWO_D + sgn | |||
</artwork> | ]]></artwork> | |||
<ol spacing="compact" start="3"> | <ol spacing="compact" start="3"> | |||
<li>Return the group element represented by the internal representation | <li>Return the group element represented by the internal representation | |||
<tt>(w0*w3, w2*w1, w1*w3, w0*w2)</tt>.</li> | <tt>(w0*w3, w2*w1, w1*w3, w0*w2)</tt>.</li> | |||
</ol> | </ol> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="scalar-field-1"><name>Scalar field</name> | <section anchor="scalar-field-1"><name>Scalar Field</name> | |||
<t>The scalars for the decaf448 group are integers modulo the order l | <t>The scalars for the decaf448 group are integers modulo the order <tt>l</tt> | |||
of the decaf448 group. Note that this is the same scalar field as | of the decaf448 group. Note that this is the same scalar field as | |||
edwards448, allowing existing implementations to be reused.</t> | edwards448, allowing existing implementations to be reused.</t> | |||
<t>Scalars are encoded as 56-byte strings in little-endian order. | <t>Scalars are encoded as 56-byte strings in little-endian order. | |||
Implementations <bcp14>SHOULD</bcp14> check that any scalar s falls in the range | Implementations <bcp14>SHOULD</bcp14> check that any scalar s falls in the range | |||
0 <= s < l when parsing them and reject non-canonical scalar | 0 <= s < <tt>l</tt> when parsing them and reject non-canonical scalar | |||
encodings. Implementations <bcp14>SHOULD</bcp14> reduce scalars modulo l when | encodings. Implementations <bcp14>SHOULD</bcp14> reduce scalars modulo <tt>l</tt | |||
> when | ||||
encoding them as byte strings. Omitting these strict range checks is | encoding them as byte strings. Omitting these strict range checks is | |||
<bcp14>NOT RECOMMENDED</bcp14> but is allowed to enable reuse of scalar | <bcp14>NOT RECOMMENDED</bcp14> but is allowed to enable reuse of scalar | |||
arithmetic implementations in existing edwards448 libraries.</t> | arithmetic implementations in existing edwards448 libraries.</t> | |||
<t>Given a uniformly distributed 64-byte string b, implementations can | <t>Given a uniformly distributed 64-byte string b, implementations can | |||
obtain a uniformly distributed scalar by interpreting the 64-byte | obtain a uniformly distributed scalar by interpreting the 64-byte | |||
string as a 512-bit unsigned integer in little-endian order and reducing the | string as a 512-bit unsigned integer in little-endian order and reducing the | |||
integer modulo l. To obtain such an input from an arbitrary-length | integer modulo <tt>l</tt>. To obtain such an input from an arbitrary-length | |||
byte string, applications should use a domain-separated hash | byte string, applications should use a domain-separated hash | |||
construction, the choice of which is out-of-scope for this document.</t> | construction, the choice of which is out of scope for this document.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="api"><name>API Considerations</name> | <section anchor="api"><name>API Considerations</name> | |||
<t>ristretto255 and decaf448 are abstractions which implement two prime-order | <t>ristretto255 and decaf448 are abstractions that implement two prime-order | |||
groups, and their elements are represented by curve points, but they are | groups. Their elements are represented by curve points, but are not curve | |||
not curve points. Implementations <bcp14>SHOULD</bcp14> reflect that: the type | points, and implementations <bcp14>SHOULD</bcp14> reflect that fact. That is, th | |||
e type | ||||
representing an element of the group <bcp14>SHOULD</bcp14> be opaque to the call er, | representing an element of the group <bcp14>SHOULD</bcp14> be opaque to the call er, | |||
meaning they do not expose the underlying curve point or field elements. | meaning they do not expose the underlying curve point or field elements. | |||
Moreover, implementations <bcp14>SHOULD NOT</bcp14> expose any internal constant s | Moreover, implementations <bcp14>SHOULD NOT</bcp14> expose any internal constant s | |||
or functions used in the implementation of the group operations.</t> | or functions used in the implementation of the group operations.</t> | |||
<t>The reason for this encapsulation is that ristretto255 and decaf448 implement ations | <t>The reason for this encapsulation is that ristretto255 and decaf448 implement ations | |||
can change their underlying curve without causing any breaking change. The ristr etto255 | can change their underlying curve without causing any breaking change. The ristr etto255 | |||
and decaf448 constructions are carefully designed so that this will be the | and decaf448 constructions are carefully designed so that this will be the | |||
case, as long as implementations do not expose internal representations or | case, as long as implementations do not expose internal representations or | |||
operate on them except as described in this document. In particular, | operate on them except as described in this document. In particular, | |||
implementations <bcp14>SHOULD NOT</bcp14> define any external ristretto255 or de caf448 | implementations <bcp14>SHOULD NOT</bcp14> define any external ristretto255 or de caf448 | |||
interface as operating on arbitrary curve points, and they <bcp14>SHOULD NOT</bc p14> | interface as operating on arbitrary curve points, and they <bcp14>SHOULD NOT</bc p14> | |||
construct group elements except via decoding, the element derivation function, | construct group elements except via decoding, the element derivation function, | |||
or group operations on other valid group elements per <xref target="interface">< | or group operations on other valid group elements per <xref target="interface">< | |||
/xref>. They are | /xref>. However, they are | |||
however allowed to apply any optimization strategy to the internal | allowed to apply any optimization strategy to the internal | |||
representations as long as it doesn't change the exposed behavior of the | representations as long as it doesn't change the exposed behavior of the | |||
API.</t> | API.</t> | |||
<t>It is <bcp14>RECOMMENDED</bcp14> that implementations do not perform a decodi ng and | <t>It is <bcp14>RECOMMENDED</bcp14> that implementations not perform a decoding and | |||
encoding operation for each group operation, as it is inefficient and | encoding operation for each group operation, as it is inefficient and | |||
unnecessary. Implementations <bcp14>SHOULD</bcp14> instead provide an opaque typ e | unnecessary. Implementations <bcp14>SHOULD</bcp14> instead provide an opaque typ e | |||
to hold the internal representation through multiple operations.</t> | to hold the internal representation through multiple operations.</t> | |||
</section> | </section> | |||
<section anchor="iana-considerations"><name>IANA Considerations</name> | <section anchor="iana-considerations"><name>IANA Considerations</name> | |||
<t>This document has no IANA actions.</t> | <t>This document has no IANA actions.</t> | |||
</section> | </section> | |||
<section anchor="security-considerations"><name>Security Considerations</name> | <section anchor="security-considerations"><name>Security Considerations</name> | |||
<t>The ristretto255 and decaf448 groups provide higher-level protocols with | <t>The ristretto255 and decaf448 groups provide higher-level protocols with | |||
the abstraction they expect: a prime-order group. Therefore, it's expected | the abstraction they expect: a prime-order group. Therefore, it's expected | |||
to be safer for use in any situation where Curve25519 or edwards448 is used | to be safer for use in any situation where Curve25519 or edwards448 is used | |||
to implement a protocol requiring a prime-order group. Note that the safety | to implement a protocol requiring a prime-order group. Note that the safety | |||
of the abstraction can be defeated by implementations that do not follow | of the abstraction can be defeated by implementations that do not follow | |||
the guidance in <xref target="api"></xref>.</t> | the guidance in <xref target="api"></xref>.</t> | |||
<t>There is no function to test whether an elliptic curve point is a | <t>There is no function to test whether an elliptic curve point is a | |||
valid internal representation of a group element. The decoding | valid internal representation of a group element. The decoding | |||
function always returns a valid internal representation, or an error, and | function always returns a valid internal representation or an error, and | |||
allowed operations on valid internal representations return valid | operations exposed by the group per <xref target="interface"></xref> return vali | |||
internal representations. In this way, an implementation can maintain | d internal | |||
representations when applied to valid internal representations. | ||||
In this way, an implementation can maintain | ||||
the invariant that an internal representation is always valid, so that | the invariant that an internal representation is always valid, so that | |||
checking is never necessary, and invalid states are unrepresentable.</t> | checking is never necessary, and invalid states are unrepresentable.</t> | |||
</section> | </section> | |||
<section anchor="acknowledgements"><name>Acknowledgements</name> | ||||
<t>The authors would like to thank Daira Hopwood, Riad S. Wahby, Christopher Woo | ||||
d, | ||||
and Thomas Pornin for their comments on the draft.</t> | ||||
</section> | ||||
</middle> | </middle> | |||
<back> | <back> | |||
<references><name>References</name> | ||||
<references><name>Normative References</name> | <references><name>Normative References</name> | |||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119. | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" | |||
xml"/> | /> | |||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8174. | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" | |||
xml"/> | /> | |||
</references> | </references> | |||
<references><name>Informative References</name> | <references><name>Informative References</name> | |||
<reference anchor="Decaf" target="https://www.shiftleft.org/papers/decaf/decaf.p df"> | <reference anchor="Decaf" target="https://www.shiftleft.org/papers/decaf/decaf.p df"> | |||
<front> | <front> | |||
<title>Decaf: Eliminating cofactors through point
compression</title> | <title>Decaf: Eliminating cofactors through point compression</title> | |||
<author fullname="Mike Hamburg" initials="M." surname="Hamburg"> | <author fullname="Mike Hamburg" initials="M." surname="Hamburg"> | |||
<organization>Rambus Cryptography Research</organization> | <organization>Rambus Cryptography Research</organization> | |||
</author> | </author> | |||
<date year="2015"></date> | <date year="2015"></date> | |||
</front> | </front> | |||
</reference> | </reference> | |||
<reference anchor="Ed25519ValidCrit" target="https://hdevalence.ca/blog/2020-10- | ||||
04-its-25519am"> | ||||
<front> | ||||
<title>It's 255:19AM. Do you know what your validation criteria are?</title> | ||||
<author fullname="Henry de Valence" initials="H" surname="de Valence"></auth | ||||
or> | ||||
<date year="2020" month="October" day="4"></date> | ||||
</front> | ||||
</reference> | ||||
<reference anchor="MoneroVuln" target="https://jonasnick.github.io/blog/2017/05/ 23/exploiting-low-order-generators-in-one-time-ring-signatures/"> | <reference anchor="MoneroVuln" target="https://jonasnick.github.io/blog/2017/05/ 23/exploiting-low-order-generators-in-one-time-ring-signatures/"> | |||
<front> | <front> | |||
<title>Exploiting Low Order Generators in One-Time Ring Signatures</title> | <title>Exploiting Low Order Generators in One-Time Ring Signatures</title> | |||
<author fullname="Jonas Nick" initials="J." surname="Nick"></author> | <author fullname="Jonas Nick" initials="J." surname="Nick"></author> | |||
<date year="2017"></date> | <date year="2017" month="May"></date> | |||
</front> | </front> | |||
</reference> | </reference> | |||
<reference anchor="Naming" target="https://mailarchive.ietf.org/arch/msg/cfrg/-9 LEdnzVrE5RORux3Oo_oDDRksU/"> | <reference anchor="Naming" target="https://mailarchive.ietf.org/arch/msg/cfrg/-9 LEdnzVrE5RORux3Oo_oDDRksU/"> | |||
<front> | <front> | |||
<title>[Cfrg] 25519 naming</title> | <title>Subject: [Cfrg] 25519 naming</title> | |||
<author fullname="Daniel J. Bernstein" initials="D. J." surname="Bernstein"> </author> | <author fullname="Daniel J. Bernstein" initials="D. J." surname="Bernstein"> </author> | |||
<date year="2014"></date> | <date year="2014" month="August" day="26"></date> | |||
</front> | </front> | |||
<refcontent>message to the Cfrg mailing list</refcontent> | ||||
</reference> | </reference> | |||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7748. | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7748.xml" | |||
xml"/> | /> | |||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8032. | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8032.xml" | |||
xml"/> | /> | |||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9380.xml" | ||||
/> | ||||
<reference anchor="RistrettoGroup" target="https://ristretto.group"> | <reference anchor="RistrettoGroup" target="https://ristretto.group"> | |||
<front> | <front> | |||
<title>The Ristretto Group</title> | <title>The Ristretto Group</title> | |||
<author fullname="Henry de Valence" initials="H" surname="de Valence"></auth or> | <author fullname="Henry de Valence" initials="H" surname="de Valence"></auth or> | |||
<author fullname="isis lovecruft" initials="I" surname="Lovecruft"></author> | <author fullname="Isis Lovecruft" initials="I" surname="Lovecruft"></author> | |||
<author fullname="Tony Arcieri" initials="T" surname="Arcieri"></author> | <author fullname="Tony Arcieri" initials="T" surname="Arcieri"></author> | |||
<author fullname="Mike Hamburg" initials="M" surname="Hamburg"></author> | <author fullname="Mike Hamburg" initials="M" surname="Hamburg"></author> | |||
<date year="2018"></date> | <date></date> | |||
</front> | </front> | |||
</reference> | </reference> | |||
<reference anchor="Twisted" target="https://eprint.iacr.org/2008/522"> | <reference anchor="Twisted" target="https://eprint.iacr.org/2008/522"> | |||
<front> | <front> | |||
<title>Twisted Edwards Curves Revisited</title> | <title>Twisted Edwards Curves Revisited</title> | |||
<author fullname="Huseyin Hisil" initials="H." surname="Hisil"></author> | <author fullname="Huseyin Hisil" initials="H." surname="Hisil"></author> | |||
<author fullname="Kenneth Koon-Ho Wong" initials="K. K." surname="Wong"></au thor> | <author fullname="Kenneth Koon-Ho Wong" initials="K. K." surname="Wong"></au thor> | |||
<author fullname="Gary Carter" initials="G." surname="Carter"></author> | <author fullname="Gary Carter" initials="G." surname="Carter"></author> | |||
<author fullname="Ed Dawson" initials="E." surname="Dawson"></author> | <author fullname="Ed Dawson" initials="E." surname="Dawson"></author> | |||
<date year="2008"></date> | <date year="2008" month="December"></date> | |||
</front> | ||||
</reference> | ||||
<reference anchor="draft-irtf-cfrg-hash-to-curve-16" target="https://datatracker | ||||
.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/"> | ||||
<front> | ||||
<title>Hashing to Elliptic Curves</title> | ||||
<author fullname="Armando Faz-Hernández" initials="A." surname="Faz-Hernánde | ||||
z"></author> | ||||
<author fullname="Sam Scott" initials="S." surname="Scott"></author> | ||||
<author fullname="Nick Sullivan" initials="N." surname="Sullivan"></author> | ||||
<author fullname="Riad S. Wahby" initials="R.S." surname="Wahby"></author> | ||||
<author fullname="Christopher A. Wood" initials="C.A." surname="Wood"></auth | ||||
or> | ||||
<date year="2022"></date> | ||||
</front> | </front> | |||
<refcontent>Cryptology ePrint Archive, Paper 2008/522</refcontent> | ||||
</reference> | </reference> | |||
</references> | </references> | |||
</references> | ||||
<section anchor="test-vectors-for-ristretto255"><name>Test vectors for ristretto 255</name> | <section anchor="test-vectors-for-ristretto255"><name>Test Vectors for ristretto 255</name> | |||
<t>This section contains test vectors for ristretto255. The octets are | <t>This section contains test vectors for ristretto255. The octets are | |||
hex encoded, and whitespace is inserted for readability.</t> | hex encoded, and whitespace is inserted for readability.</t> | |||
<section anchor="multiples-of-the-generator"><name>Multiples of the generator</n ame> | <section anchor="multiples-of-the-generator"><name>Multiples of the Generator</n ame> | |||
<t>The following are the encodings of the multiples 0 to 15 of the | <t>The following are the encodings of the multiples 0 to 15 of the | |||
canonical generator, represented as an array of elements. That is, | canonical generator, represented as an array of elements. That is, | |||
the first entry is the encoding of the identity element, and each | the first entry is the encoding of the identity element, and each | |||
successive entry is obtained by adding the generator to the previous entry.</t> | successive entry is obtained by adding the generator to the previous entry.</t> | |||
<artwork>B[ 0]: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0 | <sourcecode type="test-vectors"><![CDATA[B[ 0]: 00000000 00000000 00000000 00000 | |||
0000000 | 000 00000000 00000000 00000000 | |||
B[ 1]: e2f2ae0a 6abc4e71 a884a961 c500515f 58e30b6a a582dd8d b6a65945 e08d2d76 | 00000000 | |||
B[ 2]: 6a493210 f7499cd1 7fecb510 ae0cea23 a110e8d5 b901f8ac add3095c 73a3b919 | B[ 1]: e2f2ae0a 6abc4e71 a884a961 c500515f 58e30b6a a582dd8d b6a65945 | |||
B[ 3]: 94741f5d 5d52755e ce4f23f0 44ee27d5 d1ea1e2b d196b462 166b1615 2a9d0259 | e08d2d76 | |||
B[ 4]: da808627 73358b46 6ffadfe0 b3293ab3 d9fd53c5 ea6c9553 58f56832 2daf6a57 | B[ 2]: 6a493210 f7499cd1 7fecb510 ae0cea23 a110e8d5 b901f8ac add3095c | |||
B[ 5]: e882b131 016b52c1 d3337080 187cf768 423efccb b517bb49 5ab812c4 160ff44e | 73a3b919 | |||
B[ 6]: f64746d3 c92b1305 0ed8d802 36a7f000 7c3b3f96 2f5ba793 d19a601e bb1df403 | B[ 3]: 94741f5d 5d52755e ce4f23f0 44ee27d5 d1ea1e2b d196b462 166b1615 | |||
B[ 7]: 44f53520 926ec81f bd5a3878 45beb7df 85a96a24 ece18738 bdcfa6a7 822a176d | 2a9d0259 | |||
B[ 8]: 903293d8 f2287ebe 10e2374d c1a53e0b c887e592 699f02d0 77d5263c dd55601c | B[ 4]: da808627 73358b46 6ffadfe0 b3293ab3 d9fd53c5 ea6c9553 58f56832 | |||
B[ 9]: 02622ace 8f7303a3 1cafc63f 8fc48fdc 16e1c8c8 d234b2f0 d6685282 a9076031 | 2daf6a57 | |||
B[10]: 20706fd7 88b2720a 1ed2a5da d4952b01 f413bcf0 e7564de8 cdc81668 9e2db95f | B[ 5]: e882b131 016b52c1 d3337080 187cf768 423efccb b517bb49 5ab812c4 | |||
B[11]: bce83f8b a5dd2fa5 72864c24 ba1810f9 522bc600 4afe9587 7ac73241 cafdab42 | 160ff44e | |||
B[12]: e4549ee1 6b9aa030 99ca208c 67adafca fa4c3f3e 4e5303de 6026e3ca 8ff84460 | B[ 6]: f64746d3 c92b1305 0ed8d802 36a7f000 7c3b3f96 2f5ba793 d19a601e | |||
B[13]: aa52e000 df2e16f5 5fb1032f c33bc427 42dad6bd 5a8fc0be 0167436c 5948501f | bb1df403 | |||
B[14]: 46376b80 f409b29d c2b5f6f0 c5259199 0896e571 6f41477c d30085ab 7f10301e | B[ 7]: 44f53520 926ec81f bd5a3878 45beb7df 85a96a24 ece18738 bdcfa6a7 | |||
B[15]: e0c418f7 c8d9c4cd d7395b93 ea124f3a d99021bb 681dfc33 02a9d99a 2e53e64e | 822a176d | |||
</artwork> | B[ 8]: 903293d8 f2287ebe 10e2374d c1a53e0b c887e592 699f02d0 77d5263c | |||
dd55601c | ||||
B[ 9]: 02622ace 8f7303a3 1cafc63f 8fc48fdc 16e1c8c8 d234b2f0 d6685282 | ||||
a9076031 | ||||
B[10]: 20706fd7 88b2720a 1ed2a5da d4952b01 f413bcf0 e7564de8 cdc81668 | ||||
9e2db95f | ||||
B[11]: bce83f8b a5dd2fa5 72864c24 ba1810f9 522bc600 4afe9587 7ac73241 | ||||
cafdab42 | ||||
B[12]: e4549ee1 6b9aa030 99ca208c 67adafca fa4c3f3e 4e5303de 6026e3ca | ||||
8ff84460 | ||||
B[13]: aa52e000 df2e16f5 5fb1032f c33bc427 42dad6bd 5a8fc0be 0167436c | ||||
5948501f | ||||
B[14]: 46376b80 f409b29d c2b5f6f0 c5259199 0896e571 6f41477c d30085ab | ||||
7f10301e | ||||
B[15]: e0c418f7 c8d9c4cd d7395b93 ea124f3a d99021bb 681dfc33 02a9d99a | ||||
2e53e64e | ||||
]]></sourcecode> | ||||
<t>Note that because</t> | <t>Note that because</t> | |||
<artwork>B[i+1] = B[i] + B[1] | <artwork><![CDATA[B[i+1] = B[i] + B[1] | |||
</artwork> | ]]></artwork> | |||
<t>these test vectors allow testing the encoding function and | <t>these test vectors allow testing of the encoding function and | |||
the implementation of addition simultaneously.</t> | the implementation of addition simultaneously.</t> | |||
</section> | </section> | |||
<section anchor="invalid255"><name>Invalid encodings</name> | <section anchor="invalid255"><name>Invalid Encodings</name> | |||
<t>These are examples of encodings that <bcp14>MUST</bcp14> be rejected accordin g to | <t>These are examples of encodings that <bcp14>MUST</bcp14> be rejected accordin g to | |||
<xref target="decoding255"></xref>.</t> | <xref target="decoding255"></xref>.</t> | |||
<artwork># Non-canonical field encodings. | <sourcecode type="test-vectors"><![CDATA[# Non-canonical field encodings. | |||
00ffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | 00ffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | |||
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffff7f | ffffffff | |||
f3ffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffff7f | ||||
edffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffff7f | ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | |||
ffffff7f | ||||
f3ffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | ||||
ffffff7f | ||||
edffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | ||||
ffffff7f | ||||
# Negative field elements. | # Negative field elements. | |||
01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | 01000000 00000000 00000000 00000000 00000000 00000000 00000000 | |||
01ffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffff7f | 00000000 | |||
ed57ffd8 c914fb20 1471d1c3 d245ce3c 746fcbe6 3a3679d5 1b6a516e bebe0e20 | ||||
c34c4e18 26e5d403 b78e246e 88aa051c 36ccf0aa febffe13 7d148a2b f9104562 | 01ffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | |||
c940e5a4 404157cf b1628b10 8db051a8 d439e1a4 21394ec4 ebccb9ec 92a8ac78 | ffffff7f | |||
47cfc549 7c53dc8e 61c91d17 fd626ffb 1c49e2bc a94eed05 2281b510 b1117a24 | ||||
f1c6165d 33367351 b0da8f6e 4511010c 68174a03 b6581212 c71c0e1d 026c3c72 | ed57ffd8 c914fb20 1471d1c3 d245ce3c 746fcbe6 3a3679d5 1b6a516e | |||
87260f7a 2f124951 18360f02 c26a470f 450dadf3 4a413d21 042b43b9 d93e1309 | bebe0e20 | |||
c34c4e18 26e5d403 b78e246e 88aa051c 36ccf0aa febffe13 7d148a2b | ||||
f9104562 | ||||
c940e5a4 404157cf b1628b10 8db051a8 d439e1a4 21394ec4 ebccb9ec | ||||
92a8ac78 | ||||
47cfc549 7c53dc8e 61c91d17 fd626ffb 1c49e2bc a94eed05 2281b510 | ||||
b1117a24 | ||||
f1c6165d 33367351 b0da8f6e 4511010c 68174a03 b6581212 c71c0e1d | ||||
026c3c72 | ||||
87260f7a 2f124951 18360f02 c26a470f 450dadf3 4a413d21 042b43b9 | ||||
d93e1309 | ||||
# Non-square x^2. | # Non-square x^2. | |||
26948d35 ca62e643 e26a8317 7332e6b6 afeb9d08 e4268b65 0f1f5bbd 8d81d371 | 26948d35 ca62e643 e26a8317 7332e6b6 afeb9d08 e4268b65 0f1f5bbd | |||
4eac077a 713c57b4 f4397629 a4145982 c661f480 44dd3f96 427d40b1 47d9742f | 8d81d371 | |||
de6a7b00 deadc788 eb6b6c8d 20c0ae96 c2f20190 78fa604f ee5b87d6 e989ad7b | ||||
bcab477b e20861e0 1e4a0e29 5284146a 510150d9 817763ca f1a6f4b4 22d67042 | ||||
2a292df7 e32cabab bd9de088 d1d1abec 9fc0440f 637ed2fb a145094d c14bea08 | ||||
f4a9e534 fc0d216c 44b218fa 0c42d996 35a0127e e2e53c71 2f706096 49fdff22 | ||||
8268436f 8c412619 6cf64b3c 7ddbda90 746a3786 25f9813d d9b84570 77256731 | ||||
2810e5cb c2cc4d4e ece54f61 c6f69758 e289aa7a b440b3cb eaa21995 c2f4232b | ||||
# Negative xy value. | 4eac077a 713c57b4 f4397629 a4145982 c661f480 44dd3f96 427d40b1 | |||
3eb858e7 8f5a7254 d8c97311 74a94f76 755fd394 1c0ac937 35c07ba1 4579630e | 47d9742f | |||
a45fdc55 c76448c0 49a1ab33 f17023ed fb2be358 1e9c7aad e8a61252 15e04220 | ||||
d483fe81 3c6ba647 ebbfd3ec 41adca1c 6130c2be eee9d9bf 065c8d15 1c5f396e | de6a7b00 deadc788 eb6b6c8d 20c0ae96 c2f20190 78fa604f ee5b87d6 | |||
8a2e1d30 050198c6 5a544831 23960ccc 38aef684 8e1ec8f5 f780e852 3769ba32 | e989ad7b | |||
32888462 f8b486c6 8ad7dd96 10be5192 bbeaf3b4 43951ac1 a8118419 d9fa097b | ||||
22714250 1b9d4355 ccba2904 04bde415 75b03769 3cef1f43 8c47f8fb f35d1165 | bcab477b e20861e0 1e4a0e29 5284146a 510150d9 817763ca f1a6f4b4 | |||
5c37cc49 1da847cf eb9281d4 07efc41e 15144c87 6e0170b4 99a96a22 ed31e01e | 22d67042 | |||
44542511 7cb8c90e dcbc7c1c c0e74f74 7f2c1efa 5630a967 c64f2877 92a48a4b | ||||
2a292df7 e32cabab bd9de088 d1d1abec 9fc0440f 637ed2fb a145094d | ||||
c14bea08 | ||||
f4a9e534 fc0d216c 44b218fa 0c42d996 35a0127e e2e53c71 2f706096 | ||||
49fdff22 | ||||
8268436f 8c412619 6cf64b3c 7ddbda90 746a3786 25f9813d d9b84570 | ||||
77256731 | ||||
2810e5cb c2cc4d4e ece54f61 c6f69758 e289aa7a b440b3cb eaa21995 | ||||
c2f4232b | ||||
# Negative x * y value. | ||||
3eb858e7 8f5a7254 d8c97311 74a94f76 755fd394 1c0ac937 35c07ba1 | ||||
4579630e | ||||
a45fdc55 c76448c0 49a1ab33 f17023ed fb2be358 1e9c7aad e8a61252 | ||||
15e04220 | ||||
d483fe81 3c6ba647 ebbfd3ec 41adca1c 6130c2be eee9d9bf 065c8d15 | ||||
1c5f396e | ||||
8a2e1d30 050198c6 5a544831 23960ccc 38aef684 8e1ec8f5 f780e852 | ||||
3769ba32 | ||||
32888462 f8b486c6 8ad7dd96 10be5192 bbeaf3b4 43951ac1 a8118419 | ||||
d9fa097b | ||||
22714250 1b9d4355 ccba2904 04bde415 75b03769 3cef1f43 8c47f8fb | ||||
f35d1165 | ||||
5c37cc49 1da847cf eb9281d4 07efc41e 15144c87 6e0170b4 99a96a22 | ||||
ed31e01e | ||||
44542511 7cb8c90e dcbc7c1c c0e74f74 7f2c1efa 5630a967 c64f2877 | ||||
92a48a4b | ||||
# s = -1, which causes y = 0. | # s = -1, which causes y = 0. | |||
ecffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffff7f | ecffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | |||
</artwork> | ffffff7f | |||
]]></sourcecode> | ||||
</section> | </section> | |||
<section anchor="group-elements-from-byte-strings"><name>Group elements from byt e strings</name> | <section anchor="group-elements-from-uniform-byte-strings"><name>Group Elements from Uniform Byte Strings</name> | |||
<t>The following pairs are inputs to the element derivation function of | <t>The following pairs are inputs to the element derivation function of | |||
<xref target="from_bytes_uniform255"></xref>, and their encoded outputs.</t> | <xref target="from_bytes_uniform255"></xref> and their encoded outputs.</t> | |||
<artwork>I: 5d1be09e3d0c82fc538112490e35701979d99e06ca3e2b5b54bffe8b4dc772c1 | <sourcecode type="test-vectors"><![CDATA[I: 5d1be09e3d0c82fc538112490e35701979d9 9e06ca3e2b5b54bffe8b4dc772c1 | |||
4d98b696a1bbfb5ca32c436cc61c16563790306c79eaca7705668b47dffe5bb6 | 4d98b696a1bbfb5ca32c436cc61c16563790306c79eaca7705668b47dffe5bb6 | |||
O: 3066f82a 1a747d45 120d1740 f1435853 1a8f04bb ffe6a819 f86dfe50 f44a0a46 | O: 3066f82a 1a747d45 120d1740 f1435853 1a8f04bb ffe6a819 f86dfe50 | |||
f44a0a46 | ||||
I: f116b34b8f17ceb56e8732a60d913dd10cce47a6d53bee9204be8b44f6678b27 | I: f116b34b8f17ceb56e8732a60d913dd10cce47a6d53bee9204be8b44f6678b27 | |||
0102a56902e2488c46120e9276cfe54638286b9e4b3cdb470b542d46c2068d38 | 0102a56902e2488c46120e9276cfe54638286b9e4b3cdb470b542d46c2068d38 | |||
O: f26e5b6f 7d362d2d 2a94c5d0 e7602cb4 773c95a2 e5c31a64 f133189f a76ed61b | O: f26e5b6f 7d362d2d 2a94c5d0 e7602cb4 773c95a2 e5c31a64 f133189f | |||
a76ed61b | ||||
I: 8422e1bbdaab52938b81fd602effb6f89110e1e57208ad12d9ad767e2e25510c | I: 8422e1bbdaab52938b81fd602effb6f89110e1e57208ad12d9ad767e2e25510c | |||
27140775f9337088b982d83d7fcf0b2fa1edffe51952cbe7365e95c86eaf325c | 27140775f9337088b982d83d7fcf0b2fa1edffe51952cbe7365e95c86eaf325c | |||
O: 006ccd2a 9e6867e6 a2c5cea8 3d3302cc 9de128dd 2a9a57dd 8ee7b9d7 ffe02826 | O: 006ccd2a 9e6867e6 a2c5cea8 3d3302cc 9de128dd 2a9a57dd 8ee7b9d7 | |||
ffe02826 | ||||
I: ac22415129b61427bf464e17baee8db65940c233b98afce8d17c57beeb7876c2 | I: ac22415129b61427bf464e17baee8db65940c233b98afce8d17c57beeb7876c2 | |||
150d15af1cb1fb824bbd14955f2b57d08d388aab431a391cfc33d5bafb5dbbaf | 150d15af1cb1fb824bbd14955f2b57d08d388aab431a391cfc33d5bafb5dbbaf | |||
O: f8f0c87c f237953c 5890aec3 99816900 5dae3eca 1fbb0454 8c635953 c817f92a | O: f8f0c87c f237953c 5890aec3 99816900 5dae3eca 1fbb0454 8c635953 | |||
c817f92a | ||||
I: 165d697a1ef3d5cf3c38565beefcf88c0f282b8e7dbd28544c483432f1cec767 | I: 165d697a1ef3d5cf3c38565beefcf88c0f282b8e7dbd28544c483432f1cec767 | |||
5debea8ebb4e5fe7d6f6e5db15f15587ac4d4d4a1de7191e0c1ca6664abcc413 | 5debea8ebb4e5fe7d6f6e5db15f15587ac4d4d4a1de7191e0c1ca6664abcc413 | |||
O: ae81e7de df20a497 e10c304a 765c1767 a42d6e06 029758d2 d7e8ef7c c4c41179 | O: ae81e7de df20a497 e10c304a 765c1767 a42d6e06 029758d2 d7e8ef7c | |||
c4c41179 | ||||
I: a836e6c9a9ca9f1e8d486273ad56a78c70cf18f0ce10abb1c7172ddd605d7fd2 | I: a836e6c9a9ca9f1e8d486273ad56a78c70cf18f0ce10abb1c7172ddd605d7fd2 | |||
979854f47ae1ccf204a33102095b4200e5befc0465accc263175485f0e17ea5c | 979854f47ae1ccf204a33102095b4200e5befc0465accc263175485f0e17ea5c | |||
O: e2705652 ff9f5e44 d3e841bf 1c251cf7 dddb77d1 40870d1a b2ed64f1 a9ce8628 | O: e2705652 ff9f5e44 d3e841bf 1c251cf7 dddb77d1 40870d1a b2ed64f1 | |||
a9ce8628 | ||||
I: 2cdc11eaeb95daf01189417cdddbf95952993aa9cb9c640eb5058d09702c7462 | I: 2cdc11eaeb95daf01189417cdddbf95952993aa9cb9c640eb5058d09702c7462 | |||
2c9965a697a3b345ec24ee56335b556e677b30e6f90ac77d781064f866a3c982 | 2c9965a697a3b345ec24ee56335b556e677b30e6f90ac77d781064f866a3c982 | |||
O: 80bd0726 2511cdde 4863f8a7 434cef69 6750681c b9510eea 557088f7 6d9e5065 | O: 80bd0726 2511cdde 4863f8a7 434cef69 6750681c b9510eea 557088f7 | |||
</artwork> | 6d9e5065 | |||
]]></sourcecode> | ||||
<t>The following element derivation function inputs all produce the same encoded | <t>The following element derivation function inputs all produce the same encoded | |||
output.</t> | output.</t> | |||
<artwork>I: edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff | <sourcecode type="test-vectors"><![CDATA[I: edffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffff | |||
1200000000000000000000000000000000000000000000000000000000000000 | 1200000000000000000000000000000000000000000000000000000000000000 | |||
I: edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f | I: edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f | |||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff | |||
I: 0000000000000000000000000000000000000000000000000000000000000080 | I: 0000000000000000000000000000000000000000000000000000000000000080 | |||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f | |||
I: 0000000000000000000000000000000000000000000000000000000000000000 | I: 0000000000000000000000000000000000000000000000000000000000000000 | |||
1200000000000000000000000000000000000000000000000000000000000080 | 1200000000000000000000000000000000000000000000000000000000000080 | |||
O: 30428279 1023b731 28d277bd cb5c7746 ef2eac08 dde9f298 3379cb8e 5ef0517f | O: 30428279 1023b731 28d277bd cb5c7746 ef2eac08 dde9f298 3379cb8e | |||
</artwork> | 5ef0517f | |||
]]></sourcecode> | ||||
</section> | </section> | |||
<section anchor="square-root-of-a-ratio-of-field-elements"><name>Square root of a ratio of field elements</name> | <section anchor="square-root-of-a-ratio-of-field-elements"><name>Square Root of a Ratio of Field Elements</name> | |||
<t>The following are inputs and outputs of <tt>SQRT_RATIO_M1(u, v)</tt> defined | <t>The following are inputs and outputs of <tt>SQRT_RATIO_M1(u, v)</tt> defined | |||
in <xref target="sqrtratio255"></xref>. The values are little-endian encodings o f field | in <xref target="sqrtratio255"></xref>. The values are little-endian encodings o f field | |||
elements.</t> | elements.</t> | |||
<artwork>u: 0000000000000000000000000000000000000000000000000000000000000000 | <sourcecode type="test-vectors"><![CDATA[u: 000000000000000000000000000000000000 0000000000000000000000000000 | |||
v: 0000000000000000000000000000000000000000000000000000000000000000 | v: 0000000000000000000000000000000000000000000000000000000000000000 | |||
was_square: TRUE | was_square: TRUE | |||
r: 0000000000000000000000000000000000000000000000000000000000000000 | r: 0000000000000000000000000000000000000000000000000000000000000000 | |||
u: 0000000000000000000000000000000000000000000000000000000000000000 | u: 0000000000000000000000000000000000000000000000000000000000000000 | |||
v: 0100000000000000000000000000000000000000000000000000000000000000 | v: 0100000000000000000000000000000000000000000000000000000000000000 | |||
was_square: TRUE | was_square: TRUE | |||
r: 0000000000000000000000000000000000000000000000000000000000000000 | r: 0000000000000000000000000000000000000000000000000000000000000000 | |||
u: 0100000000000000000000000000000000000000000000000000000000000000 | u: 0100000000000000000000000000000000000000000000000000000000000000 | |||
skipping to change at line 975 ¶ | skipping to change at line 1082 ¶ | |||
u: 0400000000000000000000000000000000000000000000000000000000000000 | u: 0400000000000000000000000000000000000000000000000000000000000000 | |||
v: 0100000000000000000000000000000000000000000000000000000000000000 | v: 0100000000000000000000000000000000000000000000000000000000000000 | |||
was_square: TRUE | was_square: TRUE | |||
r: 0200000000000000000000000000000000000000000000000000000000000000 | r: 0200000000000000000000000000000000000000000000000000000000000000 | |||
u: 0100000000000000000000000000000000000000000000000000000000000000 | u: 0100000000000000000000000000000000000000000000000000000000000000 | |||
v: 0400000000000000000000000000000000000000000000000000000000000000 | v: 0400000000000000000000000000000000000000000000000000000000000000 | |||
was_square: TRUE | was_square: TRUE | |||
r: f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f | r: f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f | |||
</artwork> | ]]></sourcecode> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="test-vectors-for-decaf448"><name>Test vectors for decaf448</nam e> | <section anchor="test-vectors-for-decaf448"><name>Test Vectors for decaf448</nam e> | |||
<t>This section contains test vectors for decaf448. The octets are | <t>This section contains test vectors for decaf448. The octets are | |||
hex encoded, and whitespace is inserted for readability.</t> | hex encoded, and whitespace is inserted for readability.</t> | |||
<section anchor="multiples-of-the-generator-1"><name>Multiples of the generator< /name> | <section anchor="multiples-of-the-generator-1"><name>Multiples of the Generator< /name> | |||
<t>The following are the encodings of the multiples 0 to 15 of the | <t>The following are the encodings of the multiples 0 to 15 of the | |||
canonical generator, represented as an array of elements. That is, | canonical generator, represented as an array of elements. That is, | |||
the first entry is the encoding of the identity element, and each | the first entry is the encoding of the identity element, and each | |||
successive entry is obtained by adding the generator to the previous entry.</t> | successive entry is obtained by adding the generator to the previous entry.</t> | |||
<artwork>B[ 0]: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | <sourcecode type="test-vectors"><![CDATA[B[ 0]: 00000000 00000000 00000000 00000 000 00000000 00000000 00000000 | |||
00000000 00000000 00000000 00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | |||
B[ 1]: 66666666 66666666 66666666 66666666 66666666 66666666 66666666 | B[ 1]: 66666666 66666666 66666666 66666666 66666666 66666666 66666666 | |||
33333333 33333333 33333333 33333333 33333333 33333333 33333333 | 33333333 33333333 33333333 33333333 33333333 33333333 33333333 | |||
B[ 2]: c898eb4f 87f97c56 4c6fd61f c7e49689 314a1f81 8ec85eeb 3bd5514a | B[ 2]: c898eb4f 87f97c56 4c6fd61f c7e49689 314a1f81 8ec85eeb 3bd5514a | |||
c816d387 78f69ef3 47a89fca 817e66de fdedce17 8c7cc709 b2116e75 | c816d387 78f69ef3 47a89fca 817e66de fdedce17 8c7cc709 b2116e75 | |||
B[ 3]: a0c09bf2 ba7208fd a0f4bfe3 d0f5b29a 54301230 6d43831b 5adc6fe7 | B[ 3]: a0c09bf2 ba7208fd a0f4bfe3 d0f5b29a 54301230 6d43831b 5adc6fe7 | |||
f8596fa3 08763db1 5468323b 11cf6e4a eb8c18fe 44678f44 545a69bc | f8596fa3 08763db1 5468323b 11cf6e4a eb8c18fe 44678f44 545a69bc | |||
B[ 4]: b46f1836 aa287c0a 5a5653f0 ec5ef9e9 03f436e2 1c1570c2 9ad9e5f5 | B[ 4]: b46f1836 aa287c0a 5a5653f0 ec5ef9e9 03f436e2 1c1570c2 9ad9e5f5 | |||
96da97ee af17150a e30bcb31 74d04bc2 d712c8c7 789d7cb4 fda138f4 | 96da97ee af17150a e30bcb31 74d04bc2 d712c8c7 789d7cb4 fda138f4 | |||
B[ 5]: 1c5bbecf 4741dfaa e79db72d face00ea aac502c2 060934b6 eaaeca6a | B[ 5]: 1c5bbecf 4741dfaa e79db72d face00ea aac502c2 060934b6 eaaeca6a | |||
skipping to change at line 1021 ¶ | skipping to change at line 1128 ¶ | |||
B[11]: be88bbb8 6c59c13d 8e9d09ab 98105f69 c2d1dd13 4dbcd3b0 863658f5 | B[11]: be88bbb8 6c59c13d 8e9d09ab 98105f69 c2d1dd13 4dbcd3b0 863658f5 | |||
3159db64 c0e139d1 80f3c89b 8296d0ae 324419c0 6fa87fc7 daaf34c1 | 3159db64 c0e139d1 80f3c89b 8296d0ae 324419c0 6fa87fc7 daaf34c1 | |||
B[12]: a456f936 9769e8f0 8902124a 0314c7a0 6537a06e 32411f4f 93415950 | B[12]: a456f936 9769e8f0 8902124a 0314c7a0 6537a06e 32411f4f 93415950 | |||
a17badfa 7442b621 7434a3a0 5ef45be5 f10bd7b2 ef8ea00c 431edec5 | a17badfa 7442b621 7434a3a0 5ef45be5 f10bd7b2 ef8ea00c 431edec5 | |||
B[13]: 186e452c 4466aa43 83b4c002 10d52e79 22dbf977 1e8b47e2 29a9b7b7 | B[13]: 186e452c 4466aa43 83b4c002 10d52e79 22dbf977 1e8b47e2 29a9b7b7 | |||
3c8d10fd 7ef0b6e4 1530f91f 24a3ed9a b71fa38b 98b2fe47 46d51d68 | 3c8d10fd 7ef0b6e4 1530f91f 24a3ed9a b71fa38b 98b2fe47 46d51d68 | |||
B[14]: 4ae7fdca e9453f19 5a8ead5c be1a7b96 99673b52 c40ab279 27464887 | B[14]: 4ae7fdca e9453f19 5a8ead5c be1a7b96 99673b52 c40ab279 27464887 | |||
be53237f 7f3a21b9 38d40d0e c9e15b1d 5130b13f fed81373 a53e2b43 | be53237f 7f3a21b9 38d40d0e c9e15b1d 5130b13f fed81373 a53e2b43 | |||
B[15]: 841981c3 bfeec3f6 0cfeca75 d9d8dc17 f46cf010 6f2422b5 9aec580a | B[15]: 841981c3 bfeec3f6 0cfeca75 d9d8dc17 f46cf010 6f2422b5 9aec580a | |||
58f34227 2e3a5e57 5a055ddb 051390c5 4c24c6ec b1e0aceb 075f6056 | 58f34227 2e3a5e57 5a055ddb 051390c5 4c24c6ec b1e0aceb 075f6056 | |||
</artwork> | ]]></sourcecode> | |||
</section> | </section> | |||
<section anchor="invalid448"><name>Invalid encodings</name> | <section anchor="invalid448"><name>Invalid Encodings</name> | |||
<t>These are examples of encodings that <bcp14>MUST</bcp14> be rejected accordin g to | <t>These are examples of encodings that <bcp14>MUST</bcp14> be rejected accordin g to | |||
<xref target="decoding448"></xref>.</t> | <xref target="decoding448"></xref>.</t> | |||
<artwork># Non-canonical field encodings. | <sourcecode type="test-vectors"><![CDATA[# Non-canonical field encodings. | |||
8e24f838 059ee9fe f1e20912 6defe53d cd74ef9b 6304601c 6966099e | 8e24f838 059ee9fe f1e20912 6defe53d cd74ef9b 6304601c 6966099e | |||
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | |||
86fcc721 2bd4a0b9 80928666 dc28c444 a605ef38 e09fb569 e28d4443 | 86fcc721 2bd4a0b9 80928666 dc28c444 a605ef38 e09fb569 e28d4443 | |||
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | |||
866d54bd 4c4ff41a 55d4eefd beca73cb d653c7bd 3135b383 708ec0bd | 866d54bd 4c4ff41a 55d4eefd beca73cb d653c7bd 3135b383 708ec0bd | |||
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff | |||
4a380ccd ab9c8636 4a89e77a 464d64f9 157538cf dfa686ad c0d5ece4 | 4a380ccd ab9c8636 4a89e77a 464d64f9 157538cf dfa686ad c0d5ece4 | |||
skipping to change at line 1093 ¶ | skipping to change at line 1200 ¶ | |||
4be7e3cb 6684fd1b cfe5071a 9a974ad2 49a4aaa8 ca812642 16c68574 | 4be7e3cb 6684fd1b cfe5071a 9a974ad2 49a4aaa8 ca812642 16c68574 | |||
2ed9ffe2 ded67a37 2b181ac5 24996402 c4297062 9db03f5e 8636cbaf | 2ed9ffe2 ded67a37 2b181ac5 24996402 c4297062 9db03f5e 8636cbaf | |||
6074b523 d154a7a8 c4472c4c 353ab88c d6fec7da 7780834c c5bd5242 | 6074b523 d154a7a8 c4472c4c 353ab88c d6fec7da 7780834c c5bd5242 | |||
f063769e 4241e76d 815800e4 933a3a14 4327a30e c40758ad 3723a788 | f063769e 4241e76d 815800e4 933a3a14 4327a30e c40758ad 3723a788 | |||
388399f7 b3f5d45b 6351eb8e ddefda7d 5bff4ee9 20d338a8 b89d8b63 | 388399f7 b3f5d45b 6351eb8e ddefda7d 5bff4ee9 20d338a8 b89d8b63 | |||
5a0104f1 f55d152c eb68bc13 81824998 91d90ee8 f09b4003 8ccc1e07 | 5a0104f1 f55d152c eb68bc13 81824998 91d90ee8 f09b4003 8ccc1e07 | |||
cb621fd4 62f781d0 45732a4f 0bda73f0 b2acf943 55424ff0 388d4b9c | cb621fd4 62f781d0 45732a4f 0bda73f0 b2acf943 55424ff0 388d4b9c | |||
</artwork> | ]]></sourcecode> | |||
</section> | </section> | |||
<section anchor="group-elements-from-uniform-byte-strings"><name>Group elements from uniform byte strings</name> | <section anchor="group-elements-from-uniform-byte-strings-1"><name>Group Element s from Uniform Byte Strings</name> | |||
<t>The following pairs are inputs to the element derivation function of | <t>The following pairs are inputs to the element derivation function of | |||
<xref target="from_bytes_uniform448"></xref>, and their encoded outputs.</t> | <xref target="from_bytes_uniform448"></xref> and their encoded outputs.</t> | |||
<artwork>I: cbb8c991fd2f0b7e1913462d6463e4fd2ce4ccdd28274dc2ca1f4165 | <sourcecode type="test-vectors"><![CDATA[I: cbb8c991fd2f0b7e1913462d6463e4fd2ce4 ccdd28274dc2ca1f4165 | |||
d5ee6cdccea57be3416e166fd06718a31af45a2f8e987e301be59ae6 | d5ee6cdccea57be3416e166fd06718a31af45a2f8e987e301be59ae6 | |||
673e963001dbbda80df47014a21a26d6c7eb4ebe0312aa6fffb8d1b2 | 673e963001dbbda80df47014a21a26d6c7eb4ebe0312aa6fffb8d1b2 | |||
6bc62ca40ed51f8057a635a02c2b8c83f48fa6a2d70f58a1185902c0 | 6bc62ca40ed51f8057a635a02c2b8c83f48fa6a2d70f58a1185902c0 | |||
O: 0c709c96 07dbb01c 94513358 745b7c23 953d03b3 3e39c723 4e268d1d | O: 0c709c96 07dbb01c 94513358 745b7c23 953d03b3 3e39c723 4e268d1d | |||
6e24f340 14ccbc22 16b965dd 231d5327 e591dc3c 0e8844cc fd568848 | 6e24f340 14ccbc22 16b965dd 231d5327 e591dc3c 0e8844cc fd568848 | |||
I: b6d8da654b13c3101d6634a231569e6b85961c3f4b460a08ac4a5857 | I: b6d8da654b13c3101d6634a231569e6b85961c3f4b460a08ac4a5857 | |||
069576b64428676584baa45b97701be6d0b0ba18ac28d443403b4569 | 069576b64428676584baa45b97701be6d0b0ba18ac28d443403b4569 | |||
9ea0fbd1164f5893d39ad8f29e48e399aec5902508ea95e33bc1e9e4 | 9ea0fbd1164f5893d39ad8f29e48e399aec5902508ea95e33bc1e9e4 | |||
620489d684eb5c26bc1ad1e09aba61fabc2cdfee0b6b6862ffc8e55a | 620489d684eb5c26bc1ad1e09aba61fabc2cdfee0b6b6862ffc8e55a | |||
skipping to change at line 1148 ¶ | skipping to change at line 1255 ¶ | |||
8a84e919fbd28e02a0f9c49b48dc689eb5d5d922dc01469968ee81b5 | 8a84e919fbd28e02a0f9c49b48dc689eb5d5d922dc01469968ee81b5 | |||
O: 7e79b00e 8e0a76a6 7c0040f6 2713b8b8 c6d6f05e 9c6d0259 2e8a22ea | O: 7e79b00e 8e0a76a6 7c0040f6 2713b8b8 c6d6f05e 9c6d0259 2e8a22ea | |||
896f5dea cc7c7df5 ed42beae 6fedb900 0285b482 aa504e27 9fd49c32 | 896f5dea cc7c7df5 ed42beae 6fedb900 0285b482 aa504e27 9fd49c32 | |||
I: e9fb440282e07145f1f7f5ecf3c273212cd3d26b836b41b02f108431 | I: e9fb440282e07145f1f7f5ecf3c273212cd3d26b836b41b02f108431 | |||
488e5e84bd15f2418b3d92a3380dd66a374645c2a995976a015632d3 | 488e5e84bd15f2418b3d92a3380dd66a374645c2a995976a015632d3 | |||
6a6c2189f202fc766e1c82f50ad9189be190a1f0e8f9b9e69c9c18cc | 6a6c2189f202fc766e1c82f50ad9189be190a1f0e8f9b9e69c9c18cc | |||
98fdd885608f68bf0fdedd7b894081a63f70016a8abf04953affbefa | 98fdd885608f68bf0fdedd7b894081a63f70016a8abf04953affbefa | |||
O: 20b171cb 16be977f 15e013b9 752cf86c 54c631c4 fc8cbf7c 03c4d3ac | O: 20b171cb 16be977f 15e013b9 752cf86c 54c631c4 fc8cbf7c 03c4d3ac | |||
9b8e8640 e7b0e930 0b987fe0 ab504466 9314f6ed 1650ae03 7db853f1 | 9b8e8640 e7b0e930 0b987fe0 ab504466 9314f6ed 1650ae03 7db853f1 | |||
</artwork> | ]]></sourcecode> | |||
</section> | ||||
</section> | </section> | |||
<section anchor="acknowledgements" numbered="false"><name>Acknowledgements</name | ||||
> | ||||
<t>The authors would like to thank <contact fullname="Daira Emma Hopwood"><organ | ||||
ization></organization><address><postal><street></street> | ||||
</postal></address></contact>, <contact fullname="Riad S. Wahby"><organization>< | ||||
/organization><address><postal><street></street> | ||||
</postal></address></contact>, <contact fullname="Christopher Wood"><organizatio | ||||
n></organization><address><postal><street></street> | ||||
</postal></address></contact>, | ||||
and <contact fullname="Thomas Pornin"><organization></organization><address><pos | ||||
tal><street></street> | ||||
</postal></address></contact> for their comments on the document.</t> | ||||
</section> | </section> | |||
</back> | </back> | |||
</rfc> | </rfc> | |||
End of changes. 166 change blocks. | ||||
316 lines changed or deleted | 446 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. |