\documentclass[12pt,letterpaper]{article}
\usepackage{amsthm}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{upquote}
\usepackage[margin=1.5in]{geometry}

\newcommand{\eps}{\epsilon}
\newcommand{\wh}{\widehat}
\newcommand{\R}{\mathbb{R}}
\newcommand{\norm}[1]{\|#1\|}
\newcommand{\abs}[1]{|#1|}
\DeclareMathOperator*{\E}{\mathbb{E}}
\DeclareMathOperator{\poly}{poly}
\DeclareMathOperator*{\mean}{mean}
\DeclareMathOperator*{\median}{median}

\title{Problem Set 5}
\author{Randomized Algorithms}
\date{Due Friday, October 4}
\begin{document}
\maketitle

\begin{enumerate}
\item{} In class, we showed that cuckoo hashing achieves worst case
  constant time lookups and expected constant time insertion/deletion,
  with $O(n)$ space to store $n$ items.  Show how to get the same
  guarantees, but using only $(1 + \eps) n$ space for a small constant
  $\eps$.  For this problem, assume that you have access to
  perfectly random hash functions. \textbf{Hint:} Use the following
  ideas:
  \begin{itemize}
  \item Probing more than twice in a table increases the chances of finding an empty cell.
  \item If after some probes you fail to find an empty cell, move the
    failed item into an ``overflow'' table that uses cuckoo hashing.
  \end{itemize}
\item{} For a hash family $\mathcal{H}$ from $[U]$ to $[n]$, and a set
  of items $S \subset [U]$, let $X(\mathcal{H}, S)$ be the random variable denoting the load in the first bin:
  \[
  X := \abs{\{i \in S \mid h(i) = 1\}}
  \]
  as a distribution over $h \in \mathcal{H}$.  Further, let
  $f(\mathcal{H}, S)$ denote the expected max load in any bin:
  \[
  f(\mathcal{H}, S) := \E_{h \in \mathcal{H}} \max_{j \in [n]} \abs{\{i \in S \mid h(i) = j\}}.
  \]
  \begin{enumerate}
  \item For any $t \geq 1$, and for any $k$-wise independent hash
    family $\mathcal{H}$ with $k = O(1)$, and any set $S$ with
    $\abs{S} = n$, show that
    \[
    \Pr[X \geq t] \lesssim 1/t^k.
    \]
    \textbf{Hints:} bound $\E[(X-\E[X])^k]$. (Rot13) Svefg svther vg
    bhg jura u vf shyyl vaqrcraqrag; lbhe cebbs zbfg yvxryl bayl arrqf
    x-jvfr vaqrcraqrapr.
  \item Use the above to show that for any $k$-wise independent family $\mathcal{H}$, $k = O(1)$, that
    \[
    f(\mathcal{H}, S) \lesssim n^{1/k}
    \]
    for any $S$ with $\abs{S} = n$.
  \item Consider the special case $U = n$, $S = [n]$.  Show that there
    exists a universal hash family $\mathcal{H}$ such that
    \[
      f(\mathcal{H}, S) \gtrsim \sqrt{n}.
    \]
    (Optional.) Extend your construction to be pairwise independent,
    not just universal.

    \textbf{Hint:} You may make $\mathcal{H}$ extremely contrived
    and/or large, as long as it satisfies the constraint of
    univerality/pairwise independence.
  \end{enumerate}
% \item{} (Optional.) A \emph{minimal perfect} hash function for a set $S$
%   of size $n$ is one that maps $S$ to $[n]$ with no collisions.  In
%   class, we showed how to take $S$ and construct a minimal perfect
%   hash function for $S$ that can be evaluated in constant time.  The
%   construction took expected $O(n)$ time and the resulting function
%   took $O(n)$ words to store.

%   Show that this last condition cannot be significantly improved upon.
%   In particular, show that any procedure for storing a minimal perfect
%   hash function requires at least $\Omega(n)$ bits for some $S$ of
%   size $n$.  Assume the universe size $U$ is polynomial in $n$.
%   \textbf{Hint:} show that any particular function $h$ is perfect for
%   at most a $1/2^{\Omega(n)}$ fraction of the possible sets $S$.
% \item{} Bloom filters can be used to estimate the difference
%   between two sets. Suppose that you have sets $X$ and $Y$, each with
%   $m$ elements, and with $r$ elements in common. Create an $n$-bit
%   Bloom filter for each, using the same $k$ hash functions. Determine
%   the expected number of bits where the two Bloom filters differ, as a
%   function of $m$, $n$, $k$, and $r$. Explain how this could be used
%   as a technique for estimating $r$.
% \item{} [MR 4.9]. Consider the following randomized variant of the bit
%   fixing algorithm.  Each packet randomly orders the bit positions in
%   the label of its source and then corrects the mismatched bits in
%   that order. Show that there is a permutation for which, with high
%   probability, this algorithm uses $2^{\Omega(n)}$ steps to route.
% \item{} [MR7.2]. Two rooted trees $T_1$ and $T_2$ are said to be
%   isomorphic if there exists a one to one mapping $f$ from the nodes
%   of $T_1$ to those of $T_2$ satisfying the following condition: $v$
%   is a child of $w$ in $T_1$ if and only if $f(v)$ is a child of
%   $f(w)$ in $T_2$. Observe that no ordering is assumed on the children
%   of any vertex. Devise an efficient randomized algorithm for testing
%   the isomorphism of rooted trees and analyze its
%   performance. \textbf{Hint}: Recursively associate a polynomial $P_v$
%   with each vertex $v$ in a tree $T$.
\item The Python programming language uses hash tables (or
  ``dictionaries'') internally in many places.  Until 2012, however,
  the hash function was not randomized: keys that collided in one
  Python program would do so for every other program.  To avoid denial
  of service attacks, Python implemented hash randomization---but
  there was an issue with the initial implementation.  Also, in python 2,
  hash randomization is still not the default: one must enable it with the
  \texttt{-R} flag.

  Find a 64-bit machine with both Python 2.7 and Python 3.5 or later;
  one is available at \texttt{linux.cs.utexas.edu}.

  \begin{enumerate}
  \item First, let's look at the behavior of $\texttt{hash}(``a") -
    \texttt{hash}(``b")$ over $n = 2000$ different initializations.  If
    $\texttt{hash}$ were pairwise independent over the range (64-bit
    integers, on a 64-bit machine), how many times should we see the
    same value appear?


  \item How many times \emph{do} we see the same value appear, for
    three different instantiations of python: (I) no randomization
    (\texttt{python2}), (II) python 2's hash randomization
    (\texttt{python2 -R}), and (III) python 3's hash randomization
    (\texttt{python3})?

    % If you have trouble coding this on your own, the following snippet
    % lets you get the answer:
%     \begin{verbatim}
% for i in `seq 1 2000`; do
%   python2 -R -c 'print((hash("a")-hash("b")))';
% done | sort | uniq -c | awk '{print $1}' | sort -n | uniq -c
% \end{verbatim}

  \item What might be going on here?  Roughly how many ``different''
    hash functions does this suggest that each version has?

  \item The above suggests that Python 2's hash randomization is
    broken, but does not yet demonstrate a practical issue.  Let's
    show that large collision probabilities happen.  Observe that the
    strings ``8177111679642921702" and ``6826764379386829346" hash to
    the same value in non-randomized python 2.

    Check how often those two keys hash to the same value under
    \texttt{python2 -R}.  What fraction of runs do they collide?  Run
    it enough times to estimate the fraction to within $20\%$
    multiplicative error, with good probability.

    How could an attacker use this behavior to denial of service
    attack a website?

  \item (Optional) Find other pairs of inputs that collide.  

  \end{enumerate}
\end{enumerate}

\end{document}
