Skip to content

Commit

Permalink
Reintroduce padlock module
Browse files Browse the repository at this point in the history
  • Loading branch information
Zekiah-A committed Mar 3, 2024
1 parent e780362 commit ddea174
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 1 deletion.
1 change: 1 addition & 0 deletions padlock/algo-1/algo-1.min.js

Large diffs are not rendered by default.

Binary file added padlock/algo-1/algo-1.wasm
Binary file not shown.
66 changes: 66 additions & 0 deletions padlock/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* eslint-disable jsdoc/require-jsdoc */
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { ServerWebSocket } from "bun"
import * as path from "path"
import { PublicPromise } from "../server-types.ts"
import { fileURLToPath } from "url"

const __dirname = path.dirname(fileURLToPath(import.meta.url))

// Pending serverside solutions
const pendingServerSolutions = new Map<ServerWebSocket<any>, number>()

// Challenge is global for now until we have more challenges we can dynamically switch per client
let sourcesData:string|null = null
let wasmPath = ""
export async function useAlgo(name: string) {
wasmPath = path.join(__dirname, name, name + ".wasm")
const sourcesFile = Bun.file(path.join(__dirname, name, name + ".min.js"))
sourcesData = await sourcesFile.text()
}
await useAlgo("algo-1")

const solveReqs = new Map<number, PublicPromise<bigint>>()
const solveWorker = new Worker(path.join(__dirname, "solve-worker.ts"))
let solveReqId = 0

function makeSolveRequest(data:any) {
const handle = solveReqId++
const postMessage = { handle: handle, data: data, solver: wasmPath }
const promise = new PublicPromise<bigint>()
solveReqs.set(handle, promise)
solveWorker.postMessage(postMessage)
return handle
}
solveWorker.onmessage = ({data}) => {
solveReqs.get(data.handle)?.resolve(data.solution)
}

export function requestChallenge(ws:ServerWebSocket<any>):Buffer {
const challengeData = Buffer.alloc(256)
for (let i = 0; i < challengeData.byteLength; i++) {
challengeData.writeUint8(Math.floor(Math.random() * 256), i)
}
const sourcesBuf = Buffer.from(btoa(sourcesData!))
const packet = Buffer.allocUnsafe(1 + 4 + sourcesBuf.byteLength + challengeData.byteLength)
packet.writeUint8(21, 0)
packet.writeUint32BE(sourcesBuf.byteLength, 1)
packet.set(sourcesBuf, 5)
packet.set(new Uint8Array(challengeData), 5 + sourcesBuf.byteLength)
const handle = makeSolveRequest(challengeData)
pendingServerSolutions.set(ws, handle)
return packet
}

export async function verifySolution(ws:ServerWebSocket<any>, message:Buffer):Promise<"badpacket"|"nosolution"|boolean> {
if (message.byteLength < 9) return "badpacket"
const serverSolutionHandle = pendingServerSolutions.get(ws)
if (serverSolutionHandle == null) return "nosolution"
const solveReq = solveReqs.get(serverSolutionHandle)?.promise
if (!solveReq) return "nosolution"
const serverSolution = await solveReq
const clientSolution = message.readBigUint64BE(1)
pendingServerSolutions.delete(ws)
solveReqs.delete(serverSolutionHandle)
return clientSolution === serverSolution
}
16 changes: 16 additions & 0 deletions padlock/solve-worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { parentPort } from "worker_threads"

async function importWASM(path: string) {
const file = Bun.file(path)
const buffer = await file.arrayBuffer()
const module = await WebAssembly.compile(buffer)
const instance = await WebAssembly.instantiate(module)
return instance
}

self.onmessage = async function(event: any) {
const { handle, data, solver } = event.data
const wasm = await importWASM(solver)
const solution = wasm.exports.solve(data, data.byteLength)
parentPort?.postMessage({ handle, solution })
}
3 changes: 2 additions & 1 deletion server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,8 @@ if (SECURE) {
else {
throw new Error("Could not start server with SECURE, cert and key file could not be opened.")
}
})
}
const bunServer = Bun.serve<ClientData>(serverOptions)
// For compat with methods that use node ws clients property
// @ts-ignore
bunServer.clients = new Set<ServerWebSocket<ClientData>>()
Expand Down

0 comments on commit ddea174

Please sign in to comment.