hardbyte/Paillier.jl

Random number stream/pool

hardbyte opened this issue · 1 comments

It would be faster to precompute a bunch of n bit random numbers for a given public key's n so that during use (in particular during the obfuscation step) the numbers are already to go.

One idea is that a Channel is created with a specific sized buffer and a Task has the job of keeping it full.

It would be worth benchmarking before and after this.

A first cut:

DEFAULT_RANDOM_BUFFER = 2048

function create_producer_of_nbit_randoms(rng::AbstractRNG, n::Integer)
    function producer(c::Channel)
       while true
           put!(c, Paillier.n_bit_random_number(n))
       end
    end
end

n_bit_producers = Dict{Integer, Channel}()

function init_random_stream(rng::AbstractRNG, n::Integer, buffer=DEFAULT_RANDOM_BUFFER)
    return n_bit_producers[n] = Channel(create_producer_of_nbit_randoms(rng, n), csize=buffer)
end

function n_bit_random_channel(n)
    if !haskey(n_bit_producers, n)
        rng = default_rng()
        init_random_stream(rng, n, DEFAULT_RANDOM_BUFFER)
    end
    return n_bit_producers[n]
end

default_rng() = Paillier.default_rng()
n_bit_random_number(len::Integer) = n_bit_random_number(default_rng(), len)
n_bit_random_number(len::Integer) = n_bit_random_number(Paillier.default_rng(), len)
function n_bit_random_number(rng::AbstractRNG, len::Integer)
    return take!(n_bit_random_channel(len))
end

Not sure if in the __init__() I should call init_random_stream