diff --git a/spec/specification.md b/spec/specification.md index 658ae7c..36206cd 100644 --- a/spec/specification.md +++ b/spec/specification.md @@ -1,4 +1,4 @@ -# Ring VRF +# Bandersnatch VRFs ## VRF @@ -42,7 +42,6 @@ $$ append(t, cofactor * VRFpreout) $$ $$ VRFoutput \leftarrow t.challenge("") $$ - ### VRF Key #### Public key \ @@ -52,7 +51,61 @@ Public key is represented in Affine form and is serialized using Arkwork compres format. -### Pedersen VRF +## IETF VRF + +Refer to [RFC-9381](https://www.rfc-editor.org/rfc/rfc9381) for the details. + +### Bandersnatch Cipher Suite Configuration + +Configuration follows the RFC-9381 suite specification guidelines. + +* The EC group G is the Bandersnatch elliptic curve, in Twisted Edwards form, + with the finite field and curve parameters as specified in the [neuromancer](https://neuromancer.sk/std/bls/Bandersnatch) + standard curves database. For this group, `fLen` = `qLen` = 32 and `cofactor` = 4. + +* The prime subgroup generator `g` is constructed following Zcash's guidelines: + *"The generators of G1 and G2 are computed by finding the lexicographically + smallest valid x-coordinate, and its lexicographically smallest y-coordinate + and scaling it by the cofactor such that the result is not the point at infinity."* + + - g.x = `0x29c132cc2c0b34c5743711777bbe42f32b79c022ad998465e1e71866a252ae18` + - g.y = `0x2a6c669eda123e0f157d8b50badcd586358cad81eee464605e3167b6cc974166` + +* The public key generation primitive is `PK = SK · g`, with `SK` the secret + key scalar and `g` the group generator. In this ciphersuite, the secret + scalar `x` is equal to the secret key `SK`. + +* `suite_string` = 0x33. + +* `cLen` = 32. + +* `encode_to_curve_salt` = `PK_string`. + +* The `ECVRF_nonce_generation` function is as specified in Section 5.4.2.1 of RFC-9381. + +* The `int_to_string` function encodes into the 32 bytes little endian representation. + +* The `string_to_int` function decodes from the 32 bytes little endian representation. + +* The point_to_string function converts a point on E to an octet + string using compressed form. The Y coordinate is encoded using + `int_to_string` function and the most significant bit of the last + octet is used to keep track of the X's sign. This implies that + the point is encoded on 32 bytes. + +* The string_to_point function tries to decompress the point encoded + according to `point_to_string` procedure. This function MUST outputs + "INVALID" if the octet string does not decode to a point on the curve E. + +* The hash function Hash is SHA-512 as specified in + [RFC6234](https://www.rfc-editor.org/rfc/rfc6234), with hLen = 64. + +* The ECVRF_encode_to_curve function is as specified in + Section 5.4.1.2, with `h2c_suite_ID_string` = `"BANDERSNATCH_XMD:BLAKE2b_ELL2_RO_"`. + The suite is defined in Section 8.5 of [RFC9380](https://datatracker.ietf.org/doc/rfc9380/). + +## Pedersen VRF + Pedersen VRF resembles EC VRF but replaces the public key by a Pedersen commitment to the secret key, which makes the Pedersen VRF useful in anonymized ring VRFs, or perhaps group VRFs. @@ -129,9 +182,7 @@ $z2 \leftarrow ClearCofactor(z1)$ --- -## Bandersnatch VRF - -### VRF input +## VRF input Procedure to map arbitrary user input to a point follows the `hash_to_curve` procedure described by RFC9380. @@ -140,7 +191,7 @@ procedure described by RFC9380. See [ArkTranscript](TODO) for details. -#### From transcript to point +### From transcript to point You need to call challenge and add b"vrf-input" to it. getting random byte (some hash?) then hash to curve it. @@ -163,114 +214,3 @@ followed by the serialization of the length of each objects, as a 32-bit unsigne Shake128(bytes) The length of each item should be less than 2^31. - -## Objects Serialization Encoding - -### Unsigned Integers - -Unsigned integers are encoded in big-endian. - -This applies to both fixed or arbitrary width unsigned integers. - -TODO: -- ARK serializes integers in LE :-/ -- Check Zcash serialization format (IIRC BE) - -### EC Points - -Elliptic curve points are serialized in compressed form as specified by TODO. - -TODO isn't there any standard like https://www.secg.org/sec1-v2.pdf ? -There the standard serializes in BE as well. - -TODO maybe we must convert to BE our serialized points/scalars? - - -## OBSOLETE (TODO: REMOVE THIS PARAGRAPH) - -Write unlabeled domain separator into the hasher state. - -``` - write_separator(hasher, data) - - Inputs: - - hasher: shake128 hasher state - - data: user data - - Steps: - 1. bytes = big_endian_bytes(length(data)) - 2. write_bytes(hasher, bytes) -``` - -Update the hasher state with user provided data with separator. - -``` - update(hasher, data) - - Inputs: - - hasher: shake128 hasher state - - data: user data - - Steps: - 1. write_bytes(hasher, data) - 2. write_separator(hasher, data) -``` - -### Challenge - -Creates a challenge reader - -``` - challenge(hasher, label) - - Inputs: - - label: user provided domain separator (octet-string) - Outputs: - - Shake128 hash reader - - Steps: - 1. update(hasher, label) - 2. write_bytes(hasher, b"challenge") - 3. reader = get_reader(hasher) - 4. separate(hasher, b"challenge") - 5. return reader -``` - -### Forking - -Forks transcript to prepare a witness reader - -``` - fork(hasher, label) - - Inputs: - - hasher: shake128 state - - label: user provided label (octets) - Output: - - forked hasher state - - Steps: - 1. hasher_clone = clone(hasher) - 2. update(hasher_clone, label) - 3. return hasher_clone -``` - -### Witness - -Create a witness reader from a forked transcript - -``` - witness(hasher, rng) - - Inputs: - - hasher: shake128 state - - rng: random number generator - Output - - Shake128 hasher reader - - Steps: - 1. rand = read_bytes(rng, 32) - 2. write_bytes(hasher, rand) - 3. reader = get_reader(hasher) - 4. return reader -``` diff --git a/spec/specification.pdf b/spec/specification.pdf new file mode 100644 index 0000000..7afd10a Binary files /dev/null and b/spec/specification.pdf differ diff --git a/spec/specification.tex b/spec/specification.tex new file mode 100644 index 0000000..6bd5415 --- /dev/null +++ b/spec/specification.tex @@ -0,0 +1,361 @@ +% Options for packages loaded elsewhere +\PassOptionsToPackage{unicode}{hyperref} +\PassOptionsToPackage{hyphens}{url} +% +\documentclass[ +]{article} +\usepackage{amsmath,amssymb} +\usepackage{lmodern} +\usepackage{iftex} +\ifPDFTeX + \usepackage[T1]{fontenc} + \usepackage[utf8]{inputenc} + \usepackage{textcomp} % provide euro and other symbols +\else % if luatex or xetex + \usepackage{unicode-math} + \defaultfontfeatures{Scale=MatchLowercase} + \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} +\fi +% Use upquote if available, for straight quotes in verbatim environments +\IfFileExists{upquote.sty}{\usepackage{upquote}}{} +\IfFileExists{microtype.sty}{% use microtype if available + \usepackage[]{microtype} + \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts +}{} +\makeatletter +\@ifundefined{KOMAClassName}{% if non-KOMA class + \IfFileExists{parskip.sty}{% + \usepackage{parskip} + }{% else + \setlength{\parindent}{0pt} + \setlength{\parskip}{6pt plus 2pt minus 1pt}} +}{% if KOMA class + \KOMAoptions{parskip=half}} +\makeatother +\usepackage{xcolor} +\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available +\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} +\hypersetup{ + hidelinks, + pdfcreator={LaTeX via pandoc}} +\urlstyle{same} % disable monospaced font for URLs +\setlength{\emergencystretch}{3em} % prevent overfull lines +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} +\setcounter{secnumdepth}{-\maxdimen} % remove section numbering +\ifLuaTeX + \usepackage{selnolig} % disable illegal ligatures +\fi + +\author{} +\date{} + +\begin{document} + +\hypertarget{bandersnatch-vrfs}{% +\section{Bandersnatch VRFs}\label{bandersnatch-vrfs}} + +\hypertarget{vrf}{% +\subsection{VRF}\label{vrf}} + +\textbf{Definition}: A \emph{verifiable random function with auxiliary +data (VRF-AD)} can be described with three functions: + +\begin{itemize} +\tightlist +\item + \(VRF.KeyGen: () \mapsto (pk,sk)\) where \(pk\) is a public key and + \(sk\) is its corresponding secret key. +\item + \(VRF.Sign : (sk,msg,aux) \mapsto \sigma\) takes a secret key \(sk\), + an input \(msg\), and auxiliary data \(aux\), and then returns a VRF + signature \(\sigma\). +\item + \(VRF.Eval : (sk, msg) \mapsto Out\) takes a secret key \(sk\) and an + input \(msg\), and then returns a VRF output \(Out\). +\item + \(VRF.Verify: (pk,msg,aux,\sigma)\mapsto (Out|prep)\) for a public key + pk, an input msg, and auxiliary data aux, and then returns either an + output \(Out\) or else failure \(perp\). +\end{itemize} + +\textbf{Definition}: For an elliptic curve \(E\) defined over finite +field \(F\) with large prime subgroup \(G\) generated by point \(g\), we +call a VRF, EC-VRF is VRF-AD where \(pk = sk.g\) and \(VRF.Sign\) is an +elliptic curve signature scheme. + +All VRFs described in this specification are EC-VRF. For input \(msg\) +and \(aux\) auxilary data first we compute the \(VRFInput\) which is a +point on elliptic curve \(E\) as follows: +\[ t \leftarrow Transcript(msg) \]\\ +\[ VRFiput := H2C(challange(t, "vrf-input") \] + +where - \(transcript\) function is described in +{[}{[}ark-transcript{]}{]} section.\\ +- \(H2C: B \rightarrow G\) is a hash to curve function correspond to +curve \(E\) specified in Section {[}{[}hash-to-curve{]}{]} for the +specific choice of \(E\) + +\hypertarget{vrf-input}{% +\subsubsection{VRF Input}\label{vrf-input}} + +The VRF input ultimately is a point on the elliptic curve as out put of +hash of the transcript using arkworks chosen hash for the given curve. + +VRF Input point should always be created locally, either as a +hash-to-cuve output of the transcripto or ocasionally some base point. +It should never be sent over the wire nor deserialized???Do you mean +serialized? + +\hypertarget{vrf-preoutput-and-output}{% +\subsubsection{VRF Preoutput and +Output}\label{vrf-preoutput-and-output}} + +\textbf{Definition}: \emph{VRF pre-output} is defined to be a point in +\(E\) in serialized affine representation. + +\textbf{Definition}: \emph{VRF InOut} is defined as a pair as follows: +\[(VRF Input, VRF Preoutput)\] \textbf{Definition}: \emph{VRF output} is +generated using VRF preoutput: \[ t \leftarrow Transcript(Domain) \] +\[ append(t, "VrfOutput") \] \[ append(t, cofactor * VRFpreout) \] +\[ VRFoutput \leftarrow t.challenge("") \] + +\hypertarget{vrf-key}{% +\subsubsection{VRF Key}\label{vrf-key}} + +\hypertarget{public-key}{% +\paragraph{\texorpdfstring{Public key\\ +}{Public key }}\label{public-key}} + +\hfill\break +A Public key of a VRF is a point on an Elliptic Curve \(E\).\\ +Public key is represented in Affine form and is serialized using Arkwork +compressed serialized format. + +\hypertarget{ietf-vrf}{% +\subsection{IETF VRF}\label{ietf-vrf}} + +Refer to \href{https://www.rfc-editor.org/rfc/rfc9381}{RFC-9381} for the +details. + +\hypertarget{bandersnatch-cipher-suite-configuration}{% +\subsubsection{Bandersnatch Cipher Suite +Configuration}\label{bandersnatch-cipher-suite-configuration}} + +Configuration follows the RFC-9381 suite specification guidelines. + +\begin{itemize} +\item + The EC group G is the Bandersnatch elliptic curve, in Twisted Edwards + form, with the finite field and curve parameters as specified in the + \href{https://neuromancer.sk/std/bls/Bandersnatch}{neuromancer} + standard curves database. For this group, \texttt{fLen} = + \texttt{qLen} = 32 and \texttt{cofactor} = 4. +\item + The prime subgroup generator \texttt{g} is constructed following + Zcash's guidelines: \emph{``The generators of G1 and G2 are computed + by finding the lexicographically smallest valid x-coordinate, and its + lexicographically smallest y-coordinate and scaling it by the cofactor + such that the result is not the point at infinity.''} + + \begin{itemize} + \tightlist + \item + g.x = + \texttt{0x29c132cc2c0b34c5743711777bbe42f32b79c022ad998465e1e71866a252ae18} + \item + g.y = + \texttt{0x2a6c669eda123e0f157d8b50badcd586358cad81eee464605e3167b6cc974166} + \end{itemize} +\item + The public key generation primitive is \texttt{PK\ =\ SK\ ·\ g}, with + \texttt{SK} the secret key scalar and \texttt{g} the group generator. + In this ciphersuite, the secret scalar \texttt{x} is equal to the + secret key \texttt{SK}. +\item + \texttt{suite\_string} = 0x33. +\item + \texttt{cLen} = 32. +\item + \texttt{encode\_to\_curve\_salt} = \texttt{PK\_string}. +\item + The \texttt{ECVRF\_nonce\_generation} function is as specified in + Section 5.4.2.1 of RFC-9381. +\item + The \texttt{int\_to\_string} function encodes into the 32 bytes little + endian representation. +\item + The \texttt{string\_to\_int} function decodes from the 32 bytes little + endian representation. +\item + The point\_to\_string function converts a point on E to an octet + string using compressed form. The Y coordinate is encoded using + \texttt{int\_to\_string} function and the most significant bit of the + last octet is used to keep track of the X's sign. This implies that + the point is encoded on 32 bytes. +\item + The string\_to\_point function tries to decompress the point encoded + according to \texttt{point\_to\_string} procedure. This function MUST + outputs ``INVALID'' if the octet string does not decode to a point on + the curve E. +\item + The hash function Hash is SHA-512 as specified in + \href{https://www.rfc-editor.org/rfc/rfc6234}{RFC6234}, with hLen = + 64. +\item + The ECVRF\_encode\_to\_curve function is as specified in Section + 5.4.1.2, with \texttt{h2c\_suite\_ID\_string} = + \texttt{"BANDERSNATCH\_XMD:BLAKE2b\_ELL2\_RO\_"}. The suite is defined + in Section 8.5 of + \href{https://datatracker.ietf.org/doc/rfc9380/}{RFC9380}. +\end{itemize} + +\hypertarget{pedersen-vrf}{% +\subsection{Pedersen VRF}\label{pedersen-vrf}} + +Pedersen VRF resembles EC VRF but replaces the public key by a Pedersen +commitment to the secret key, which makes the Pedersen VRF useful in +anonymized ring VRFs, or perhaps group VRFs. + +\hypertarget{pedersen-vrf-1}{% +\subsection{Pedersen VRF}\label{pedersen-vrf-1}} + +Strictly speaking Pederson VRF is not a VRF. Instead, it proves that the +output has been generated with a secret key associated with a blinded +public (instead of public key). The blinded public key is a +cryptographic commitement to the public key. And it could unblinded to +prove that the output of the VRF is corresponds to the public key of the +signer. + +\hypertarget{setup}{% +\subsubsection{Setup}\label{setup}} + +PedersenVRF is initiated for prime subgroup \(G < E\) of an elliptic +curve E with \(K, B \in G\) are defined to be \emph{key base} and +\emph{blinding base} respectively. + +\hypertarget{pedersenvrf.sign}{% +\subsubsection{PedersenVRF.Sign}\label{pedersenvrf.sign}} + +\textbf{Inputs}:\\ +- Transcript \(t\) of \texttt{ArkTranscript} type\\ +- \(input\): \(VRFInput \in G\). - \(sb\): Blinding coefficient +\(\in F\)\\ +- \(sk\): A VRF secret key.\\ +- \(pk\): VRF verification key corresponds to \(sk\).\\ +\textbf{Output}:\\ +- A Quintuple \((compk, KBrand, PORand, ks, bs)2\) corresponding to +PedersenVRF signature + +\begin{center}\rule{0.5\linewidth}{0.5pt}\end{center} + +\begin{enumerate} +\def\labelenumi{\arabic{enumi}.} +\tightlist +\item + \(AddLabel(t, "PedersenVRF")\) +\item + \(compk = sk*G + sb*B\) +\item + AppendToTranscript(``KeyCommitment'') +\item + AppendToTranscript(t, compk) +\item + \(krand \leftarrow RandomElement(F)\) +\item + \(brand \leftarrow RandomElement(F)\) +\item + \(KBrand \leftarrow krand * G + brand * B\) +\item + \(POrand \leftarrow krand * input\) +\item + \(AppendToTranscript(t, "Pedersen R")\) +\item + \(AppendToTranscript(t, "PedersenVrfChallenge")\) +\item + \(c \rightarrow GetChallengeFromTranscript(t)\) +\item + \(ks \rightarrow krand + sk * c\) +\item + \(bs \rightarrow brand + c * sb\) +\item + \textbf{return} \((compk, KBrand, PORand, ks, bs)\) +\end{enumerate} + +\hypertarget{pedersenvrf.verify}{% +\subsubsection{PedersenVRF.Verify}\label{pedersenvrf.verify}} + +\textbf{Inputs}:\\ +- \(t\): Transcript of \texttt{ArkTranscript} type\\ +- \(input\): \(VRFInput \in G\).\\ +- \(preout\): \(VRFPreOutput \in G\).\\ +- \((compk, KBrand, PORand, ks, bs)\) the quintuple results of +PeredersonVRF.Sign\\ +\textbf{Output}:\\ +- True if Pedersen VRF signature verifys False otherwise. + +\begin{center}\rule{0.5\linewidth}{0.5pt}\end{center} + +Append\((t, "PedersenVRF")\)\\ +Append\((t, ""KeyCommitment")\)\\ +Append\((t, compk)\)\\ +\(z1 \leftarrow POrand + c \times PreOut - In \times ks\) +Append\((t, "Pedersen R")\)\\ +Append\((t, KBrand || PORand)\)\\ +\(c \leftarrow Challenge(t, "PedersenVrfChallenge")\)\\ +\(z1 \leftarrow POrand + c \times preoutput - input \times ks\)\\ +\(z1 \leftarrow ClearCofactor(z1)\)\\ +\textbf{if} \(z1 \neq O\) \textbf{then} \textbf{return} False\\ +\(z2 \leftarrow KBrand + c \times compk - krand \times K - brand \times B\)\\ +\(z2 \leftarrow ClearCofactor(z1)\)\\ +\textbf{if} \(z2 \neq O\) \textbf{then} \textbf{return} False +\textbf{else} \textbf{return} True + +\begin{center}\rule{0.5\linewidth}{0.5pt}\end{center} + +\hypertarget{vrf-input-1}{% +\subsection{VRF input}\label{vrf-input-1}} + +Procedure to map arbitrary user input to a point follows the +\texttt{hash\_to\_curve} procedure described by RFC9380. + +\begin{verbatim} +Suite_ID: "bandersnatch_XMD:SHA-512_ELL2_RO_" +\end{verbatim} + +See \href{TODO}{ArkTranscript} for details. + +\hypertarget{from-transcript-to-point}{% +\subsubsection{From transcript to +point}\label{from-transcript-to-point}} + +You need to call challenge and add b''vrf-input'' to it. getting random +byte (some hash?) then hash to curve it. + +\hypertarget{transcript}{% +\subsection{Transcript}\label{transcript}} + +A Shake-128 based transcript construction which implements the +Fiat-Shamir transform procedure. + +We do basic domain separation using postfix writes of the lengths of +written data (as opposed to the prefix writes by +\href{https://merlin.cool}{Merlin} \texttt{TupleHash} from +\href{https://csrc.nist.gov/pubs/sp/800/185/final}{SP 800-185}). + +\begin{verbatim} +H(item_1, item_2, ..., item_n) +\end{verbatim} + +Represents the application of shake-128 to the concatenation of the +serialization of each item followed by the serialization of the length +of each objects, as a 32-bit unsigned integer. + +\begin{verbatim} +bytes = encode(item_1) || encode(length(item_1)) || .. || encode(item_n) || encode(length(item_n)) +Shake128(bytes) +\end{verbatim} + +The length of each item should be less than 2\^{}31. + +\end{document} diff --git a/specification_template.md b/specification_template.md index 19640ee..4f4af1f 100644 --- a/specification_template.md +++ b/specification_template.md @@ -1,24 +1,75 @@ -# Ring VRF +# Bandersnatch VRFs ## VRF {sections.vrf} - ### VRF Key {sections.vrf-keys} -### Pedersen VRF +## IETF VRF + +Refer to [RFC-9381](https://www.rfc-editor.org/rfc/rfc9381) for the details. + +### Bandersnatch Cipher Suite Configuration + +Configuration follows the RFC-9381 suite specification guidelines. + +* The EC group G is the Bandersnatch elliptic curve, in Twisted Edwards form, + with the finite field and curve parameters as specified in the [neuromancer](https://neuromancer.sk/std/bls/Bandersnatch) + standard curves database. For this group, `fLen` = `qLen` = 32 and `cofactor` = 4. + +* The prime subgroup generator `g` is constructed following Zcash's guidelines: + *"The generators of G1 and G2 are computed by finding the lexicographically + smallest valid x-coordinate, and its lexicographically smallest y-coordinate + and scaling it by the cofactor such that the result is not the point at infinity."* + + - g.x = `0x29c132cc2c0b34c5743711777bbe42f32b79c022ad998465e1e71866a252ae18` + - g.y = `0x2a6c669eda123e0f157d8b50badcd586358cad81eee464605e3167b6cc974166` + +* The public key generation primitive is `PK = SK · g`, with `SK` the secret + key scalar and `g` the group generator. In this ciphersuite, the secret + scalar `x` is equal to the secret key `SK`. + +* `suite_string` = 0x33. + +* `cLen` = 32. + +* `encode_to_curve_salt` = `PK_string`. + +* The `ECVRF_nonce_generation` function is as specified in Section 5.4.2.1 of RFC-9381. + +* The `int_to_string` function encodes into the 32 bytes little endian representation. + +* The `string_to_int` function decodes from the 32 bytes little endian representation. + +* The point_to_string function converts a point on E to an octet + string using compressed form. The Y coordinate is encoded using + `int_to_string` function and the most significant bit of the last + octet is used to keep track of the X's sign. This implies that + the point is encoded on 32 bytes. + +* The string_to_point function tries to decompress the point encoded + according to `point_to_string` procedure. This function MUST outputs + "INVALID" if the octet string does not decode to a point on the curve E. + +* The hash function Hash is SHA-512 as specified in + [RFC6234](https://www.rfc-editor.org/rfc/rfc6234), with hLen = 64. + +* The ECVRF_encode_to_curve function is as specified in + Section 5.4.1.2, with `h2c_suite_ID_string` = `"BANDERSNATCH_XMD:BLAKE2b_ELL2_RO_"`. + The suite is defined in Section 8.5 of [RFC9380](https://datatracker.ietf.org/doc/rfc9380/). + +## Pedersen VRF + Pedersen VRF resembles EC VRF but replaces the public key by a Pedersen commitment to the secret key, which makes the Pedersen VRF useful in anonymized ring VRFs, or perhaps group VRFs. {sections.pedersen-vrf} -## Bandersnatch VRF - -### VRF input +## VRF input Procedure to map arbitrary user input to a point follows the `hash_to_curve` procedure described by RFC9380. @@ -27,7 +78,7 @@ procedure described by RFC9380. See [ArkTranscript](TODO) for details. -#### From transcript to point +### From transcript to point You need to call challenge and add b"vrf-input" to it. getting random byte (some hash?) then hash to curve it. @@ -50,114 +101,3 @@ followed by the serialization of the length of each objects, as a 32-bit unsigne Shake128(bytes) The length of each item should be less than 2^31. - -## Objects Serialization Encoding - -### Unsigned Integers - -Unsigned integers are encoded in big-endian. - -This applies to both fixed or arbitrary width unsigned integers. - -TODO: -- ARK serializes integers in LE :-/ -- Check Zcash serialization format (IIRC BE) - -### EC Points - -Elliptic curve points are serialized in compressed form as specified by TODO. - -TODO isn't there any standard like https://www.secg.org/sec1-v2.pdf ? -There the standard serializes in BE as well. - -TODO maybe we must convert to BE our serialized points/scalars? - - -## OBSOLETE (TODO: REMOVE THIS PARAGRAPH) - -Write unlabeled domain separator into the hasher state. - -``` - write_separator(hasher, data) - - Inputs: - - hasher: shake128 hasher state - - data: user data - - Steps: - 1. bytes = big_endian_bytes(length(data)) - 2. write_bytes(hasher, bytes) -``` - -Update the hasher state with user provided data with separator. - -``` - update(hasher, data) - - Inputs: - - hasher: shake128 hasher state - - data: user data - - Steps: - 1. write_bytes(hasher, data) - 2. write_separator(hasher, data) -``` - -### Challenge - -Creates a challenge reader - -``` - challenge(hasher, label) - - Inputs: - - label: user provided domain separator (octet-string) - Outputs: - - Shake128 hash reader - - Steps: - 1. update(hasher, label) - 2. write_bytes(hasher, b"challenge") - 3. reader = get_reader(hasher) - 4. separate(hasher, b"challenge") - 5. return reader -``` - -### Forking - -Forks transcript to prepare a witness reader - -``` - fork(hasher, label) - - Inputs: - - hasher: shake128 state - - label: user provided label (octets) - Output: - - forked hasher state - - Steps: - 1. hasher_clone = clone(hasher) - 2. update(hasher_clone, label) - 3. return hasher_clone -``` - -### Witness - -Create a witness reader from a forked transcript - -``` - witness(hasher, rng) - - Inputs: - - hasher: shake128 state - - rng: random number generator - Output - - Shake128 hasher reader - - Steps: - 1. rand = read_bytes(rng, 32) - 2. write_bytes(hasher, rand) - 3. reader = get_reader(hasher) - 4. return reader -```