diff options
Diffstat (limited to 'gamemode/shared/lockbox')
| -rw-r--r-- | gamemode/shared/lockbox/array.lua | 211 | ||||
| -rw-r--r-- | gamemode/shared/lockbox/base64.lua | 157 | ||||
| -rw-r--r-- | gamemode/shared/lockbox/bit.lua | 11 | ||||
| -rw-r--r-- | gamemode/shared/lockbox/ecb.lua | 191 | ||||
| -rw-r--r-- | gamemode/shared/lockbox/padding.lua | 21 | ||||
| -rw-r--r-- | gamemode/shared/lockbox/queue.lua | 47 | ||||
| -rw-r--r-- | gamemode/shared/lockbox/stream.lua | 112 |
7 files changed, 750 insertions, 0 deletions
diff --git a/gamemode/shared/lockbox/array.lua b/gamemode/shared/lockbox/array.lua new file mode 100644 index 0000000..7ae89fc --- /dev/null +++ b/gamemode/shared/lockbox/array.lua @@ -0,0 +1,211 @@ +print("Hello from array.lua!") +local String = string +local Bit = include("bit.lua"); + +local XOR = Bit.bxor; + +local Array = {}; + +Array.size = function(array) + return #array; +end + +Array.fromString = function(string) + local bytes = {}; + + local i=1; + local byte = String.byte(string,i); + while byte ~= nil do + bytes[i] = byte; + i = i + 1; + byte = String.byte(string,i); + end + + return bytes; + +end + +Array.toString = function(bytes) + local chars = {}; + local i=1; + + local byte = bytes[i]; + while byte ~= nil do + chars[i] = String.char(byte); + i = i+1; + byte = bytes[i]; + end + + return table.concat(chars,""); +end + +Array.fromStream = function(stream) + local array = {}; + local i=1; + + local byte = stream(); + while byte ~= nil do + array[i] = byte; + i = i+1; + byte = stream(); + end + + return array; +end + +Array.readFromQueue = function(queue,size) + local array = {}; + + for i=1,size do + array[i] = queue.pop(); + end + + return array; +end + +Array.writeToQueue = function(queue,array) + local size = Array.size(array); + + for i=1,size do + queue.push(array[i]); + end +end + +Array.toStream = function(array) + local queue = Queue(); + local i=1; + + local byte = array[i]; + while byte ~= nil do + queue.push(byte); + i=i+1; + byte = array[i]; + end + + return queue.pop; +end + + +local fromHexTable = {}; +for i=0,255 do + fromHexTable[String.format("%02X",i)]=i; + fromHexTable[String.format("%02x",i)]=i; +end + +Array.fromHex = function(hex) + local array = {}; + + for i=1,String.len(hex)/2 do + local h = String.sub(hex,i*2-1,i*2); + array[i] = fromHexTable[h]; + end + + return array; +end + + +local toHexTable = {}; +for i=0,255 do + toHexTable[i]=String.format("%02X",i); +end + +Array.toHex = function(array) + local hex = {}; + local i = 1; + + local byte = array[i]; + while byte ~= nil do + hex[i] = toHexTable[byte]; + i=i+1; + byte = array[i]; + end + + return table.concat(hex,""); + +end + +Array.concat = function(a,b) + local concat = {}; + local out=1; + + local i=1; + local byte = a[i]; + while byte ~= nil do + concat[out] = byte; + i = i + 1; + out = out + 1; + byte = a[i]; + end + + local i=1; + local byte = b[i]; + while byte ~= nil do + concat[out] = byte; + i = i + 1; + out = out + 1; + byte = b[i]; + end + + return concat; +end + +Array.truncate = function(a,newSize) + local x = {}; + + for i=1,newSize do + x[i]=a[i]; + end + + return x; +end + +Array.XOR = function(a,b) + local x = {}; + + for k,v in pairs(a) do + x[k] = XOR(v,b[k]); + end + + return x; +end + +Array.substitute = function(input,sbox) + local out = {}; + + for k,v in pairs(input) do + out[k] = sbox[v]; + end + + return out; +end + +Array.permute = function(input,pbox) + local out = {}; + + for k,v in pairs(pbox) do + out[k] = input[v]; + end + + return out; +end + +Array.copy = function(input) + local out = {}; + + for k,v in pairs(input) do + out[k] = v; + end + return out; +end + +Array.slice = function(input,start,stop) + local out = {}; + + for i=start,stop do + out[i-start+1] = input[i]; + end + return out; +end + + +return Array; diff --git a/gamemode/shared/lockbox/base64.lua b/gamemode/shared/lockbox/base64.lua new file mode 100644 index 0000000..3d9ffc3 --- /dev/null +++ b/gamemode/shared/lockbox/base64.lua @@ -0,0 +1,157 @@ +local String = string +local Bit = include("bit.lua"); + +local Array = include("array.lua"); +local Stream = include("stream.lua"); + +local AND = Bit.band; +local OR = Bit.bor; +local NOT = Bit.bnot; +local XOR = Bit.bxor; +local LROT = Bit.lrotate; +local RROT = Bit.rrotate; +local LSHIFT = Bit.lshift; +local RSHIFT = Bit.rshift; + + +local SYMBOLS = { +[0]="A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", + "Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f", + "g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v", + "w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"}; + +local LOOKUP = {}; + +for k,v in pairs(SYMBOLS) do + LOOKUP[k]=v; + LOOKUP[v]=k; +end + + +local Base64 = {}; + +Base64.fromStream = function(stream) + local bits = 0x00; + local bitCount = 0; + local base64 = {}; + + local byte = stream(); + while byte ~= nil do + bits = OR(LSHIFT(bits,8),byte); + bitCount = bitCount + 8; + while bitCount >= 6 do + bitCount = bitCount - 6; + local temp = RSHIFT(bits,bitCount); + table.insert(base64,LOOKUP[temp]); + bits = AND(bits,NOT(LSHIFT(0xFFFFFFFF,bitCount))); + end + byte = stream(); + end + + if (bitCount == 4) then + bits = LSHIFT(bits,2); + table.insert(base64,LOOKUP[bits]); + table.insert(base64,"="); + elseif (bitCount == 2) then + bits = LSHIFT(bits,4); + table.insert(base64,LOOKUP[bits]); + table.insert(base64,"=="); + end + + return table.concat(base64,""); +end + +Base64.fromArray = function(array) + local bits = 0x00; + local bitCount = 0; + local base64 = {}; + + local ind = 1; + + local byte = array[ind]; ind = ind + 1; + while byte ~= nil do + bits = OR(LSHIFT(bits,8),byte); + bitCount = bitCount + 8; + while bitCount >= 6 do + bitCount = bitCount - 6; + local temp = RSHIFT(bits,bitCount); + table.insert(base64,LOOKUP[temp]); + bits = AND(bits,NOT(LSHIFT(0xFFFFFFFF,bitCount))); + end + byte = array[ind]; ind = ind + 1; + end + + if (bitCount == 4) then + bits = LSHIFT(bits,2); + table.insert(base64,LOOKUP[bits]); + table.insert(base64,"="); + elseif (bitCount == 2) then + bits = LSHIFT(bits,4); + table.insert(base64,LOOKUP[bits]); + table.insert(base64,"=="); + end + + return table.concat(base64,""); +end + +Base64.fromString = function(string) + return Base64.fromArray(Array.fromString(string)); +end + + + +Base64.toStream = function(base64) + return Stream.fromArray(Base64.toArray(base64)); +end + +Base64.toArray = function(base64) + local bits = 0x00; + local bitCount = 0; + + local bytes = {}; + + for c in String.gmatch(base64,".") do + if (c == "=") then + bits = RSHIFT(bits,2); bitCount = bitCount - 2; + else + bits = LSHIFT(bits,6); bitCount = bitCount + 6; + bits = OR(bits,LOOKUP[c]); + end + + while(bitCount >= 8) do + bitCount = bitCount - 8; + local temp = RSHIFT(bits,bitCount); + table.insert(bytes,temp); + bits = AND(bits,NOT(LSHIFT(0xFFFFFFFF,bitCount))); + end + end + + return bytes; +end + +Base64.toString = function(base64) + local bits = 0x00; + local bitCount = 0; + + local chars = {}; + + for c in String.gmatch(base64,".") do + if (c == "=") then + bits = RSHIFT(bits,2); bitCount = bitCount - 2; + else + bits = LSHIFT(bits,6); bitCount = bitCount + 6; + bits = OR(bits,LOOKUP[c]); + end + + while(bitCount >= 8) do + bitCount = bitCount - 8; + local temp = RSHIFT(bits,bitCount); + table.insert(chars,String.char(temp)); + bits = AND(bits,NOT(LSHIFT(0xFFFFFFFF,bitCount))); + end + end + + return table.concat(chars,""); +end + +return Base64; diff --git a/gamemode/shared/lockbox/bit.lua b/gamemode/shared/lockbox/bit.lua new file mode 100644 index 0000000..0ccdb82 --- /dev/null +++ b/gamemode/shared/lockbox/bit.lua @@ -0,0 +1,11 @@ +local e = bit + +-- Workaround to support Lua 5.2 bit32 API with the LuaJIT bit one +if e.rol and not e.lrotate then + e.lrotate = e.rol +end +if e.ror and not e.rrotate then + e.rrotate = e.ror +end + +return bit diff --git a/gamemode/shared/lockbox/ecb.lua b/gamemode/shared/lockbox/ecb.lua new file mode 100644 index 0000000..67f4514 --- /dev/null +++ b/gamemode/shared/lockbox/ecb.lua @@ -0,0 +1,191 @@ +local Array = include("array.lua"); +local Stream = include("stream.lua"); +local Queue = include("queue.lua"); + +local Bit = include("bit.lua"); + +local CBC = {}; + +CBC.Cipher = function() + + local public = {}; + + local key; + local blockCipher; + local padding; + local inputQueue; + local outputQueue; + local iv; + + public.setKey = function(keyBytes) + print("Set key to:") + print(keyBytes) + key = keyBytes; + return public; + end + + public.setBlockCipher = function(cipher) + blockCipher = cipher; + return public; + end + + public.setPadding = function(paddingMode) + padding = paddingMode; + return public; + end + + public.init = function() + inputQueue = Queue(); + outputQueue = Queue(); + iv = nil; + return public; + end + + public.update = function(messageStream) + print("Entering update") + local byte = messageStream(); + while (byte ~= nil) do + print("processing byte") + inputQueue.push(byte); + print("inputQueue.size is:" .. inputQueue.size()) + print("blockCipher.blockSize:" .. blockCipher.blockSize) + if(inputQueue.size() >= blockCipher.blockSize) then + print("reading from queue") + local block = Array.readFromQueue(inputQueue,blockCipher.blockSize); + if(iv == nil) then + print("iv was nil, iv is now") + iv = block; + PrintTable(block) + else + print("iv was not nil, doing thing") + local out = Array.XOR(iv,block); + print("Calling encrypt with key:") + print(key) + print("and out") + print(out) + out = blockCipher.encrypt(key,out); + print("Out was:") + print(out) + Array.writeToQueue(outputQueue,out); + iv = out; + end + end + byte = messageStream(); + end + print("Before update returned, blockCipher was ") + PrintTable(blockCipher) + return public; + end + + public.finish = function() + paddingStream = padding(blockCipher.blockSize,inputQueue.getHead()); + public.update(paddingStream); + + return public; + end + + public.getOutputQueue = function() + return outputQueue; + end + + public.asHex = function() + print("Outputqueue is:") + PrintTable(outputQueue) + return Stream.toHex(outputQueue.pop); + end + + public.asBytes = function() + return Stream.toArray(outputQueue.pop); + end + + return public; + +end + + +CBC.Decipher = function() + + local public = {}; + + local key; + local blockCipher; + local padding; + local inputQueue; + local outputQueue; + local iv; + + public.setKey = function(keyBytes) + key = keyBytes; + return public; + end + + public.setBlockCipher = function(cipher) + blockCipher = cipher; + return public; + end + + public.setPadding = function(paddingMode) + padding = paddingMode; + return public; + end + + public.init = function() + inputQueue = Queue(); + outputQueue = Queue(); + iv = nil; + return public; + end + + public.update = function(messageStream) + print("Updateing decipher with messagestream") + local byte = messageStream(); + while (byte ~= nil) do + inputQueue.push(byte); + if(inputQueue.size() >= blockCipher.blockSize) then + local block = Array.readFromQueue(inputQueue,blockCipher.blockSize); + + if(iv == nil) then + iv = block; + print("Setting iv to ") + PrintTable(iv) + else + local out = block; + out = blockCipher.decrypt(key,out); + out = Array.XOR(iv,out); + Array.writeToQueue(outputQueue,out); + iv = block; + end + end + byte = messageStream(); + end + return public; + end + + public.finish = function() + paddingStream = padding(blockCipher.blockSize,inputQueue.getHead()); + public.update(paddingStream); + + return public; + end + + public.getOutputQueue = function() + return outputQueue; + end + + public.asHex = function() + return Stream.toHex(outputQueue.pop); + end + + public.asBytes = function() + return Stream.toArray(outputQueue.pop); + end + + public.asString = function() + return Stream.toString(outputQueue.pop) + end + + return public; + +end + +return CBC; diff --git a/gamemode/shared/lockbox/padding.lua b/gamemode/shared/lockbox/padding.lua new file mode 100644 index 0000000..72be077 --- /dev/null +++ b/gamemode/shared/lockbox/padding.lua @@ -0,0 +1,21 @@ +local Stream = include("stream.lua"); + +local ZeroPadding = function(blockSize,byteCount) + + local paddingCount = blockSize - ((byteCount -1) % blockSize) + 1; + local bytesLeft = paddingCount; + + local stream = function() + if bytesLeft > 0 then + bytesLeft = bytesLeft - 1; + return 0x00; + else + return nil; + end + end + + return stream; + +end + +return ZeroPadding; diff --git a/gamemode/shared/lockbox/queue.lua b/gamemode/shared/lockbox/queue.lua new file mode 100644 index 0000000..55b067d --- /dev/null +++ b/gamemode/shared/lockbox/queue.lua @@ -0,0 +1,47 @@ +local Queue = function() + local queue = {}; + local tail = 0; + local head = 0; + + local public = {}; + + public.push = function(obj) + queue[head] = obj; + head = head + 1; + return; + end + + public.pop = function() + if tail < head + then + local obj = queue[tail]; + queue[tail] = nil; + tail = tail + 1; + return obj; + else + return nil; + end + end + + public.size = function() + return head - tail; + end + + public.getHead = function() + return head; + end + + public.getTail = function() + return tail; + end + + public.reset = function() + queue = {}; + head = 0; + tail = 0; + end + + return public; +end + +return Queue; diff --git a/gamemode/shared/lockbox/stream.lua b/gamemode/shared/lockbox/stream.lua new file mode 100644 index 0000000..aeb3b18 --- /dev/null +++ b/gamemode/shared/lockbox/stream.lua @@ -0,0 +1,112 @@ +local Queue = include("queue.lua"); +local String = string + +local Stream = {}; + + +Stream.fromString = function(string) + local i=0; + return function() + print("string is:" .. string) + print("len is:" .. string.len(string)) + print("i is:" .. i) + i=i+1; + if(i <= string.len(string)) then + return string.byte(string,i); + else + return nil; + end + end +end + + +Stream.toString = function(stream) + local array = {}; + local i=1; + + local byte = stream(); + while byte ~= nil do + array[i] = String.char(byte); + i = i+1; + byte = stream(); + end + + return table.concat(array,""); +end + + +Stream.fromArray = function(array) + local queue = Queue(); + local i=1; + + local byte = array[i]; + while byte ~= nil do + queue.push(byte); + i=i+1; + byte = array[i]; + end + + return queue.pop; +end + + +Stream.toArray = function(stream) + local array = {}; + local i=1; + + local byte = stream(); + while byte ~= nil do + array[i] = byte; + i = i+1; + byte = stream(); + end + + return array; +end + + +local fromHexTable = {}; +for i=0,255 do + fromHexTable[String.format("%02X",i)]=i; + fromHexTable[String.format("%02x",i)]=i; +end + +Stream.fromHex = function(hex) + local queue = Queue(); + + for i=1,String.len(hex)/2 do + local h = String.sub(hex,i*2-1,i*2); + queue.push(fromHexTable[h]); + end + + return queue.pop; +end + + + +local toHexTable = {}; +for i=0,255 do + toHexTable[i]=String.format("%02X",i); +end + +Stream.toHex = function(stream) + print("tohex called with stream") + print(stream) + local hex = {}; + local i = 1; + + local byte = stream(); + print("First byte is") + print(byte) + while byte ~= nil do + print("Createing hex:") + print(table.concat(hex,"")) + hex[i] = toHexTable[byte]; + i=i+1; + byte = stream(); + end + + return table.concat(hex,""); +end + +return Stream; |
