Implement algorithm switching

This commit implements every algorithm I have played with so far. It also allows for you to switch which algorithm you want to use at runtime.
This commit is contained in:
Zoe
2025-11-25 18:09:17 +00:00
parent 570531fe32
commit e16383e9b9
20 changed files with 1262 additions and 476 deletions

View File

@@ -1,7 +1,7 @@
import { LitElement, html, css, isServer, type PropertyValues } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { type ChallengeSolveRequest, type SolutionMessage, WorkerMessageType, type WorkerRequest, WorkerResponseType } from './types/worker';
import { type Challenge, ChallengeStrategy } from '@impost/lib';
import { type Challenge, ChallengeStrategy, ChallengeAlgorithm } from '@impost/lib';
import { get_wasm_module } from '@impost/lib/solver';
import ChallengeWorker from './solver-worker?worker&inline';
@@ -172,7 +172,7 @@ export class PowCaptcha extends LitElement {
async initWorkers() {
this.solverWorkers = [];
const num_workers = 1;
const num_workers = navigator.hardwareConcurrency || 4;
for (let i = 0; i < num_workers; i++) {
this.solverWorkers.push(new ChallengeWorker());
}
@@ -275,11 +275,52 @@ export class PowCaptcha extends LitElement {
// } as WorkerRequest);
// break;
// }
switch (request.strategy) {
case ChallengeStrategy.kCTF:
switch (request.algorithm) {
case ChallengeAlgorithm.SHA256:
switch (request.strategy) {
case ChallengeStrategy.LeadingZeroes:
worker.postMessage({
algorithm: ChallengeAlgorithm.SHA256,
strategy: ChallengeStrategy.LeadingZeroes,
salt: request.salt,
difficulty: request.difficulty,
} as WorkerRequest);
break;
case ChallengeStrategy.TargetNumber:
worker.postMessage({
algorithm: ChallengeAlgorithm.SHA256,
strategy: ChallengeStrategy.TargetNumber,
target: request.target,
salt: request.salt,
} as WorkerRequest);
break;
}
break;
case ChallengeAlgorithm.Argon2id:
switch (request.strategy) {
case ChallengeStrategy.LeadingZeroes:
worker.postMessage({
algorithm: ChallengeAlgorithm.Argon2id,
strategy: ChallengeStrategy.LeadingZeroes,
salt: request.salt,
difficulty: request.difficulty,
} as WorkerRequest);
break;
case ChallengeStrategy.TargetNumber:
worker.postMessage({
algorithm: ChallengeAlgorithm.Argon2id,
strategy: ChallengeStrategy.TargetNumber,
target: request.target,
salt: request.salt,
} as WorkerRequest);
break;
}
break;
case ChallengeAlgorithm.kCTF:
worker.postMessage({
strategy: ChallengeStrategy.kCTF,
challenge: request.challenge,
algorithm: ChallengeAlgorithm.kCTF,
salt: request.salt,
difficulty: request.difficulty,
} as WorkerRequest);
break;
}
@@ -329,11 +370,52 @@ export class PowCaptcha extends LitElement {
// };
// break;
// }
switch (this.challengeData.strategy) {
case ChallengeStrategy.kCTF:
switch (this.challengeData.algorithm) {
case ChallengeAlgorithm.SHA256:
switch (this.challengeData.strategy) {
case ChallengeStrategy.LeadingZeroes:
request = {
algorithm: ChallengeAlgorithm.SHA256,
strategy: ChallengeStrategy.LeadingZeroes,
salt: this.challengeData.salt,
difficulty: this.challengeData.difficulty,
};
break;
case ChallengeStrategy.TargetNumber:
request = {
algorithm: ChallengeAlgorithm.SHA256,
strategy: ChallengeStrategy.TargetNumber,
target: this.challengeData.target,
salt: this.challengeData.salt,
};
break;
}
break;
case ChallengeAlgorithm.Argon2id:
switch (this.challengeData.strategy) {
case ChallengeStrategy.LeadingZeroes:
request = {
algorithm: ChallengeAlgorithm.Argon2id,
strategy: ChallengeStrategy.LeadingZeroes,
salt: this.challengeData.salt,
difficulty: this.challengeData.difficulty,
};
break;
case ChallengeStrategy.TargetNumber:
request = {
algorithm: ChallengeAlgorithm.Argon2id,
strategy: ChallengeStrategy.TargetNumber,
target: this.challengeData.target,
salt: this.challengeData.salt,
};
break;
}
break;
case ChallengeAlgorithm.kCTF:
request = {
strategy: ChallengeStrategy.kCTF,
challenge: this.challengeData.challenge,
algorithm: ChallengeAlgorithm.kCTF,
salt: this.challengeData.salt,
difficulty: this.challengeData.difficulty,
};
break;
}
@@ -346,9 +428,13 @@ export class PowCaptcha extends LitElement {
// TODO: We need to do a better job of tracking solvers, so if one worker
// errors out, we only error out if all workers have errored out.
let worker_promises: Promise<SolutionMessage>[] = [];
for (let worker of this.solverWorkers) {
// dispatch to all workers, func is async so it will not block
worker_promises.push(this.issueChallengeToWorker(worker, request));
if (request.algorithm === ChallengeAlgorithm.kCTF) {
worker_promises.push(this.issueChallengeToWorker(this.solverWorkers[0], request));
} else {
for (let worker of this.solverWorkers) {
// dispatch to all workers, func is async so it will not block
worker_promises.push(this.issueChallengeToWorker(worker, request));
}
}
let solution = await Promise.race(worker_promises);
@@ -370,7 +456,7 @@ export class PowCaptcha extends LitElement {
await fetch(`${this.challengeUrl}/challenge`, {
method: 'POST',
body: JSON.stringify({
challenge: this.challengeData.challenge,
salt: this.challengeData.salt,
solution: solution.solution,
}),
headers: {
@@ -382,7 +468,7 @@ export class PowCaptcha extends LitElement {
this.dispatchEvent(new CustomEvent('impost:solved', {
detail: {
challenge: this.challengeData.challenge,
salt: this.challengeData.salt,
solution: solution.solution,
},
bubbles: true,