\documentclass{article}
\input{../../../lib.sty}


\title{\texttt{fn sample\_geometric\_buffer}}
\author{Vicki Xu, Hanwen Zhang, Zachary Ratliff}
\begin{document}
\maketitle

This document proves soundness of \rustdoc{traits/samplers/geometric/fn}{sample\_geometric\_buffer} in \asOfCommit{mod.rs}{f5bb719}.

\section{Hoare Triple}
\subsection*{Preconditions}
None

\subsection*{Pseudocode}
\begin{lstlisting}[language=Python, escapechar=|]
def sample_geometric_buffer(buffer_len: usize, constant_time: bool) -> Optional[uint]: |\label{line:geombuffer}|
    
    if constant_time: 
        buf = bytearray(buffer_len)
        fill_bytes(buf) # mutates in-place
        ret = None
        for i in range(buffer_len):
            # find first nonzero event
            if buf[i] > 0:
                # compute index of first nonzero bit buffer
                cand = 8 * i + buf[i].leading_zeroes() |\label{line:indexcmp}|
                ret = cand if ret is None else min(ret, cand)
        return ret
    else:
        for i in range(buffer_len):
            buf = bytearray(1)
            fill_bytes(buf) # mutates in-place
            if buf[0] > 0:
                return 8 * i + buf[0].leading_zeroes()
        
        return None
\end{lstlisting}

\subsection*{Postcondition}
For any setting of the input arguments, \texttt{sample\_geometric\_buffer} either
raises an exception if there is insufficient system entropy, 
or returns \texttt{sample} where \texttt{sample} is drawn from a discrete distribution.

\texttt{sample} is either 
\texttt{geo} where \texttt{geo} is a sample from the $Geometric(p=0.5)$ distribution, and is less than $buffer\_len * 8$, or
\texttt{None} with probability $2^{-buffer\_len * 8}$.

\begin{proof}
    \texttt{sample\_geometric\_buffer} uses \rustdoc{traits/samplers/fn}{fill\_bytes} as a subroutine to generate a buffer of $\texttt{buffer\_len}$ bytes.
    For each bit $b$ in the buffer it follows that $\Pr[b = 1] = \frac{1}{2}$ and $\Pr[b = 0] = \frac{1}{2}$. 
    If there is some bit in the buffer equal to $1$, 
    the position of the \emph{first} such bit is a zero-indexed draw from the Geometric distribution $Geom(p)$ with $p = 0.5$,
    by definition of a Geometric random variable. 
    If the buffer is zero, the function returns \texttt{None}. 
\end{proof}

\end{document}
