-
Notifications
You must be signed in to change notification settings - Fork 20
chore: use crypto package in services #166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8f6757c
44fe8c1
979d734
9716d40
a0d1c17
f85862f
15516be
2278bd0
111d298
561737b
120a5f8
6e5a30e
9b419e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # dependencies (bun install) | ||
| node_modules | ||
|
|
||
| # output | ||
| out | ||
| dist | ||
| *.tgz | ||
|
|
||
| # code coverage | ||
| coverage | ||
| *.lcov | ||
|
|
||
| # logs | ||
| logs | ||
| _.log | ||
| report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json | ||
|
|
||
| # dotenv environment variable files | ||
| .env | ||
| .env.development.local | ||
| .env.test.local | ||
| .env.production.local | ||
| .env.local | ||
|
|
||
| # caches | ||
| .eslintcache | ||
| .cache | ||
| *.tsbuildinfo | ||
|
|
||
| # IntelliJ based IDEs | ||
| .idea | ||
|
|
||
| # Finder (MacOS) folder config | ||
| .DS_Store |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # benchmark-scripts | ||
|
|
||
| To install dependencies: | ||
|
|
||
| ```bash | ||
| bun install | ||
| ``` | ||
|
|
||
| To run: | ||
|
|
||
| ```bash | ||
| bun run index.ts | ||
| ``` | ||
|
|
||
| This project was created using `bun init` in bun v1.2.15. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| { | ||
| "name": "benchmark-scripts", | ||
| "module": "index.ts", | ||
| "type": "module", | ||
| "private": true, | ||
| "devDependencies": { | ||
| "@types/bun": "latest", | ||
| "@types/express": "^5.0.3", | ||
| "express": "^5.1.0" | ||
| }, | ||
| "peerDependencies": { | ||
| "typescript": "^5" | ||
| }, | ||
| "scripts": { | ||
| "crypto": "bun run ./signing-and-verifications/server.ts" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import http from 'k6/http'; | ||
|
|
||
| function _payload() { | ||
| const messagelength = __ENV.MESSAGE_LENGTH || '1024'; | ||
| const engine = __ENV.ENGINE || 'tweetnacl'; | ||
|
|
||
| const stream = !!__ENV.STREAM; | ||
|
|
||
| return JSON.stringify({ | ||
| message: messagelength, | ||
| api: { | ||
| engine, | ||
| stream, | ||
| }, | ||
| }); | ||
|
Comment on lines
+4
to
+15
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix env parsing and generate actual payload size.
- const messagelength = __ENV.MESSAGE_LENGTH || '1024';
- const engine = __ENV.ENGINE || 'tweetnacl';
- const stream = !!__ENV.STREAM;
+ const messagelength = parseInt(__ENV.MESSAGE_LENGTH || '1024', 10);
+ const engine = __ENV.ENGINE || 'tweetnacl';
+ const stream = String(__ENV.STREAM || '').toLowerCase() === 'true';
@@
- return JSON.stringify({
- message: messagelength,
+ const message = 'a'.repeat(Number.isFinite(messagelength) ? messagelength : 1024);
+ return JSON.stringify({
+ message,
api: {
engine,
stream,
},
});Also applies to: 22-27 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| const payload = _payload(); | ||
|
|
||
| console.log('payload:', payload); | ||
|
|
||
| export default function () { | ||
| http.post(`http://localhost:${__ENV.PORT || 8080}/signAndVerify`, payload, { | ||
| headers: { | ||
| 'content-type': 'application/json', | ||
| }, | ||
| }); | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,83 @@ | ||||||||||||||||||||||||
| import express from 'express'; | ||||||||||||||||||||||||
| import nacl from 'tweetnacl'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import { encodeCanonicalJson } from '../../packages/crypto/src'; | ||||||||||||||||||||||||
| import { loadEd25519SignerFromSeed } from '../../packages/crypto/src/utils/keys'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const app = express(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| app.use(express.json()); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| type SignAndVerifyRequest = { | ||||||||||||||||||||||||
| message: string | object; // allow big payloads | ||||||||||||||||||||||||
| api: { | ||||||||||||||||||||||||
| engine: 'native' | 'tweetnacl'; // sodium | ||||||||||||||||||||||||
| stream: boolean; // whether to use streaming API or not | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const seedBytes = new Uint8Array(32).fill(1); // for testing, should be random in real world | ||||||||||||||||||||||||
| const tweetKeyPair = nacl.sign.keyPair.fromSeed(seedBytes); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| function handleTweetnaclSignAndVerify(message: Uint8Array) { | ||||||||||||||||||||||||
| const signature = nacl.sign.detached(message, tweetKeyPair.secretKey); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| nacl.sign.detached.verify(message, signature, tweetKeyPair.publicKey); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+22
to
+26
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check the result of tweetnacl.verify. tweetnacl’s verify returns a boolean; currently ignored. function handleTweetnaclSignAndVerify(message: Uint8Array) {
const signature = nacl.sign.detached(message, tweetKeyPair.secretKey);
-
- nacl.sign.detached.verify(message, signature, tweetKeyPair.publicKey);
+ const ok = nacl.sign.detached.verify(message, signature, tweetKeyPair.publicKey);
+ if (!ok) throw new Error('Invalid signature');
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const nativeSigner = await loadEd25519SignerFromSeed(seedBytes); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| async function handleNativeSignAndVerify(message: Uint8Array, stream: boolean) { | ||||||||||||||||||||||||
| if (!stream) { | ||||||||||||||||||||||||
| const signature = await nativeSigner.sign(message); | ||||||||||||||||||||||||
| await nativeSigner.verify(message, signature); | ||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // @ts-ignore | ||||||||||||||||||||||||
| app.post('/signAndVerify', async (req, res) => { | ||||||||||||||||||||||||
| const { message, api } = req.body as SignAndVerifyRequest; | ||||||||||||||||||||||||
| if (!message) { | ||||||||||||||||||||||||
| return res.status(400).json({ error: 'Message cannot be empty' }); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const { engine, stream = false } = api; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // encode should mimick copy of memory that we'll experience in real world, json -> string | ||||||||||||||||||||||||
| const encodedMessage = new TextEncoder().encode( | ||||||||||||||||||||||||
| typeof message === 'string' ? message : encodeCanonicalJson(message), | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if (engine === 'tweetnacl') { | ||||||||||||||||||||||||
| if (stream) { | ||||||||||||||||||||||||
| return res | ||||||||||||||||||||||||
| .status(400) | ||||||||||||||||||||||||
| .json({ error: 'Stream not supported for tweetnacl' }); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||
| handleTweetnaclSignAndVerify(encodedMessage); | ||||||||||||||||||||||||
| return res.json({ success: true }); | ||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||
| console.error('Tweetnacl sign/verify error', e); | ||||||||||||||||||||||||
| return res.status(500).json({ error: 'Signing or verification failed' }); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if (engine === 'native') { | ||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||
| await handleNativeSignAndVerify(encodedMessage, stream); | ||||||||||||||||||||||||
| return res.json({ success: true }); | ||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||
| console.error('Native sign/verify error', e); | ||||||||||||||||||||||||
| return res.status(500).json({ error: 'Signing or verification failed' }); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| return res.status(400).json({ error: 'Invalid engine' }); | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const port = Number.parseInt(process.env.PORT || '', 10) || 8080; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| app.listen(port, '127.0.0.1', () => console.log(`Listening on ${port}`)); | ||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| { | ||
| "compilerOptions": { | ||
| // Environment setup & latest features | ||
| "lib": ["ESNext"], | ||
| "outDir": "dist", | ||
| "sourceMap": false, | ||
| "target": "ESNext", | ||
| "module": "Preserve", | ||
| "moduleDetection": "force", | ||
| "allowJs": true, | ||
| // Bundler mode | ||
| "moduleResolution": "node", | ||
| "allowImportingTsExtensions": true, | ||
| "verbatimModuleSyntax": true, | ||
| "noEmit": true, | ||
| // Best practices | ||
| "strict": true, | ||
| "skipLibCheck": true, | ||
| "noFallthroughCasesInSwitch": true, | ||
| "noUncheckedIndexedAccess": true, | ||
| "noImplicitOverride": true, | ||
| // Some stricter flags (disabled by default) | ||
| "noUnusedLocals": false, | ||
| "noUnusedParameters": false, | ||
| "noPropertyAccessFromIndexSignature": false | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Add missing dependency and tidy package fields.
Suggested patch:
{ "name": "benchmark-scripts", - "module": "index.ts", + "main": "index.ts", "type": "module", "private": true, + "dependencies": { + "tweetnacl": "^1.0.3" + }, "devDependencies": { "@types/bun": "latest", "@types/express": "^5.0.3", "express": "^5.1.0" }, "peerDependencies": { "typescript": "^5" },Quick check:
🏁 Script executed:
Length of output: 17
Add missing runtime dependency (tweetnacl) to benchmark-scripts/package.json
Confirmed: quick-check shows tweetnacl is missing — add it to "dependencies". Optional: replace "module" with "main" (or remove) if you want a conventional entry field.
File: benchmark-scripts/package.json (lines 1-17)
{ "name": "benchmark-scripts", - "module": "index.ts", + "main": "index.ts", "type": "module", "private": true, + "dependencies": { + "tweetnacl": "^1.0.3" + }, "devDependencies": { "@types/bun": "latest", "@types/express": "^5.0.3", "express": "^5.1.0" }, "peerDependencies": { "typescript": "^5" },📝 Committable suggestion
🤖 Prompt for AI Agents