Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local d = false
- for k, v in pairs(peripheral.getNames()) do
- if peripheral.getType(v) == "modem" then
- rednet.open(v)
- d = true
- end
- end
- if not d then
- error("A modem is required!")
- end
- DEBUG = false
- dist_cache = {}
- local function print_debug(stuff)
- if DEBUG == true then
- print(stuff)
- end
- end
- local function download_file(url, target)
- local ht = http.get(url)
- local data = ht.readAll()
- ht.close()
- local file = fs.open(target, "w")
- file.write(data)
- file.close()
- end
- local ringloc = "/ring"
- if (not fs.exists(ringloc)) then
- local newringloc = shell and shell.resolveProgram("ring") or nil
- if type(newringloc) ~= "string" then
- download_file("https://pastebin.com/raw/hCbYTgRs", "/ring")
- else
- ringloc = newringloc
- end
- end
- os.loadAPI(ringloc)
- if not ring then
- error("Ring LWE API failed to load!")
- return
- end
- local aesloc = "/aes"
- if (not fs.exists(aesloc)) then
- local newaesloc = shell and shell.resolveProgram("aes") or nil
- if type(newaesloc) ~= "string" then
- download_file(
- "https://gist.githubusercontent.com/SquidDev/86925e07cbabd70773e53d781bd8b2fe/raw/aeslua.min.lua",
- "/aes"
- )
- else
- aesloc = newaesloc
- end
- end
- os.loadAPI(aesloc)
- if not aes then
- error("AES API failed to load!")
- return
- end
- local function aes_encrypt(key, data, ...)
- return aes.encrypt(string.char(table.unpack(key)), data, ...)
- end
- local function aes_decrypt(key, data)
- return aes.decrypt(string.char(table.unpack(key)), data)
- end
- function recv_with_dist(sProtocolFilter, nTimeout)
- -- The parameters used to be ( nTimeout ), detect this case for backwards compatibility
- if type(sProtocolFilter) == "number" and nTimeout == nil then
- sProtocolFilter, nTimeout = nil, sProtocolFilter
- end
- if sProtocolFilter ~= nil and type(sProtocolFilter) ~= "string" then
- error("bad argument #1 (expected string, got " .. type(sProtocolFilter) .. ")", 2)
- end
- if nTimeout ~= nil and type(nTimeout) ~= "number" then
- error("bad argument #2 (expected number, got " .. type(nTimeout) .. ")", 2)
- end
- -- Start the timer
- local timer = nil
- local sFilter = nil
- if nTimeout then
- timer = os.startTimer(nTimeout)
- sFilter = nil
- else
- sFilter = "modem_message"
- end
- -- Wait for events
- while true do
- local sEvent, sModem, nChannel, nReplyChannel, tMessage, nDistance = os.pullEvent(sFilter)
- if sEvent == "modem_message" then
- -- Return the first matching rednet_message
- local message = tMessage.message
- if tMessage.sProtocol == nil or tMessage.sProtocol == sProtocolFilter then
- return nReplyChannel, message, tMessage.sProtocol, nDistance
- end
- elseif sEvent == "timer" then
- -- Return nil if we timeout
- if p1 == timer then
- return nil
- end
- end
- end
- end
- -- Receiving handshake!
- function initiate_handshake(p)
- while true do
- local from, mes, prot, dist = recv_with_dist(p)
- local data = {}
- if (type(mes) == "string") then
- data = textutils.unserialize(mes)
- end
- if (dist_cache[from] ~= false and type(dist_cache[from]) ~= "number") then
- if (data.moving_mode) then
- dist_cache[from] = false
- else
- dist_cache[from] = dist
- end
- end
- print_debug(textutils.serialize(tostring(data)))
- print_debug(data.type)
- if type(data) == "table" and data.type == "RingLWE_h1" then --YES! We got a handshake.
- print_debug("Got a handshake!")
- local mu, c = ring.encapsulate(data.capsule)
- sleep(0.1)
- local ctx = aes_encrypt(mu, "verification string")
- print_debug("aes: " .. tostring(ctx))
- rednet.send(
- from,
- textutils.serialize(
- {
- type = "RingLWE_h2",
- capsule = c,
- verify = ctx
- }
- ),
- prot
- )
- return mu, c, from
- end
- sleep(0)
- end
- end
- function start_handshake(id, p)
- local s1, b = ring.keyPair()
- rednet.send(
- id,
- textutils.serialize(
- {
- type = "RingLWE_h1",
- capsule = b,
- moving_mode = (pocket ~= nil)
- }
- ),
- p
- )
- print_debug("Sent handshake.")
- while true do
- local from, mes, prot, dist = recv_with_dist(p)
- local data = {}
- if (type(mes) == "string") then
- data = textutils.unserialize(mes)
- end
- if data.type == "RingLWE_h2" then --YES! We got a handshake.
- print_debug("We got a return handshake!")
- if (dist_cache[from] ~= nil and type(dist_cache[from]) == "number" and dist_cache[from] ~= dist) then
- print_debug("ALERT! ALERT! DISTANCE CHECK FAILED AGAINST " .. tostring(from))
- end
- local their_capsule = data.capsule
- local mu = ring.decapsulate(s1, their_capsule)
- if (aes_decrypt(mu, tostring(data.verify))) then
- print_debug("Woo! Ring Exchange worked!")
- end
- return mu
- end
- sleep(0)
- end
- end
- function send_ring(data, mu, p, id)
- if (type(data) ~= "string") then
- data = tostring(data)
- end
- if (type(id) == "number") then
- rednet.send(
- id,
- textutils.serialize(
- {
- type = "RingLWE_d",
- ctx = aes_encrypt(mu, data)
- }
- ),
- p
- )
- else
- rednet.broadcast(
- textutils.serialize(
- {
- type = "RingLWE_d",
- ctx = aes_encrypt(mu, data)
- }
- ),
- p
- )
- end
- end
- function recv_ring(mu, p)
- local from, mes, prot, dist = recv_with_dist(p)
- if (dist_cache[from] ~= nil and type(dist_cache[from]) == "number" and dist_cache[from] ~= dist) then
- print_debug("ALERT! ALERT! DISTANCE CHECK FAILED AGAINST " .. tostring(from))
- end
- local data = {}
- if (type(mes) == "string") then
- data = textutils.unserialize(mes)
- end
- print_debug(tostring(data.type))
- print_debug(tostring(mes))
- if (data.type == "RingLWE_d") then
- return aes_decrypt(mu, tostring(data.ctx))
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment