Skip to content

Instantly share code, notes, and snippets.

@LLFourn
Created April 6, 2021 05:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LLFourn/e6d7c1ad0b970fc6bcd642b25ad9a760 to your computer and use it in GitHub Desktop.
Save LLFourn/e6d7c1ad0b970fc6bcd642b25ad9a760 to your computer and use it in GitHub Desktop.
sub MAIN(Int \m, Int \n, Int :$samples = 10_000) {
my \q = 2 ** 19 - 1;
my \m-n = m ** n;
# experiment should be done over a prime field so that it mirrors reality
say "q = {q} (is-prime: {q.is-prime})";
say "samples = {$samples}, m = {m}, n = {n}, m ^ n = {m-n}";
sub count-collisions(@table) {
# This line of code:
# 1. creates the cartesian product of the columns
# 2. sums each of the products
# 3. removes each duplicate sum
# 4. subtract number of non-duplicate sums from m^n
m-n - ([X+] @table).unique.elems;
}
# the random oracle samples 0..q
my &H = -> *@ { (^q).roll };
my @hash-trails;
my @half-hash-trails;
my @uniform-trails;
for ^$samples {
# hash
{
my @table = (^n).map: -> \i { (^m).map: -> \j { H(i,j) } };
@hash-trails.push: count-collisions(@table);
}
# half hash
{
my @table = (^n).map: -> \i {
my \h = H(i);
(^m).map( -> \j { (j * h) mod q })
};
@half-hash-trails.push: count-collisions(@table);
}
# uniform
@uniform-trails.push: m-n - (^m-n).map({ H() }).unique.elems;
}
say " uniform hash half-hash";
say "----------------------";
say "max: { @uniform-trails.max } { @hash-trails.max } { @half-hash-trails.max }";
say "min: { @uniform-trails.min } { @hash-trails.min } { @half-hash-trails.min }";
say "avg: { @uniform-trails.sum / $samples } { @hash-trails.sum / $samples } { @half-hash-trails.sum / $samples }";
say "med: { median(@uniform-trails) } { median(@hash-trails) } { median(@half-hash-trails) }"
}
sub median(@list) {
@list.sort[(*-1) div 2, * div 2].sum / 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment