## fuzzyhash - A toy (s-t)Detectable Hash Function
This package contains a toy implementation of an (s-t)Detectable Hash Function as described in [The Apple PSI System](https://www.apple.com/child-safety/pdf/Apple_PSI_System_Security_Protocol_and_Analysis.pdf) by Abhishek Bhowmick, Dan Boneh, Steve Myers, Kunal Talwa, and Karl Tarbe.
The first kind of hash (`Hash(x)`) "a true hash" multiplies the given `x` by the secret key (treating the secret key as a `s x t` matrix of polynomials (`p_1..p_s`)). `DHF(k,x):=(x,p_1(x),...,p_s(x))`
The second kind of hash is a random hash of the same size as a true hash, but all the elements are selected randomly
from the domain.
#### The Detection Algorithm
Given a set of hashes, a `Solver` is able to distinguish true hashes from random hashes as long as there are
at least `t+1` true hashes and a maximum of `s` random hashes.
The solver does this by computing the kernel basis vectors of a Matrix containing an **extended** version of the
hashes which transforms the upper portion of the matrix into a Vandermonde matrix, and the lower portion contains
the evaluated polynomials from the hashes themselves.
Our solver does this by first appending the identity matrix to the lower portion of the matrix, then transposing,
converting the matrix to row-echelon form, and transposing again - at which point the kernel basis vectors, if there
are any, are found in the lower portion of matrix.
(If there are no basis vectors then the algorithm returns an error as there are not enough true hashes
in the set to compute a solution)
We then check the kernel basis for rows where all values are zero, and eliminate these as random rows. What is left
is the solution to the detection algorithm - the indexes of the original hashes which are actually true hashes.