"use client"; import { N_ARRAY } from "@/lib/const"; import { UAParser } from "ua-parser-js"; import { useEffect, useState } from "react"; import { computeVdfInWorker } from "@/lib/vdf"; import { FilledButton } from "@/components/ui/Buttons/FilledButton"; let bigintSupported = typeof BigInt !== "undefined"; function generateRandomBigInt(min: bigint, max: bigint) { const range = max - min; const bitLength = range.toString(2).length; const byteLength = Math.ceil(bitLength / 8); const mask = (1n << BigInt(bitLength)) - 1n; let result; do { const randomBytes = new Uint8Array(byteLength); crypto.getRandomValues(randomBytes); result = 0n; for (let i = 0; i < byteLength; i++) { result = (result << 8n) | BigInt(randomBytes[i]); } result = result & mask; } while (result > range); return min + result; } function generateValidG(N: bigint) { if (N <= 4n) throw new Error("N must be > 4"); while (true) { const r = generateRandomBigInt(2n, N - 1n); const g = (r * r) % N; if (g !== 1n && g !== 0n && g !== N - 1n) { return g; } } } export const VDFtestCard = () => { const [browserInfo, setBrowserInfo] = useState(null); const [isBenchmarking, setIsBenchmarking] = useState(false); const [benchmarkResults, setBenchmarkResults] = useState<{ N: bigint; difficulty: bigint; time: number }[]>([]); const [currentProgress, setCurrentProgress] = useState(0); const [currentN, setCurrentN] = useState(null); const [currentDifficulty, setCurrentDifficulty] = useState(null); const [currentTestIndex, setCurrentTestIndex] = useState(0); const difficulties = [BigInt(20000), BigInt(200000)]; const [testCombinations, setTestCombinations] = useState<{ N: bigint; difficulty: bigint }[]>([]); const speedSampleIndex = 1; const [speedSample, setSpeedSample] = useState<{ N: bigint; difficulty: bigint; time: number } | undefined>( undefined ); useEffect(() => { // 创建需要测试的 N 和难度的组合 const combinations: { N: bigint; difficulty: bigint }[] = []; N_ARRAY.forEach((n) => { difficulties.forEach((difficulty) => { combinations.push({ N: n, difficulty }); }); }); setTestCombinations(combinations); const ua = navigator ? navigator.userAgent : ""; const { browser } = UAParser(ua); setBrowserInfo(browser.name + " " + browser.version); }, []); async function startBenchmark() { if (testCombinations.length === 0) { alert("No N values provided in src/const N_ARRAY."); return; } setIsBenchmarking(true); setBenchmarkResults([]); setCurrentTestIndex(0); async function runTest(index: number) { if (index >= testCombinations.length) { setIsBenchmarking(false); setCurrentN(null); setCurrentDifficulty(null); return; } const { N, difficulty } = testCombinations[index]; const g = generateValidG(N); try { const { time } = await computeVdfInWorker(g, N, difficulty, (progress) => { setCurrentProgress(progress); setCurrentN(N); setCurrentDifficulty(difficulty); }); setBenchmarkResults((prevResults) => [...prevResults, { N, difficulty, time }]); setCurrentProgress(0); setCurrentTestIndex((prevIndex) => prevIndex + 1); runTest(index + 1); } catch (error) { setIsBenchmarking(false); setCurrentN(null); setCurrentDifficulty(null); } } runTest(0); } function getAccumulatedTime() { return benchmarkResults.reduce((acc, result) => acc + result.time, 0); } function calculateSpeed() { const sample = benchmarkResults[speedSampleIndex]; if (!sample) return 0; return (Number(sample.difficulty) / sample.time) * 1000; } useEffect(() => { if (benchmarkResults.length > speedSampleIndex) { setSpeedSample(benchmarkResults[speedSampleIndex]); } }, [benchmarkResults]); return (

VDF 基准测试

{!bigintSupported ? (

⚠️ 您的浏览器不支持 BigInt,无法运行基准测试。

) : !isBenchmarking ? ( 开始测试 ) : null} {isBenchmarking && ( <>

正在测试: {currentTestIndex + 1}/{testCombinations.length}

{currentN !== null && currentDifficulty !== null && ( <>

密钥长度: {currentN.toString(2).length} 比特

难度: {currentDifficulty.toLocaleString()}

)} )} {benchmarkResults.length > 0 && !isBenchmarking && ( <>

测试结果

测试在 {(getAccumulatedTime() / 1000).toFixed(3)} 秒内完成.
速度: {Math.round(calculateSpeed()).toLocaleString()} 迭代 / 秒.
速度是在 N = {speedSample?.N.toString(2).length} bits, T = {speedSample?.difficulty}{" "} 的测试中测量的.
{browserInfo && <>浏览器版本:{browserInfo}}

{benchmarkResults.map((result) => ( ))}
耗时 (ms) N (bits) T (迭代)
{result.time.toFixed(2)} {result.N.toString(2).length} {Number(result.difficulty)}
)}
); };