Module:RadioGatun32/debug

-- Placed in the public domain 2020, 2022 Sam Trenholme

-- This is a version of RadioGatun[32] (RG32) which uses bit32.

-- Wikipedia has bit32 in an external library

if not bit32 then

bit32 = require("bit32")

end

local p = {}

-- Note that belt and mill are 1-indexed here

local function beltMill(belt, mill)

-- Mill to belt feedforward

for z = 0, 11 do

local offset = z + ((z % 3) * 13) + 1

belt[offset] = bit32.bxor(belt[offset],mill[z + 2])

end

-- Mill core

local rotate = 0

local millPrime = {}

for z = 0, 18 do

rotate = rotate + z

local view = (z * 7) % 19

local num = mill[view + 1]

view = (view + 1) % 19

local viewPrime = (view + 1) % 19

num = bit32.bxor(num,bit32.bor(mill[view + 1],

bit32.bnot(mill[viewPrime + 1])))

num = bit32.rrotate(num,rotate)

millPrime[z + 1] = num

end

for z = 0, 18 do

local view = (z + 1) % 19

local viewPrime = (z + 4) % 19

mill[z + 1] = bit32.bxor(millPrime[z + 1],

millPrime[view + 1],millPrime[viewPrime + 1])

end

-- Belt rotate

for z = 39, 1, -1 do

belt[z + 1] = belt[z]

end

for z = 0, 2 do

belt[(z * 13) + 1] = belt[((z + 1) * 13) + 1]

end

-- Belt to mill

for z = 0, 2 do

mill[14 + z] = bit32.bxor(belt[(z * 13) + 1],mill[14 + z])

end

-- Iota

mill[1] = bit32.bxor(mill[1],1)

end

-- Debug function to show the belt and mill

local function showBeltMill(belt, mill)

for z = 1, 13 do

print(string.format("%2d %08x %08x %08x %08x",z,mill[z],belt[z],

belt[z + 13],belt[z + 26]))

end

for z = 14, 19 do

print(string.format("%2d %08x",z,mill[z]))

end

end

local function initBeltMill()

local belt = {}

local mill = {}

for z = 1, 40 do

belt[z] = 0

end

for z = 1, 19 do

mill[z] = 0

end

return belt, mill

end

-- Output strings which are hex numbers in the same endian order

-- as RadioGatun[32] test vectors, given a float

local function makeLittleEndianHex(i)

local out = ""

for z = 1, 4 do

i = math.floor(i)

out = out .. string.format("%02X",i % 256)

i = i / 256

end

return out

end

-- Output a 256-bit digest string, given a radiogatun state. Affects belt and

-- mill, returns string

local function makeRG32sum(belt, mill)

local out = ""

for z = 1, 4 do

out = out .. makeLittleEndianHex(mill[2]) .. makeLittleEndianHex(mill[3])

beltMill(belt, mill)

end

return out

end

-- RadioGatun input map; given string return belt, mill

local function RG32inputMap(i)

local belt, mill

belt, mill = initBeltMill()

local phase = 0;

for a = 1, string.len(i) do

local c = string.byte(i, a)

local b

c = c % 256

c = c * (2 ^ (8 * (phase % 4)))

b = math.floor(phase / 4) % 3

belt[(13 * b) + 1] = bit32.bxor(belt[(13 * b) + 1],c)

mill[17 + b] = bit32.bxor(mill[17 + b],c)

phase = phase + 1

if phase % 12 == 0 then

beltMill(belt, mill)

end

end

-- Padding byte

local b = math.floor(phase / 4) % 3

local c = 2 ^ (8 * (phase % 4))

belt[(13 * b) + 1] = bit32.bxor(belt[(13 * b) + 1],c)

mill[17 + b] = bit32.bxor(mill[17 + b],c)

-- Blank rounds

for z = 1, 18 do

beltMill(belt,mill)

end

return belt, mill

end

-- Get the input string from a function input

-- depending on how the parent function is called, this can be a Mediawiki

-- table with all args or it can be a simple string.

local function grabString(i)

local input = i

if type(input) == "table" then

local args = nil

local pargs = nil

args = input.args

pargs = input:getParent().args

if args and args[1] then

input = args[1]

elseif pargs and pargs[1] then

input = pargs[1]

else

input = "1234" -- Default value

end

end

return input

end

-- Given an input string, make a string with the hex RadioGatun[32] sum

function p.rg32sum(i)

local belt, mill = RG32inputMap(grabString(i))

return makeRG32sum(belt,mill)

end

-- Given an input to hash, return a formatted version of the hash

-- with both the input and hash value

function p.rg32(i)

local input = grabString(i)

local rginput

-- Remove formatting from the string we give to the rg32 engine

rginput = input:gsub("{{Background color|#%w+|(%w+)}}","%1")

rginput = rginput:gsub("<[^>]+>","") -- Remove HTML tags

rginput = rginput:gsub("%[%[Category[^%]]+%]%]","") -- Remove categories

local sum = p.rg32sum(rginput)

-- This is the output in Mediawiki markup format we give to

-- the caller of this function

return(' RadioGatun[32]("' .. input .. '") =\n ' .. sum)

end

-- This script is a standalone Lua script outside of the Wikipedia

if not mw then

if arg and arg[1] then

print(p.rg32(arg[1]))

else

print(p.rg32(

'The quick brown fox jumps over the lazy {{Background color|#87CEEB|d}}og'))

end

end

return p