bigint-extra.lua 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. #!/usr/bin/env lua
  2. local bigint = require("bigint")
  3. local bigint_extra = {}
  4. local zero = bigint.new(0)
  5. local one = bigint.new(1)
  6. local three = bigint.new(3)
  7. local four = bigint.new(4)
  8. -- Implementation of the Blum Blum Shub PRNG
  9. local p = bigint.new(15487151)
  10. local q = bigint.new(29731279)
  11. assert(bigint.compare(bigint.modulus(p, four), three, "=="), "p mod 4 != 3")
  12. assert(bigint.compare(bigint.modulus(q, four), three, "=="), "q mod 4 != 3")
  13. local m = bigint.multiply(p, q)
  14. local x = bigint.multiply(bigint.new(os.time()), bigint.new(1000)) -- the seed
  15. -- BACKEND: Completely functional but requires two arguments
  16. function bigint_extra.random_raw(low, high)
  17. -- Type checking done by bigint.compare
  18. local range, result
  19. assert(bigint.compare(low, high, "<"), bigint.unserialize(low)
  20. .. " is not less than "
  21. .. bigint.unserialize(high))
  22. range = bigint.add(bigint.subtract(high, low), one)
  23. x = bigint.modulus(bigint.multiply(x, x), m)
  24. return bigint.add(bigint.divide(bigint.multiply(x, range), m), low)
  25. end
  26. -- FRONTEND: Fill in missing arguments
  27. function bigint_extra.random(low, high)
  28. if (low and high) then -- Output between low and high
  29. if (bigint.compare(low, high, "==")) then
  30. return low:clone()
  31. else
  32. return bigint_extra.random_raw(low, high)
  33. end
  34. elseif (low) then -- Output between one and low
  35. return bigint_extra.random_raw(one, low)
  36. else -- Output one or zero
  37. return bigint_extra.random(zero, one)
  38. end
  39. end
  40. bigint_extra.random(); bigint_extra.random(); bigint_extra.random() -- Initialize PRNG
  41. return bigint_extra