<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
]>
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<?rfc strict="no"?>
<?rfc rfcedstyle="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>

<rfc category="std" docName="draft-goldbe-vrf-00" ipr="trust200902">
    <front>
        <title abbrev="VRF">Verifiable Random Functions (VRFs)</title>

        <author fullname="Sharon Goldberg" initials="S." surname="Goldberg">
            <organization>Boston University</organization>
            <address>
                <postal>
                    <street>111 Cummington St, MCS135</street>
                    <city>Boston</city>
                    <region>MA</region>
                    <code>02215</code>
                    <country>USA</country>
                </postal>
                <email>goldbe@cs.bu.edu</email>
            </address>
        </author>

        <author fullname="Dimitrios Papadopoulos" initials="D." surname="Papadopoulos">
            <organization>University of Maryland</organization>
            <address>
                <postal>
                    <street>8223 Paint Branch Dr</street>
                    <city>College Park</city>
                    <region>MD</region>
                    <code>20740</code>
                    <country>USA</country>
                </postal>
                <email>dipapado@bu.edu</email>
            </address>
        </author>

        <author fullname="Jan Vcelak" initials="J." surname="Vcelak">
            <organization>NS1</organization>
            <address>
                <postal>
                    <street>16 Beaver St</street>
                    <city>New York</city>
                    <region>NY</region>
                    <code>10004</code>
                    <country>USA</country>
                </postal>
                <email>jvcelak@ns1.com</email>
            </address>
        </author>

        <date year="2017" />

        <!-- <workgroup></workgroup> -->

        <keyword>public key cryptography</keyword>
        <keyword>hashing</keyword>
        <keyword>authenticated denial</keyword>
        
    <abstract>

       <t>
        A Verifiable Random Function (VRF) is the public-key version of a
        keyed cryptographic hash. Only the holder of the private key
        can compute the hash, but anyone with public key
        can verify the correctness of the hash.    
        VRFs are useful for preventing enumeration of hash-based data structures.
        This document specifies several VRF constructions that are secure in
        the cryptographic random oracle model. One  VRF uses RSA and the other
        VRF uses Eliptic Curves (EC). 
        </t>

    </abstract>

</front>

<middle>

    <section title="Introduction" anchor="intro">

        <section title="Rationale">

    <t>
   A Verifiable Random Function
   (VRF) <xref target="MRV99"></xref> is the public-key version of a
   keyed cryptographic hash. Only the holder of the private VRF key
   can compute the hash, but anyone with corresponding public key
   can verify the correctness of the hash.
   </t>

   <t>
   The main application of the VRF is to protect the privacy of data records
   stored in a hash-based data structure against a querying adversary. In this
   application, a prover holds the VRF secret key and uses the VRF hashing to
   construct a hash-based data structure on the input data.

   Due to the nature of the VRF hashing, only the prover can answer queries
   about whether or not some data is stored in the data structure.  Anyone who
   knows the public VRF key can verify that the prover has answered the queries
   correctly. However no offline inferences (i.e. inferences without querying
   the prover) can be made about the data stored in the data strucuture.
   </t>

   <!--
   <t>
       VRFs are used for this purpose to prevent zone content enumeration in
       Domain Name System Security Extensions (DNSSEC) with NSEC5 Authenticated
       Denial of Existence <xref target="I-D.vcelak-nsec5"/>.
   </t>
   -->

   </section>
   
        <section title="Requirements">
            <t>
                The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
                "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
                document are to be interpreted as described in
                <xref target="RFC2119" />.
            </t>
        </section>
   
        <section title="Terminology">
                
            <t>
                The following terminology is used through this document:
            </t>

            <t>
                <list style="hanging">
                    <t hangText="SK:">
                        The private key for the VRF. 
                    </t>
                    <t hangText="PK:">
                        The public key for the VRF. 
                    </t>
                    <t hangText="alpha:">
                        The input to be hashed by the VRF. 
                    </t>
                    <t hangText="beta:">
                        The VRF hash output. 
                    </t>
                    <t hangText="pi:">
                        The VRF proof. 
                    </t>
                </list>
            </t>
        </section>
   
   </section>
   
   <section title="VRF Algorithms">
   
   <t>
   A VRF comes with a key generation algorithm that generates a public VRF 
   key PK and private VRF key SK. 
   </t>
   
   <t>
   A VRF hashes an input alpha using the private VRF key SK to obtain a VRF 
   hash output beta:       
    <list>
    <t> beta = VRF_hash(SK, alpha) </t>
    </list>
   The VRF_hash algorithm MUST be deterministic, in 
   the sense that it will always produce the same output beta given a 
   pair of inputs (SK, alpha).
      
   The private key SK is also used to construct a 
   proof pi that beta is the correct hash output 
   <list>
        <t>pi = VRF_prove(SK, alpha)</t>
   </list>
   The VRFs defined in this document allow anyone to deterministically
   obtain the VRF hash output beta directly from the proof value pi as
   <list>
   <t> beta = VRF_proof2hash(pi)</t>
   </list>
   Notice that this means that 
   <list>
   <t> VRF_hash(SK, alpha) = VRF_proof2hash(VRF_prove(SK, alpha))</t>
   </list>
   The proof pi allows anyone holding the public key PK 
   to verify that beta is the correct VRF hash of input alpha
   under key PK. Thus, the VRF also comes with an algorithm
   <list>
   <t>   VRF_verify(PK, alpha, pi)</t>
   </list>
   that outputs VALID if beta=VRF_proof2hash(pi) is correct 
   VRF hash of alpha under key PK, and outputs INVALID otherwise.
   </t>   
   </section>
   
   
   <section title="VRF Security Properties" anchor="secdef">
    
    <t> VRFs are designed to ensure the following security properties.
   </t>
   
   
   <section title= "Full Uniqueness or Trusted Uniqueness">
	
    <t> Uniqueness states that, for any fixed public
	VRF key and for any input alpha, there is a unique VRF
	output beta that can be proved to be valid, even for a 
    computationally-bounded adversary that knows the VRF secret key SK.
    </t>

    <t>
    More precisely, full uniqueness states that 
    a computationally bounded adversary cannot
	choose 
    a VRF public key PK, 
    a VR input alpha, 
    two different VRF hash outputs beta1 and beta2, 
    and two proofs pi1 and pi2 such that 
    VRF_verify(PK, alpha, pi1)
    and VRF_verify(PK, alpha, pi2)
	both output VALID.
    </t>
    
    <t>
     A slightly weaker security
     property called "trusted uniquness" sufficies for many applications.
     Trusted uniqueness is the same as full uniqueness, but it must hold 
     only if the VRF keys PK and SK were generated in a trustworthy 
     manner. In otherwords, uniqueness might not hold if keys were 
     generated in an invalid manner.
	</t>
	</section>
    <section title="Full Pseudorandomness or Selective Pseudorandomness">
    
    <t>
	     Suppose the public and private VRF keys (PK, SK) were generated
	     in a trustworthy manner. 
    </t>
    
    <t>
	     Pseudorandomness ensures that the VRF hash output beta
         (without its corresponding VRF proof pi) on
	     any adversarially-chosen "target" VRF input alpha
	     looks indistinguishable from random
	     for any computationally bounded adversary who does not know the private
         VRF key SK.  This holds even if the adversary also gets to 
         choose other VRF inputs alpha' and observe their corresponding 
         VRF hash outputs beta' and proofs pi'.
    </t>
    
    <t>   
         With "full pseudorandomness", the adversary is allowed to choose the 
         target VRF input  alpha at any time, even after it observes VRF outputs beta'
         and proofs pi' on a variety of chosen inputs alpha'.
         </t>
         
         <t>
         "Selective pseudorandomness" is a weaker security property
         which suffices in many applications. Here, the adversary must choose
         the target VRF input alpha independently of the public VRF key PK,
         and before it  observes VRF outputs beta'
         and proofs pi' on inputs alpha' of its choice.
	     </t>
         
	<t> 
	It is important to remember that the VRF output beta does not 
	look random to a party that knows the private VRF key SK!  Such a party
	can easily distinguish beta from a random value by comparing it to 
	the result of VRF_hash(SK, alpha).	     
	</t>

	<t> Also, the VRF output beta does not look random to any party that
	knows valid VRF proof pi corresponding to the VRF input alpha, even
	if this party does not know the private VRF key SK.
	Such a party can easily distinguish beta from a random value by
    checking whether VRF_verify(PK, alpha, pi) returns "VALID" and
    beta = VRF_proof2hash(pi).
	</t>

    
	<t>
    Finally, the VRF output beta may not look random if VRF key generation
    was not done in a trustworthy fashion. (For example, if VRF keys were 
    not generated with good randomness.)
	</t>

    </section>

	<section title="Full Collison Resistance or Trusted Collision Resistance">

    <t>Finally, like any cryprographic hash function, VRFs need to be
        collision resistant.  Specifically, it should be computationally 
        infeasible for an adversary to find two distinct VRF
	    inputs alpha1 and alpha2 that have the same VRF hash beta, 
        even if that adversary knows the secret VRF key SK.
    </t>
    
    <t>
	    For most applications, a slightly weaker security property
        called "trusted collision resistance" suffices. 
        Trusted collision resistance is the same as collision resistance, 
        but it holds only if PK and SK were generated in a trustworthy manner.
    </t>
   </section>
   </section>
  
   
    <section title="RSA Full Domain Hash VRF (RSA-FDH-VRF)" anchor="fdh">
        <t>
            The RSA Full Domain Hash  VRF (RSA-FDH-VRF) is VRF that satisfies
            the trusted uniqueness, full pseudorandomness, and trusted
            collision resistance properties defined in <xref target="secdef"/>.  
            Its security follows from the
            standard RSA assumption in the random oracle model.  Formal
            security proofs are in <xref target="nsec5ecc" />.  
        </t>

        <t>
            The VRF computes the proof pi as a deterministic RSA signature on
            input alpha using the RSA Full Domain Hash Algorithm
            <xref target="RFC8017" /> parametrized with the selected hash algorithm.
            RSA signature verification is used to verify the correctness of the
            proof. The VRF hash output beta is simply obtained by hashing 
            the proof pi with the selected hash algorithm.
        </t>

        <t>
            The key pair for RSA-FDH-VRF MUST be generated in a way that it satisfies
            the conditions specified in Section 3 of <xref target="RFC8017" />.
        </t>

        <t>
            In this document, the notation from <xref target="RFC8017" /> is used.
        </t>

        <t>
            Used parameters:
            <list>
                <!-- do not change the names, these are from RFC8017 -->
                <t>(n, e) - RSA public key</t>
                <t>K - RSA private key</t>
                <t>k - length in octets of the RSA modulus n</t>
            </list>
        </t>

        <t>
            Fixed options:
            <list>
                <t>Hash - cryptographic hash function</t>
                <t>hLen - output length in octets of hash function Hash</t>
            </list>
        </t>

        <t>
            Options constraints:
            <list>
                <t>Cryptographic security of Hash is at least as high as the cryptographic security level of the RSA key</t>
            </list>
        </t>

        <t>
            Used primitives:
            <list>
                <t>
                    I2OSP - Coversion of a nonnegative integer to an octet string as defined in
                    Section 4.1 of <xref target="RFC8017" />
                </t>
                <t>
                    OS2IP - Coversion of an octet string to a nonnegative integer as defined in
                    Section 4.2 of <xref target="RFC8017" />
                </t>
                <t>
                    RSASP1 - RSA signature primitive as defined in
                    Section 5.2.1 of <xref target="RFC8017" />
                </t>
                <t>
                    RSAVP1 - RSA verification primitive as defined in
                    Section 5.2.2 of <xref target="RFC8017" />
                </t>
                <t>
                    MGF1 - Mask Generation Function based on a hash function as defined in
                    Section B.2.1 of <xref target="RFC8017" />
                </t>
            </list>
        </t>

        <section title="RSA-FDH-VRF Proving">
            <t>
                RSAFDHVRF_prove(K, alpha)
            </t>

            <t>
                Input:
                <list>
                    <t>K - RSA private key</t>
                    <t>alpha - VRF hash input, an octet string</t>
                </list>
            </t>

            <t>
                Output:
                <list>
                    <t>pi - proof, an octet string of length k</t>
                </list>
            </t>

            <t>
                Steps:
                <list style="numbers">
                    <t>EM = MGF1(alpha, k - 1)</t>
                    <t>m = OS2IP(EM)</t>
                    <t>s = RSASP1(K, m)</t>
                    <t>pi = I2OSP(s, k)</t>
                    <t>Output pi</t>
                </list>
            </t>
        </section>
        
        <section title="RSA-FDH-VRF Proof To Hash">
            <t>
                RSAFDHVRF_proof2hash(pi)
            </t>

            <t>
                Input:
                <list>
                    <t>pi - proof, an octet string of length k</t>
                </list>
            </t>
            
            <t>
                Output:
                <list>
                    <t>beta - VRF hash output, an octet string of length hLen</t>
                </list>
            </t>

            <t>
                Steps:
                <list style="numbers">
                    <t>beta = Hash(pi)</t>
                    <t>Output beta</t>
                </list>
            </t>
        </section>

        <section title="RSA-FDH-VRF Verifying">
            <t>
                RSAFDHVRF_verify((n, e), alpha, pi)
            </t>

            <t>
                Input:
                <list>
                    <t>(n, e) - RSA public key</t>
                    <t>alpha - VRF hash input, an octet string</t>
                    <t>pi - proof to be verified, an octet string of length n</t>
                </list>
            </t>

            <t>
                Output:
                <list>
                    <t>"VALID" or "INVALID"</t>
                </list>
            </t>

            <t>
                Steps:
                <list style="numbers">
                    <t>s = OS2IP(pi)</t>
                    <t>m = RSAVP1((n, e), s)</t>
                    <t>EM = I2OSP(m, k - 1)</t>
                    <t>EM' = MGF1(alpha, k - 1)</t>
                    <t>
                        If EM and EM' are the same, output "VALID";
                        else output "INVALID".
                    </t>
                </list>
            </t>
        </section>
 
    </section>

    <section title="Elliptic Curve VRF (EC-VRF)" anchor="ecvrf">

    	<!--<t><cref source="Jan">We repeat these security properties here, 
            although we already said that all VRF functions are required 
            to satisfy these properties. What about removing it here and 
            keep just the rough description, reference to the 
            security proof, and the optional properties (i.e. proof-to-hash)?</cref>
            <cref source="Sharon">Relevant because of trusted / full / selective
            qualifiers of the security definitions. </cref>
        </t>-->
        
        <t>
            The Elliptic Curve Verifiable Random Function (EC-VRF) is VRF that
            satisfies the trusted uniqueness, full pseudorandomness, and
            trusted collision resistance properties defined in <xref target="secdef"/>. 
            The security of this VRF
            follows from the decisional Diffie-Hellman (DDH) assumption in the
            cyclic group in the random oracle model. Formal security proofs are
            in <xref target="nsec5ecc" />.  
        </t>

        <t>
            The key pair generation primitive is specified in
            Section 3.2.1 of <xref target="SECG1" />.
        </t>

        <t>
            Fixed options:
            <list>
                <t>G - EC group</t>
                <t>q - prime order of group G</t>
                <t>g - generator of group G</t>
                <t>2n - ceil(log2(q)/8); where log2(x) is the binary
                 logarithm of x and ceil(x) is the smallest integer 
                 larger than or equal to the real number x. </t>
                 <!--Remember that n=16 for the P-256 curve-->                 
                <t>Hash - cryptographic hash function</t>
                <t>hLen - output length in octets of function Hash</t>
            </list>
        </t>

        <t>
            Options constraints:
            <list>
            	<t>Cryptographic security of Hash is at least as high as the cryptographic security of G</t>
            	<t>hLen is equal to 2n</t>
            </list>
        </t>

        <t>
            Used parameters:
            <list>
                <t>g^x - EC public key</t>
                <t>x - EC private key</t>
             </list>
        </t>

        <t>
            Used primitives:
            <list>
                <t>"" - empty octet string</t>
                <t>|| - octet string concatenation</t>
                <t>p^k - EC point multiplication</t>
                <t>p1*p2 - EC point addition</t>
                <t>h[i] - the i'th octet of octet string h</t>
                <t>ECP2OS - EC point to octet string conversion with point compression as specified in Section 2.3.3 of <xref target="SECG1" /></t>
                <t>OS2ECP - octet string to EC point conversion with point compression as specified in Section 2.3.4 of <xref target="SECG1" /></t>
            </list>
        </t>

        <section title="EC-VRF Proving">
            <t>
                ECVRF_prove(g^x, x, alpha)
            </t>

            <t>
                Input:
                <list>
                    <t>g^x - EC public key</t>
                    <t>x - EC private key</t>
                    <t>alpha - VRF input, octet string</t>
                </list>
            </t>

            <t>
                Output:
                <list>
                    <t>pi - VRF proof, octet string of length 5n+1</t>
                </list>
            </t>

            <t>
                Steps:
                <list style="numbers">
                    <t>h = ECVRF_hash_to_curve(alpha, g^x)</t>
                    <t>gamma = h^x</t>
                    <t>choose a random nonce k from [0, q-1]</t>
                    <t>c = ECVRF_hash_points(g, h, g^x, h^x, g^k, h^k)</t>
                    <t>s = k - c*q mod q</t>
                    <t>pi = ECP2OS(gamma) || I2OSP(c, n) || I2OSP(s, 2n)</t>
                    <t>Output pi</t>
                </list>
            </t>
            
        </section>


        <section title="EC-VRF Proof To Hash">
            <t>
                ECVRF_proof2hash(pi)
            </t>
            <t>
                Input:
                <list>
                    <t>pi - VRF proof, octet string of length 5n+1</t> 
                </list>
            </t>
            <t>
                Output:
                <list>
                    <t>beta - VRF hash output, octet string of length 2n</t>
                </list>
            </t>
            <t>
                Steps:
                <list style="numbers">
                    <t>beta = pi[2] || pi[3] || ... pi[2n+1]</t>
                    <t>Output beta</t>
                </list>
            </t>
        </section>

        <section title="EC-VRF Verifying">
            <t>
                ECVRF_verify(g^x, pi, alpha)
            </t>

            <t>
                Input:
                <list>
                    <t>g^x - EC public key</t>
                    <t>pi - VRF proof, octet string of length 5n+1</t>
                    <t>alpha - VRF input, octet string</t>
                </list>
            </t>

            <t>
                Output:
                <list>
                    <t>"VALID" or "INVALID"</t>
                </list>
            </t>

            <t>
                Steps:
                <list style="numbers">
                    <t>gamma, c, s = ECVRF_decode_proof(pi)</t>
                    <t>
                        If gamma is not a valid EC point in G,
                        output "INVALID" and stop.
                    </t>
                    <t>u = (g^x)^c * g^s</t>
                    <t>h = ECVRF_hash_to_curve(alpha, g^x)</t>
                    <t>v = gamma^c * h^s</t>
                    <t>c' = ECVRF_hash_points(g, h, g^x, gamma, u, v)</t>
                    <t>
                        If c and c' are the same, output "VALID";
                        else output "INVALID". 
                    </t>
                </list>
            </t>
        </section>


        <section title="EC-VRF Auxiliary Functions">

        <section title="EC-VRF Hash To Curve" anchor="ecvrfH2C">
        
            <t>The ECVRF_hash_to_curve algorithm takes in an octet string alpha
            and converts it to h, an EC point in G. </t>
            
            <section title="ECVRF_hash_to_curve1" anchor="ecvrfH2C1">
            
            <t>
            The following ECVRF_hash_to_curve1(alpha, g^x) algorithm
            implements ECVRF_hash_to_curve in a simple and
            generic way that works for any elliptic curve that supports
            point compression.  
            </t>
            
            <t>
            However, this algorithm MUST NOT be used in 
            applications where
            the VRF input alpha must be kept secret. This is because the running time of 
            the hashing algorithm depends on alpha, and so it is susceptible to 
            timing attacks.  That said, the amount of information obtained from
            such a timing attack is likely to be small, since the algorithm 
            is expected to find a valid curve point after only two attempts 
            (i.e., when ctr=1) on average (see <xref target="Icart09"/>).
            </t>
            
            
            <t>
                ECVRF_hash_to_curve1(alpha, g^x)
            </t>
            <t>
                Input:
                <list>
                    <t>alpha - value to be hashed, an octet string</t>
                    <t>g^x - EC public key</t>
                </list>
            </t>
            <t>
                Output:
                <list>
                    <t>h - hashed value, EC point in G</t>
                </list>
            </t>
            
            <t>
                Steps:
                <list style="numbers">
                    <t>ctr = 0</t>
                    <t>pk = ECP2OS(g^x)</t>
                    <t>Repeat:
                    <list style="letters">
                        <t>CTR = I2OSP(ctr, 4)</t>
                        <t>p = 0x02 || Hash(alpha || pk || CTR)</t>
                        <t>Goto step 3 if OS2ECP(p) is valid EC point in G</t>
                        <t>p = 0x03 || Hash(alpha || pk || CTR)</t>
                        <t>Goto step 3 if OS2ECP(p) is valid EC point in G</t>
                        <t>ctr = ctr + 1</t>
                    </list>
                    </t>
                    <t>h = OS2ECP(p)</t>
                    <t>Output h</t>
                </list>
            </t>
            
            <t>
                The initial octet 0x02 in the octet string created in step B
                represents that the point in compressed form has positive
                y-coefficient <xref target="SECG1" />. Similarly, the 0x03 octet
                in step D represents negative y-coefficient.
            </t>
            
            </section>
            
            
            <section title="ECVRF_hash_to_curve2">
            
            <t>For applications where VRF input alpha must be kept secret,
            the following ECVRF_hash_to_curve algorithm MAY be used to used as
            generic way to hash an octet string onto any elliptic curve.
            </t>
            
            <t>[TODO: If there interest, we could look into specifying the 
            generic deterministic time hash_to_curve algorithm from 
            <xref target="Icart09"/>. ]
            </t>
            </section>
        </section>

        <section title="EC-VRF Hash Points">
                     
            <t>
                ECVRF_hash_points(p_1, p_2, ..., p_j)
            </t>
            <t>
                Input:
                <list>
                    <t>p_i - EC point in G</t>
                </list>
            </t>
            <t>
                Output:
                <list>
                    <t>h - hash value, integer between 0 and 2^(8n)-1</t>
                </list>
            </t>
            <t>
                Steps:
                <list style="numbers">
                    <t>P = ""</t>
                    <t>for p_i in [p_1, p_2, ... p_j]:
                       <vspace/>P = P || ECP2OS(p_i)
                    </t>
                    <t>h' = Hash(P) 
                    </t>
                    <t>h = OS2IP(h'[1] || h'[2] || ... h'[n])</t>
                    <t>Output h</t>
                </list>
            </t>
            
            
                   
        </section>

        <section title="EC-VRF Decode Proof">
            <t>
                ECVRF_decode_proof(pi)
            </t>
            <t>
                Input:
                <list>
                    <t>pi - VRF proof, octet string (5n+1 octets)</t>
                </list>
            </t>
            <t>
                Output:
                <list>
                    <t>gamma - EC point</t>
                    <t>
                    c - integer between 0 and 2^(8n)-1
                    </t>
                    <t>
                    s - integer between 0 and 2^(16n)-1
                    </t>
                </list>
            </t>
            <t>
                Steps:
                <list style="numbers">
                    <t>let gamma', c', s' be pi split after (2n+1)-th and (3n+1)-th octet</t>
                    <t>gamma = OS2ECP(gamma')</t>
                    <t>c = OS2IP(c')</t>
                    <t>s = OS2IP(s')</t>
                    <t>Output gamma, c, and s</t>
                </list>
            </t>
        </section>

        </section><!-- Auxiliary Functions -->

        <section title="EC-VRF Ciphersuites">
        
        <t>[Seeking feedback on this section!]</t>
        
        <t>This document defines EC-VRF-P256-SHA256 as follows: 
        <list style="symbols">
        <t>
            The EC group G is the NIST-P256 elliptic curve, with curve parameters
            as specified in <xref target="FIPS-186-3"></xref> (Section D.1.2.3) 
            and <xref target="RFC5114"></xref>  (Section 2.6).  For this group,
            the length in octets of a single coordinate of an EC point is 
            2n = 32.
        </t>
        <t>
            The hash function Hash is SHA-256 as specified in <xref target="RFC6234"/>.
        </t>
        <t>
            The ECVRF_hash_to_curve function is ECVRF_hash_to_curve1, 
            as specified in <xref target="ecvrfH2C1"/>.
        </t>
        </list>
        </t>
        
        <t>This document defines EC-VRF-ED25519-SHA256 as follows: 
        <list style="symbols">
        <t>
            The EC group G is the Ed25519
            elliptic curve with parameters defined in 
            <xref target="RFC7748"></xref> (Section 4.1).      
            For this group,
            the length in octets of a single coordinate of an EC point is 
            2n = 32.
        </t>
        <t>
            The hash function Hash is SHA-256 as specified in <xref target="RFC6234"/>.
        </t>
        <t>
            The ECVRF_hash_to_curve function is as specified in <xref target="ecvrfH2C1"/>.
        </t>
        </list>
        </t>
   
        <t>[TODO: Should we add an EC-VRF-ED25519-SHA256-Elligator
        ciphersuite where the Elligator hash function is used for ECVRF_hash-to-curve?]
        </t>
   
        <t>[TODO: Add an Ed448 ciphersuite?]</t>
        
        </section>
    </section>
    
    
    <section title="Implementation Status" anchor="imp">
    
        <t>
            An implementation of the RSA-FDH-VRF (SHA-256) and EC-VRF-P256-SHA256 was developed
            as a part of the NSEC5 project <xref target="I-D.vcelak-nsec5" /> and is available
            at <eref target="http://github.com/fcelda/nsec5-crypto" />.
        </t>
    
    <t>
    The Key Transparency project at Google
    uses a VRF implemention that is almost identical to
    the EC-VRF-P256-SHA256 specified here, with a few minor changes
    including the use of SHA-512 instead of SHA-256. Its implementation
    is available <eref target="https://github.com/google/keytransparency/blob/master/core/vrf/vrf.go" />
    </t>
    
    <t>
    Open Whisper Systems also uses a VRF very similar to 
    EC-VRF-ED25519-SHA512-Elligator, called VXEdDSA, and specified here:
    <eref target="https://whispersystems.org/docs/specifications/xeddsa/" />
    </t> 
    </section>    


    <section title="Security Considerations" anchor="securitycons">


    <section title="Key Generation">

    <t>Applications that use the VRFs defined in this
    document MUST ensure that that the VRF key is generated correctly,
    using good randomness. Without good randomness, pseudorandomness
    properties of the VRF may not hold. Also, trusted uniqueness and trusted collision-resistance
    may also not hold if the keys are generated
    adversarially  (e.g., the RSA modulus is not a product of two primes
    for the RSA-FDH-VRF or the public key g^x is not valid point in the
    prime-order group G for the EC).
    </t>


    <t>
    Full uniqueness and full collision-resistance (as opposed to trusted
    uniqueness and trusted collision-resistance) are properties that hold
    even if VRF keys are generated by an adversary.
    The VRFs defined in this document
    do not have these properties.
    However, they may be modifed to have these
    properties if adversarial key generation
    is a concern. The modification consists of additional cryptographic
    proofs that keys
    have of the correct form.
    These modifications are left for future specification.
    </t>


    <t>Note that for the RSA-FDH-VRF, it might be possible to construct
        such a proof using the <xref target="GQ88" />
    identification protocol made non-interactive using the Fiat-Shamir heuristic
    in the random oracle model.
    </t>
   
    <t>
     However, it is not possible to guarantee pseudorandomness in the face
    of adversarially generated VRF keys.  This is because an adversary can
    always use bad randomness to generate the VRF keys, and thus, the VRF 
    output may not be pseudorandom.
   </t>
    </section>


    <section title="Proper randomness for EC-VRF">

    <t>
    Applications that use the EC-VRF defined in this document MUST ensure
    that the random nonce k used in the ECVRF_prove algorithm is
    chosen with proper randomness. Otherwise, an adversary may be able to recover
    the private VRF key x (and thus break pseudorandomness of the VRF)
    after observing several valid VRF proofs pi.
    </t>

    </section>

    <section title="Timing attacks">
    
    <t>The EC-VRF_hash_to_curve algorithm defined in
    <xref target="ecvrfH2C1" /> should not be used in applications where
    the VRF input alpha is secret and is hashed by the VRF on-the-fly.
    This is because the EC-VRF_hash_to_curve algorithm's running time depends
    on the VRF input alpha, and thus creates a timing channel that
    can be used to learn information about alpha.
    </t>

    </section>
    
    <section title="Selective vs Full Pseudorandomness">
    
    <t><xref target="nsec5ecc"/> presents cryptographic reductions to an 
    underlying hard problem (e.g. Decisional Diffie Hellman, or the 
    standard RSA assumption) that prove the VRFs specificied in this 
    document possess full pseudorandomness
    as well as selective pseudorandomness. 
    However, the cryptographic reductions are tighter for selective
    pseudorandomness than for full pseudorandomness.  This means the 
    the VRFs have quantitavely stronger security 
    guarentees for selective pseudorandomness. 
    </t>
    
    <t> Applications that are concerned about tightness of cryptographic
    reductions therefor have two options.
    
    <list style="symbols">
    <t> They may choose to ensure that selective pseudorandomness is sufficient for
    the application. That is, that
	pseudorandomness of outputs matters only for inputs that are chosen
    independently of the VRF key. 
    </t>
    <t>If full pseudorandomness is required for the application, the application
    may increase
    security parameters to make up for the loose security reduction. 
    For RSA-FDH-VRF, this means increasing the RSA key length. For 
    EC-VRF, this means increasing the cryptographic strength of the EC group
    G. For both RSA-FDH-VRF and EC-VRF the cryptographic strength of the 
    hash function Hash may also potentially need to be increased.
    </t>
    </list>
    </t>
    </section>

    </section>


    <section title="Change Log">
        <t>
            Note to RFC Editor: if this document does not obsolete an existing RFC,
            please remove this appendix before publication as an RFC.
        </t>

        <t>
            <list>
                <t>
                    00 - Forked this document from draft-vcelak-nsec5-04. 
                    Cleaned up the definitions of VRF algorithms.
                    Added security definitions for VRF and security considerations.
                    Parameterized EC-VRF so it could support curves other than 
                    P-256 and Ed25519. 
                </t> 
            </list>
        </t>
    </section>

    <section title="Contributors">
        <t>
            Leonid Reyzin (Boston University) made major contributions to this 
            document. 
            This document also would not be possible without the work of
            Moni Naor (Weizmann Institute),
            Sachin Vasant (Cisco Systems), and
            Asaf Ziv (Facebook).
            Shumon Huque (Salesforce) and David C. Lawerence (Akamai) provided
            valuable input to this draft.
        </t>
    </section>

</middle>

<back>
    <!-- References Section -->

<!--
     Section 4.7f of [RFC2223bis] specifies the requirements for the
     references sections.  In particular, there MUST be separate lists of
     normative and informative references, each in a separate section.
     The style SHOULD follow that of recently published RFCs.

     In general, each normative reference SHOULD reference the most recent
     version of the specification in question.
-->

    <references title="Normative References">
        <?rfc include="reference.RFC.2119.xml"?>
        <?rfc include="reference.RFC.8017.xml"?>
        <?rfc include="reference.RFC.5114.xml"?>
        <?rfc include="reference.RFC.6234.xml"?>
        <?rfc include="reference.RFC.7748.xml"?>
        <?rfc include="reference.I-D.vcelak-nsec5.xml"?>

        <reference anchor="FIPS-186-3">
            <front>
                <title>Digital Signature Standard (DSS)</title>
                <author><organization>National Institute for Standards and Technology</organization></author>
                <date year="2009" month="June" />
            </front>
            <seriesInfo name="FIPS" value="PUB 186-3" />
        </reference>

        <reference anchor="SECG1" target="http://www.secg.org/sec1-v2.pdf">
            <front>
                <title>SEC 1: Elliptic Curve Cryptography</title>
                <author><organization>Standards for Efficient Cryptography Group (SECG)</organization></author>
                <date year="2009" month="May" />
            </front>
            <seriesInfo name="Version" value="2.0" />
        </reference>

    </references>

    <references title="Informative References">

        <reference anchor="nsec5ecc" target="https://eprint.iacr.org/2017/099.pdf">
            <front>
                <title>NSEC5 from Elliptic Curves</title>
                <author initials="D." surname="Papadopoulos"><organization /></author>
                <author initials="D." surname="Wessels"><organization /></author>
                <author initials="S." surname="Huque"><organization /></author>
                <author initials="J." surname="Vcelak"><organization /></author>
                <author initials="M." surname="Naor"><organization /></author>
                <author initials="L." surname="Reyzin"><organization /></author>
                <author initials="S." surname="Goldberg"><organization /></author>
                <date year="2017" month="February" />
            </front>
            <seriesInfo name="in" value="ePrint Cryptology Archive 2017/099" />
        </reference>

        <reference anchor="MRV99">
            <front>
                <title>Verifiable Random Functions</title>
                <author initials="S." surname="Michali"><organization /></author>
                <author initials="M." surname="Rabin"><organization /></author>
                <author initials="S." surname="Vadhan"><organization /></author>
                <date year="1999" />
            </front>
            <seriesInfo name="in" value="FOCS" />
        </reference>

        <reference anchor="CP92">
            <front>
                <title>Wallet databases with observers</title>
                <author initials="D." surname="Chaum"><organization /></author>
                <author initials="C." surname="Pederson"><organization /></author>
                <date year="1992" />
            </front>
            <seriesInfo name="in" value="FOCS" />
        </reference>


        <reference anchor="Icart09">
            <front>
                <title>How to Hash into Elliptic Curves</title>
                <author initials= "T." surname="Icart"><organization /></author>
                <date year="2009" />
            </front>
            <seriesInfo name="in" value="CRYPTO" />
        </reference>

        <reference anchor="GQ88">
            <front>
                <title>A Practical Zero-Knowledge Protocol Fitted to Security Microprocessor Minimizing Both Transmission and Memory</title>
                <author initials="L. C." surname="Guillou" />
                <author initials="JJ." surname="Quisquater" />
                <date year="1988" />
            </front>
            <seriesInfo name="in" value="Advances in Cryptology - EUROCRYPT '88" />
        </reference>

    </references>


    <section title="Open Issues">
        <t>
            Note to RFC Editor: please remove this appendix before publication as an RFC.
        </t>

        <t>
            <list style="numbers">
                <t>Open issues</t>
            </list>
        </t>
    </section>
  </back>
</rfc>
<!-- vim: et ts=4 sts=4 sw=4 colorcolumn=100 spell :
-->
