Initial commit.
This commit is contained in:
commit
0a9434be1b
18 changed files with 1860 additions and 0 deletions
154
server/ts-express/server.ts
Normal file
154
server/ts-express/server.ts
Normal file
|
@ -0,0 +1,154 @@
|
|||
import express, { Request, Response } from 'express';
|
||||
import crypto from 'crypto';
|
||||
|
||||
const app = express();
|
||||
app.use(express.urlencoded({ extended: false }));
|
||||
|
||||
const DIFFICULTY = 20;
|
||||
const challengeStore = new Map<string, number>();
|
||||
|
||||
function generateChallenge(): string {
|
||||
return crypto.randomBytes(12).toString('hex');
|
||||
}
|
||||
|
||||
function hashSha256(input: string): Buffer {
|
||||
return crypto.createHash('sha256').update(input).digest();
|
||||
}
|
||||
|
||||
function checkDifficulty(hash: Buffer, bits: number): boolean {
|
||||
let remaining = bits, i = 0;
|
||||
while (remaining > 0 && i < hash.length) {
|
||||
const byte = hash[i];
|
||||
if (remaining >= 8) {
|
||||
if (byte !== 0) return false;
|
||||
remaining -= 8;
|
||||
} else {
|
||||
const mask = 0xFF << (8 - remaining);
|
||||
if ((byte & mask) !== 0) return false;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
app.get('/', (_req: Request, res: Response) => {
|
||||
const challenge = generateChallenge();
|
||||
challengeStore.set(challenge, Date.now());
|
||||
res.send(`
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>POWOW POC</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
body {
|
||||
padding: 20px;
|
||||
margin-bottom: 300px;
|
||||
background: #cacaca;
|
||||
color: black;
|
||||
}
|
||||
code {
|
||||
white-space: break-spaces;
|
||||
background: black;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
display: block;
|
||||
max-width: 500px;
|
||||
}
|
||||
.h {
|
||||
font-size: 21px;
|
||||
font-weight: bolder;
|
||||
width: 100%;
|
||||
float: left;
|
||||
}
|
||||
button {
|
||||
background: #006ed0;
|
||||
color: white;
|
||||
border: 1px solid #006ed0;
|
||||
padding: 10px 20px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
input {
|
||||
background: black;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
display: block;
|
||||
max-width: 500px;
|
||||
width: 100%;
|
||||
border: 0px solid transparent;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>NOJSCAP demo</h1>
|
||||
<p><a href="https://git.libroot.org/libroot/NOJSCAP/" target="_blank">https://git.libroot.org/libroot/NOJSCAP/</a></p><p><br></p>
|
||||
<p>If you don't already have the <b><em>NOJSCAP</em></b> client:</p>
|
||||
<code>$ git clone https://git.libroot.org/libroot/NOJSCAP/
|
||||
$ cd NOJSCAP/client/</code>
|
||||
<p><br></p>
|
||||
<p>
|
||||
<strong>Python:</strong>
|
||||
</p>
|
||||
<p>
|
||||
<input type="text" value="python3 pow_client.py ${challenge} ${DIFFICULTY}">
|
||||
</p>
|
||||
<p>
|
||||
<strong>Go:</strong>
|
||||
</p>
|
||||
<p>
|
||||
<input type="text" value="go run pow_client.go ${challenge} ${DIFFICULTY}">
|
||||
</p>
|
||||
<p>
|
||||
<strong>Node.js:</strong>
|
||||
</p>
|
||||
<p>
|
||||
<input type="text" value="node pow_client.js ${challenge} ${DIFFICULTY}">
|
||||
</p>
|
||||
<p>
|
||||
<strong>Rust:</strong>
|
||||
</p>
|
||||
<p>
|
||||
<details><summary>Show compilation commands</summary><code>$ rustc pow_client.rs -o pow_client_rs</code>
|
||||
<small>Requires Rust and sha2 crate if using the Cargo version.</small><br></details>
|
||||
<input type="text" value="pow_client_rs ${challenge} ${DIFFICULTY}">
|
||||
</p>
|
||||
<p>
|
||||
<strong>C:</strong>
|
||||
</p>
|
||||
<p>
|
||||
<details><summary>Show compilation commands</summary><code>$ gcc -O2 -o pow_client pow_client.c -lssl -lcrypto</code>
|
||||
<small>Required: GCC or any C compiler. OpenSSL development libraries (libssl-dev on Debian-based systems)</small><br></details>
|
||||
|
||||
<input type="text" value="./pow_client ${challenge} ${DIFFICULTY}">
|
||||
|
||||
</p>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="challenge" value="${challenge}">
|
||||
<label class="h">Enter found nonce: <input name="nonce"></label>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
});
|
||||
|
||||
app.post('/', (req: Request, res: Response) => {
|
||||
const { challenge, nonce } = req.body as { challenge?: string; nonce?: string };
|
||||
if (!challenge || !nonce || !challengeStore.has(challenge)) {
|
||||
return res.send('Invalid input.');
|
||||
}
|
||||
|
||||
challengeStore.delete(challenge);
|
||||
const hash = hashSha256(challenge + nonce);
|
||||
if (checkDifficulty(hash, DIFFICULTY)) {
|
||||
res.send('<p>Success! Valid nonce.</p><a href="/">Try again</a>');
|
||||
} else {
|
||||
res.send('<p>Invalid nonce.</p><a href="/">Try again</a>');
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(3000, () => console.log('Server running at http://localhost:3000'));
|
Loading…
Add table
Add a link
Reference in a new issue