cc-stuff/dh/dh.lua

72 lines
2.1 KiB
Lua

local ecc = require("ecc")
string.toHex = function(str)
return str:gsub(".", function(ch) return string.format("%02x", ch:byte()) end)
end
string.fromHex = function(hex)
return hex:gsub("%x%x", function(d) return string.char(tonumber(d, 16)) end)
end
local keypair = {}
if fs.exists("/.id_dh.json") then
local fp = io.open("/.id_dh.json", "r")
local d = textutils.unserializeJSON(fp:read())
keypair.sk = string.fromHex(d.secret)
keypair.pk = string.fromHex(d.public)
fp:close()
else
printError("no identity found, generating...")
local sk, pk = ecc.keypair(ecc.random.random())
io.open("/.id_dh.json", "w"):write(textutils.serializeJSON({
secret = string.toHex(sk),
public = string.toHex(pk)
})):close()
keypair.sk = string.char(table.unpack(sk))
keypair.pk = string.char(table.unpack(pk))
end
print("pubkey: "..string.toHex(keypair.pk))
local running = true
local known_hosts = {}
parallel.waitForAll(function() while running do -- dh:discover sender
rednet.broadcast(keypair.pk, "dh:discover")
os.sleep(10)
end end,
function() while running do -- dh:discover handler
local id, pk, proto = rednet.receive("dh:discover")
if proto == "dh:discover" then
print("DH discover from "..id.." with key "..pk)
local nonce = string.toHex(ecc.random.random())
local key = ecc.exchange(keypair.sk, pk)
known_hosts[id] = {
id = id,
pk = pk,
sk = key,
verified = false,
nonce = nonce,
t = os.clock()
}
known_hosts[pk] = known_hosts[id]
rednet.send(id, {
pk = keypair.pk,
msg = ecc.encrypt(nonce, key)
}, "dh:pair")
end
end end,
function() while running do -- dh:pair handler
local id, msg, proto = rednet.receive("dh:pair")
if proto == "dh:pair" then
local key = ecc.exchange(keypair.sk, msg.pk)
known_hosts[id] = {
id = id,
pk = msg.pk,
sk = key,
verified = false,
nonce = ecc.decrypt(msg.msg, msg.msg)
}
end
end end)