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:
@@ -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,
|
||||
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
WorkerResponseType,
|
||||
} from "./types/worker";
|
||||
|
||||
import { type SolverModule, init_solver, solve } from '@impost/lib/solver';
|
||||
import { type SolverModule, init_solver, solve, type SolveParams } from '@impost/lib/solver';
|
||||
import { ChallengeStrategy, ChallengeAlgorithm } from '@impost/lib';
|
||||
|
||||
let solver: SolverModule | null = null;
|
||||
|
||||
@@ -59,9 +60,59 @@ onmessage = async (event: MessageEvent<WorkerRequest>) => {
|
||||
return;
|
||||
}
|
||||
|
||||
let solution: string;
|
||||
let solution: string | number;
|
||||
try {
|
||||
solution = solve(solver, event.data.challenge);
|
||||
let params = {
|
||||
name: event.data.algorithm,
|
||||
salt: event.data.salt,
|
||||
};
|
||||
|
||||
switch (event.data.algorithm) {
|
||||
case ChallengeAlgorithm.SHA256:
|
||||
switch (event.data.strategy) {
|
||||
case ChallengeStrategy.LeadingZeroes:
|
||||
// @ts-ignore
|
||||
params.strategy = ChallengeStrategy.LeadingZeroes;
|
||||
// @ts-ignore
|
||||
params.difficulty = event.data.difficulty;
|
||||
break;
|
||||
case ChallengeStrategy.TargetNumber:
|
||||
// @ts-ignore
|
||||
params.strategy = ChallengeStrategy.TargetNumber;
|
||||
// @ts-ignore
|
||||
params.target = event.data.target;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ChallengeAlgorithm.Argon2id:
|
||||
switch (event.data.strategy) {
|
||||
case ChallengeStrategy.LeadingZeroes:
|
||||
// @ts-ignore
|
||||
params.strategy = ChallengeStrategy.LeadingZeroes;
|
||||
// @ts-ignore
|
||||
params.difficulty = event.data.difficulty;
|
||||
break;
|
||||
case ChallengeStrategy.TargetNumber:
|
||||
// @ts-ignore
|
||||
params.strategy = ChallengeStrategy.TargetNumber;
|
||||
// @ts-ignore
|
||||
params.target = event.data.target;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ChallengeAlgorithm.kCTF:
|
||||
// @ts-ignore
|
||||
params.strategy = ChallengeStrategy.Null;
|
||||
// @ts-ignore
|
||||
params.difficulty = event.data.difficulty;
|
||||
break;
|
||||
}
|
||||
|
||||
solution = solve(solver, params as SolveParams);
|
||||
|
||||
if (event.data.algorithm !== ChallengeAlgorithm.kCTF) {
|
||||
solution = Atomics.load(atomic_solution!, 0);
|
||||
}
|
||||
} catch (error: any) {
|
||||
postMessage({
|
||||
type: WorkerResponseType.Error,
|
||||
@@ -70,6 +121,7 @@ onmessage = async (event: MessageEvent<WorkerRequest>) => {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
postMessage({
|
||||
type: WorkerResponseType.Solution,
|
||||
solution,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChallengeStrategy } from "@impost/lib";
|
||||
import { ChallengeAlgorithm, ChallengeStrategy } from "@impost/lib";
|
||||
|
||||
export enum WorkerMessageType {
|
||||
Init = "init",
|
||||
@@ -12,37 +12,40 @@ interface WorkerInitRequest {
|
||||
sab: SharedArrayBuffer;
|
||||
}
|
||||
|
||||
// interface ChallengeLeadingZeroesSolveRequest {
|
||||
// strategy: ChallengeStrategy.LeadingZeroes;
|
||||
// salt: string;
|
||||
// difficulty: number;
|
||||
// }
|
||||
interface ChallengeLeadingZeroesSolveRequest {
|
||||
algorithm: ChallengeAlgorithm.SHA256 | ChallengeAlgorithm.Argon2id;
|
||||
strategy: ChallengeStrategy.LeadingZeroes;
|
||||
salt: string;
|
||||
difficulty: number;
|
||||
}
|
||||
|
||||
// interface WorkerChallengeLeadingZeroesSolveRequest extends ChallengeLeadingZeroesSolveRequest {
|
||||
// type: WorkerMessageType.Challenge;
|
||||
// }
|
||||
interface WorkerChallengeLeadingZeroesSolveRequest extends ChallengeLeadingZeroesSolveRequest {
|
||||
type: WorkerMessageType.Challenge;
|
||||
}
|
||||
|
||||
// interface ChallengeTargetNumberSolveRequest {
|
||||
// strategy: ChallengeStrategy.TargetNumber;
|
||||
// target: string;
|
||||
// salt: string;
|
||||
// }
|
||||
interface ChallengeTargetNumberSolveRequest {
|
||||
algorithm: ChallengeAlgorithm.SHA256 | ChallengeAlgorithm.Argon2id;
|
||||
strategy: ChallengeStrategy.TargetNumber;
|
||||
target: string;
|
||||
salt: string;
|
||||
}
|
||||
|
||||
// interface WorkerChallengeTargetNumberSolveRequest extends ChallengeTargetNumberSolveRequest {
|
||||
// type: WorkerMessageType.Challenge;
|
||||
// }
|
||||
interface WorkerChallengeTargetNumberSolveRequest extends ChallengeTargetNumberSolveRequest {
|
||||
type: WorkerMessageType.Challenge;
|
||||
}
|
||||
|
||||
interface ChallengekCTFSolveRequest {
|
||||
strategy: ChallengeStrategy.kCTF;
|
||||
challenge: string;
|
||||
algorithm: ChallengeAlgorithm.kCTF;
|
||||
salt: string;
|
||||
difficulty: number;
|
||||
}
|
||||
|
||||
interface WorkerChallengekCTFSolveRequest extends ChallengekCTFSolveRequest {
|
||||
type: WorkerMessageType.Challenge;
|
||||
}
|
||||
|
||||
export type ChallengeSolveRequest = ChallengekCTFSolveRequest;
|
||||
type WorkerChallengeSolveRequest = WorkerChallengekCTFSolveRequest;
|
||||
export type ChallengeSolveRequest = ChallengekCTFSolveRequest | ChallengeLeadingZeroesSolveRequest | ChallengeTargetNumberSolveRequest;
|
||||
type WorkerChallengeSolveRequest = WorkerChallengekCTFSolveRequest | WorkerChallengeLeadingZeroesSolveRequest | WorkerChallengeTargetNumberSolveRequest;
|
||||
|
||||
export type WorkerRequest = WorkerInitRequest | WorkerChallengeSolveRequest;
|
||||
|
||||
@@ -59,7 +62,7 @@ interface ErrorMessageResponse {
|
||||
|
||||
interface SolutionMessageResponse {
|
||||
type: WorkerResponseType.Solution;
|
||||
solution: string;
|
||||
solution: string | number;
|
||||
}
|
||||
|
||||
interface InitOkMessageResponse {
|
||||
|
||||
Reference in New Issue
Block a user