├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── build.rs ├── examples ├── benckmark.rs ├── blockchain_val.rs └── prepare_blockchain.py ├── gfx └── screenshot.png ├── kernel ├── Cargo.lock ├── Cargo.toml └── src │ └── lib.rs ├── rust-toolchain ├── src ├── helpers.rs ├── lib.rs ├── main.rs └── runner.rs └── web └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | **.pdf 2 | 3 | *.swp 4 | *.swo 5 | 6 | **/target 7 | 8 | **.csv 9 | 10 | bitcoin 11 | 12 | releases 13 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "ahash" 22 | version = "0.7.7" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" 25 | dependencies = [ 26 | "getrandom", 27 | "once_cell", 28 | "version_check", 29 | ] 30 | 31 | [[package]] 32 | name = "ahash" 33 | version = "0.8.6" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" 36 | dependencies = [ 37 | "cfg-if", 38 | "once_cell", 39 | "version_check", 40 | "zerocopy", 41 | ] 42 | 43 | [[package]] 44 | name = "aho-corasick" 45 | version = "1.1.2" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 48 | dependencies = [ 49 | "memchr", 50 | ] 51 | 52 | [[package]] 53 | name = "allocator-api2" 54 | version = "0.2.16" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" 57 | 58 | [[package]] 59 | name = "android_system_properties" 60 | version = "0.1.5" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 63 | dependencies = [ 64 | "libc", 65 | ] 66 | 67 | [[package]] 68 | name = "anstream" 69 | version = "0.6.5" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" 72 | dependencies = [ 73 | "anstyle", 74 | "anstyle-parse", 75 | "anstyle-query", 76 | "anstyle-wincon", 77 | "colorchoice", 78 | "utf8parse", 79 | ] 80 | 81 | [[package]] 82 | name = "anstyle" 83 | version = "1.0.4" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 86 | 87 | [[package]] 88 | name = "anstyle-parse" 89 | version = "0.2.3" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 92 | dependencies = [ 93 | "utf8parse", 94 | ] 95 | 96 | [[package]] 97 | name = "anstyle-query" 98 | version = "1.0.2" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 101 | dependencies = [ 102 | "windows-sys 0.52.0", 103 | ] 104 | 105 | [[package]] 106 | name = "anstyle-wincon" 107 | version = "3.0.2" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 110 | dependencies = [ 111 | "anstyle", 112 | "windows-sys 0.52.0", 113 | ] 114 | 115 | [[package]] 116 | name = "ar" 117 | version = "0.9.0" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69" 120 | 121 | [[package]] 122 | name = "arrayvec" 123 | version = "0.7.4" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 126 | 127 | [[package]] 128 | name = "ash" 129 | version = "0.37.3+1.3.251" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" 132 | dependencies = [ 133 | "libloading 0.7.4", 134 | ] 135 | 136 | [[package]] 137 | name = "autocfg" 138 | version = "1.1.0" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 141 | 142 | [[package]] 143 | name = "backtrace" 144 | version = "0.3.69" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 147 | dependencies = [ 148 | "addr2line", 149 | "cc", 150 | "cfg-if", 151 | "libc", 152 | "miniz_oxide", 153 | "object", 154 | "rustc-demangle", 155 | ] 156 | 157 | [[package]] 158 | name = "bit-set" 159 | version = "0.5.3" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" 162 | dependencies = [ 163 | "bit-vec", 164 | ] 165 | 166 | [[package]] 167 | name = "bit-vec" 168 | version = "0.6.3" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" 171 | 172 | [[package]] 173 | name = "bitflags" 174 | version = "1.3.2" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 177 | 178 | [[package]] 179 | name = "bitflags" 180 | version = "2.4.1" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" 183 | 184 | [[package]] 185 | name = "block" 186 | version = "0.1.6" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 189 | 190 | [[package]] 191 | name = "bumpalo" 192 | version = "3.14.0" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" 195 | 196 | [[package]] 197 | name = "bytemuck" 198 | version = "1.14.0" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" 201 | 202 | [[package]] 203 | name = "byteorder" 204 | version = "1.5.0" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 207 | 208 | [[package]] 209 | name = "cc" 210 | version = "1.0.83" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 213 | dependencies = [ 214 | "jobserver", 215 | "libc", 216 | ] 217 | 218 | [[package]] 219 | name = "cfg-if" 220 | version = "1.0.0" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 223 | 224 | [[package]] 225 | name = "clap" 226 | version = "4.4.11" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" 229 | dependencies = [ 230 | "clap_builder", 231 | "clap_derive", 232 | ] 233 | 234 | [[package]] 235 | name = "clap_builder" 236 | version = "4.4.11" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" 239 | dependencies = [ 240 | "anstream", 241 | "anstyle", 242 | "clap_lex", 243 | "strsim", 244 | ] 245 | 246 | [[package]] 247 | name = "clap_derive" 248 | version = "4.4.7" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 251 | dependencies = [ 252 | "heck", 253 | "proc-macro2", 254 | "quote", 255 | "syn 2.0.43", 256 | ] 257 | 258 | [[package]] 259 | name = "clap_lex" 260 | version = "0.6.0" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 263 | 264 | [[package]] 265 | name = "codespan-reporting" 266 | version = "0.11.1" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 269 | dependencies = [ 270 | "termcolor", 271 | "unicode-width", 272 | ] 273 | 274 | [[package]] 275 | name = "colorchoice" 276 | version = "1.0.0" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 279 | 280 | [[package]] 281 | name = "com-rs" 282 | version = "0.2.1" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "bf43edc576402991846b093a7ca18a3477e0ef9c588cde84964b5d3e43016642" 285 | 286 | [[package]] 287 | name = "console_error_panic_hook" 288 | version = "0.1.7" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" 291 | dependencies = [ 292 | "cfg-if", 293 | "wasm-bindgen", 294 | ] 295 | 296 | [[package]] 297 | name = "console_log" 298 | version = "1.0.0" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f" 301 | dependencies = [ 302 | "log", 303 | "web-sys", 304 | ] 305 | 306 | [[package]] 307 | name = "convert_case" 308 | version = "0.4.0" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 311 | 312 | [[package]] 313 | name = "core-foundation" 314 | version = "0.9.4" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 317 | dependencies = [ 318 | "core-foundation-sys", 319 | "libc", 320 | ] 321 | 322 | [[package]] 323 | name = "core-foundation-sys" 324 | version = "0.8.6" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 327 | 328 | [[package]] 329 | name = "core-graphics-types" 330 | version = "0.1.3" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" 333 | dependencies = [ 334 | "bitflags 1.3.2", 335 | "core-foundation", 336 | "libc", 337 | ] 338 | 339 | [[package]] 340 | name = "csv" 341 | version = "1.3.0" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" 344 | dependencies = [ 345 | "csv-core", 346 | "itoa", 347 | "ryu", 348 | "serde", 349 | ] 350 | 351 | [[package]] 352 | name = "csv-core" 353 | version = "0.1.11" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" 356 | dependencies = [ 357 | "memchr", 358 | ] 359 | 360 | [[package]] 361 | name = "d3d12" 362 | version = "0.7.0" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "e16e44ab292b1dddfdaf7be62cfd8877df52f2f3fde5858d95bab606be259f20" 365 | dependencies = [ 366 | "bitflags 2.4.1", 367 | "libloading 0.8.1", 368 | "winapi", 369 | ] 370 | 371 | [[package]] 372 | name = "derive_more" 373 | version = "0.99.17" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 376 | dependencies = [ 377 | "convert_case", 378 | "proc-macro2", 379 | "quote", 380 | "rustc_version", 381 | "syn 1.0.109", 382 | ] 383 | 384 | [[package]] 385 | name = "either" 386 | version = "1.9.0" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" 389 | 390 | [[package]] 391 | name = "elsa" 392 | version = "1.10.0" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "d98e71ae4df57d214182a2e5cb90230c0192c6ddfcaa05c36453d46a54713e10" 395 | dependencies = [ 396 | "indexmap 2.1.0", 397 | "stable_deref_trait", 398 | ] 399 | 400 | [[package]] 401 | name = "equivalent" 402 | version = "1.0.1" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 405 | 406 | [[package]] 407 | name = "errno" 408 | version = "0.3.8" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 411 | dependencies = [ 412 | "libc", 413 | "windows-sys 0.52.0", 414 | ] 415 | 416 | [[package]] 417 | name = "fastrand" 418 | version = "2.0.1" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 421 | 422 | [[package]] 423 | name = "fixedbitset" 424 | version = "0.4.2" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 427 | 428 | [[package]] 429 | name = "flume" 430 | version = "0.11.0" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" 433 | dependencies = [ 434 | "futures-core", 435 | "futures-sink", 436 | "nanorand", 437 | "spin", 438 | ] 439 | 440 | [[package]] 441 | name = "foreign-types" 442 | version = "0.5.0" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" 445 | dependencies = [ 446 | "foreign-types-macros", 447 | "foreign-types-shared", 448 | ] 449 | 450 | [[package]] 451 | name = "foreign-types-macros" 452 | version = "0.2.3" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" 455 | dependencies = [ 456 | "proc-macro2", 457 | "quote", 458 | "syn 2.0.43", 459 | ] 460 | 461 | [[package]] 462 | name = "foreign-types-shared" 463 | version = "0.3.1" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" 466 | 467 | [[package]] 468 | name = "futures" 469 | version = "0.3.30" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" 472 | dependencies = [ 473 | "futures-channel", 474 | "futures-core", 475 | "futures-executor", 476 | "futures-io", 477 | "futures-sink", 478 | "futures-task", 479 | "futures-util", 480 | ] 481 | 482 | [[package]] 483 | name = "futures-channel" 484 | version = "0.3.30" 485 | source = "registry+https://github.com/rust-lang/crates.io-index" 486 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 487 | dependencies = [ 488 | "futures-core", 489 | "futures-sink", 490 | ] 491 | 492 | [[package]] 493 | name = "futures-core" 494 | version = "0.3.30" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 497 | 498 | [[package]] 499 | name = "futures-executor" 500 | version = "0.3.30" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" 503 | dependencies = [ 504 | "futures-core", 505 | "futures-task", 506 | "futures-util", 507 | ] 508 | 509 | [[package]] 510 | name = "futures-io" 511 | version = "0.3.30" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 514 | 515 | [[package]] 516 | name = "futures-macro" 517 | version = "0.3.30" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 520 | dependencies = [ 521 | "proc-macro2", 522 | "quote", 523 | "syn 2.0.43", 524 | ] 525 | 526 | [[package]] 527 | name = "futures-sink" 528 | version = "0.3.30" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 531 | 532 | [[package]] 533 | name = "futures-task" 534 | version = "0.3.30" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 537 | 538 | [[package]] 539 | name = "futures-util" 540 | version = "0.3.30" 541 | source = "registry+https://github.com/rust-lang/crates.io-index" 542 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 543 | dependencies = [ 544 | "futures-channel", 545 | "futures-core", 546 | "futures-io", 547 | "futures-macro", 548 | "futures-sink", 549 | "futures-task", 550 | "memchr", 551 | "pin-project-lite", 552 | "pin-utils", 553 | "slab", 554 | ] 555 | 556 | [[package]] 557 | name = "fxhash" 558 | version = "0.2.1" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 561 | dependencies = [ 562 | "byteorder", 563 | ] 564 | 565 | [[package]] 566 | name = "getrandom" 567 | version = "0.2.11" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" 570 | dependencies = [ 571 | "cfg-if", 572 | "js-sys", 573 | "libc", 574 | "wasi", 575 | "wasm-bindgen", 576 | ] 577 | 578 | [[package]] 579 | name = "gimli" 580 | version = "0.28.1" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 583 | 584 | [[package]] 585 | name = "gl_generator" 586 | version = "0.14.0" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" 589 | dependencies = [ 590 | "khronos_api", 591 | "log", 592 | "xml-rs", 593 | ] 594 | 595 | [[package]] 596 | name = "glow" 597 | version = "0.13.0" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "886c2a30b160c4c6fec8f987430c26b526b7988ca71f664e6a699ddf6f9601e4" 600 | dependencies = [ 601 | "js-sys", 602 | "slotmap", 603 | "wasm-bindgen", 604 | "web-sys", 605 | ] 606 | 607 | [[package]] 608 | name = "glutin_wgl_sys" 609 | version = "0.5.0" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" 612 | dependencies = [ 613 | "gl_generator", 614 | ] 615 | 616 | [[package]] 617 | name = "gpu-alloc" 618 | version = "0.6.0" 619 | source = "registry+https://github.com/rust-lang/crates.io-index" 620 | checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" 621 | dependencies = [ 622 | "bitflags 2.4.1", 623 | "gpu-alloc-types", 624 | ] 625 | 626 | [[package]] 627 | name = "gpu-alloc-types" 628 | version = "0.3.0" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" 631 | dependencies = [ 632 | "bitflags 2.4.1", 633 | ] 634 | 635 | [[package]] 636 | name = "gpu-allocator" 637 | version = "0.23.0" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "40fe17c8a05d60c38c0a4e5a3c802f2f1ceb66b76c67d96ffb34bef0475a7fad" 640 | dependencies = [ 641 | "backtrace", 642 | "log", 643 | "presser", 644 | "thiserror", 645 | "winapi", 646 | "windows", 647 | ] 648 | 649 | [[package]] 650 | name = "gpu-descriptor" 651 | version = "0.2.4" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" 654 | dependencies = [ 655 | "bitflags 2.4.1", 656 | "gpu-descriptor-types", 657 | "hashbrown 0.14.3", 658 | ] 659 | 660 | [[package]] 661 | name = "gpu-descriptor-types" 662 | version = "0.1.2" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" 665 | dependencies = [ 666 | "bitflags 2.4.1", 667 | ] 668 | 669 | [[package]] 670 | name = "hashbrown" 671 | version = "0.11.2" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 674 | dependencies = [ 675 | "ahash 0.7.7", 676 | ] 677 | 678 | [[package]] 679 | name = "hashbrown" 680 | version = "0.12.3" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 683 | 684 | [[package]] 685 | name = "hashbrown" 686 | version = "0.14.3" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 689 | dependencies = [ 690 | "ahash 0.8.6", 691 | "allocator-api2", 692 | ] 693 | 694 | [[package]] 695 | name = "hassle-rs" 696 | version = "0.10.0" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "1397650ee315e8891a0df210707f0fc61771b0cc518c3023896064c5407cb3b0" 699 | dependencies = [ 700 | "bitflags 1.3.2", 701 | "com-rs", 702 | "libc", 703 | "libloading 0.7.4", 704 | "thiserror", 705 | "widestring", 706 | "winapi", 707 | ] 708 | 709 | [[package]] 710 | name = "heck" 711 | version = "0.4.1" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 714 | 715 | [[package]] 716 | name = "hex" 717 | version = "0.4.3" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 720 | 721 | [[package]] 722 | name = "hexf-parse" 723 | version = "0.2.1" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" 726 | 727 | [[package]] 728 | name = "indexmap" 729 | version = "1.9.3" 730 | source = "registry+https://github.com/rust-lang/crates.io-index" 731 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 732 | dependencies = [ 733 | "autocfg", 734 | "hashbrown 0.12.3", 735 | ] 736 | 737 | [[package]] 738 | name = "indexmap" 739 | version = "2.1.0" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" 742 | dependencies = [ 743 | "equivalent", 744 | "hashbrown 0.14.3", 745 | ] 746 | 747 | [[package]] 748 | name = "internal-iterator" 749 | version = "0.2.3" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | checksum = "969ee3fc68ec2e88eb21434ce4d9b7e1600d1ce92ff974560a6c4a304f5124b9" 752 | 753 | [[package]] 754 | name = "itertools" 755 | version = "0.10.5" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 758 | dependencies = [ 759 | "either", 760 | ] 761 | 762 | [[package]] 763 | name = "itoa" 764 | version = "1.0.10" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 767 | 768 | [[package]] 769 | name = "jobserver" 770 | version = "0.1.27" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" 773 | dependencies = [ 774 | "libc", 775 | ] 776 | 777 | [[package]] 778 | name = "js-sys" 779 | version = "0.3.66" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" 782 | dependencies = [ 783 | "wasm-bindgen", 784 | ] 785 | 786 | [[package]] 787 | name = "khronos-egl" 788 | version = "6.0.0" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" 791 | dependencies = [ 792 | "libc", 793 | "libloading 0.8.1", 794 | "pkg-config", 795 | ] 796 | 797 | [[package]] 798 | name = "khronos_api" 799 | version = "3.1.0" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" 802 | 803 | [[package]] 804 | name = "lazy_static" 805 | version = "1.4.0" 806 | source = "registry+https://github.com/rust-lang/crates.io-index" 807 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 808 | 809 | [[package]] 810 | name = "libc" 811 | version = "0.2.151" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" 814 | 815 | [[package]] 816 | name = "libloading" 817 | version = "0.7.4" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" 820 | dependencies = [ 821 | "cfg-if", 822 | "winapi", 823 | ] 824 | 825 | [[package]] 826 | name = "libloading" 827 | version = "0.8.1" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" 830 | dependencies = [ 831 | "cfg-if", 832 | "windows-sys 0.48.0", 833 | ] 834 | 835 | [[package]] 836 | name = "libm" 837 | version = "0.2.8" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" 840 | 841 | [[package]] 842 | name = "linux-raw-sys" 843 | version = "0.4.12" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" 846 | 847 | [[package]] 848 | name = "lock_api" 849 | version = "0.4.11" 850 | source = "registry+https://github.com/rust-lang/crates.io-index" 851 | checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 852 | dependencies = [ 853 | "autocfg", 854 | "scopeguard", 855 | ] 856 | 857 | [[package]] 858 | name = "log" 859 | version = "0.4.20" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 862 | 863 | [[package]] 864 | name = "longest-increasing-subsequence" 865 | version = "0.1.0" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" 868 | 869 | [[package]] 870 | name = "malloc_buf" 871 | version = "0.0.6" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 874 | dependencies = [ 875 | "libc", 876 | ] 877 | 878 | [[package]] 879 | name = "memchr" 880 | version = "2.6.4" 881 | source = "registry+https://github.com/rust-lang/crates.io-index" 882 | checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" 883 | 884 | [[package]] 885 | name = "metal" 886 | version = "0.27.0" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" 889 | dependencies = [ 890 | "bitflags 2.4.1", 891 | "block", 892 | "core-graphics-types", 893 | "foreign-types", 894 | "log", 895 | "objc", 896 | "paste", 897 | ] 898 | 899 | [[package]] 900 | name = "miniz_oxide" 901 | version = "0.7.1" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 904 | dependencies = [ 905 | "adler", 906 | ] 907 | 908 | [[package]] 909 | name = "naga" 910 | version = "0.14.2" 911 | source = "registry+https://github.com/rust-lang/crates.io-index" 912 | checksum = "ae585df4b6514cf8842ac0f1ab4992edc975892704835b549cf818dc0191249e" 913 | dependencies = [ 914 | "bit-set", 915 | "bitflags 2.4.1", 916 | "codespan-reporting", 917 | "hexf-parse", 918 | "indexmap 2.1.0", 919 | "log", 920 | "num-traits", 921 | "petgraph", 922 | "rustc-hash", 923 | "spirv", 924 | "termcolor", 925 | "thiserror", 926 | "unicode-xid", 927 | ] 928 | 929 | [[package]] 930 | name = "nanorand" 931 | version = "0.7.0" 932 | source = "registry+https://github.com/rust-lang/crates.io-index" 933 | checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" 934 | dependencies = [ 935 | "getrandom", 936 | ] 937 | 938 | [[package]] 939 | name = "num-traits" 940 | version = "0.2.17" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 943 | dependencies = [ 944 | "autocfg", 945 | "libm", 946 | ] 947 | 948 | [[package]] 949 | name = "objc" 950 | version = "0.2.7" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 953 | dependencies = [ 954 | "malloc_buf", 955 | "objc_exception", 956 | ] 957 | 958 | [[package]] 959 | name = "objc_exception" 960 | version = "0.1.2" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" 963 | dependencies = [ 964 | "cc", 965 | ] 966 | 967 | [[package]] 968 | name = "object" 969 | version = "0.32.2" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 972 | dependencies = [ 973 | "memchr", 974 | ] 975 | 976 | [[package]] 977 | name = "once_cell" 978 | version = "1.19.0" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 981 | 982 | [[package]] 983 | name = "parking_lot" 984 | version = "0.12.1" 985 | source = "registry+https://github.com/rust-lang/crates.io-index" 986 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 987 | dependencies = [ 988 | "lock_api", 989 | "parking_lot_core", 990 | ] 991 | 992 | [[package]] 993 | name = "parking_lot_core" 994 | version = "0.9.9" 995 | source = "registry+https://github.com/rust-lang/crates.io-index" 996 | checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" 997 | dependencies = [ 998 | "cfg-if", 999 | "libc", 1000 | "redox_syscall", 1001 | "smallvec", 1002 | "windows-targets 0.48.5", 1003 | ] 1004 | 1005 | [[package]] 1006 | name = "paste" 1007 | version = "1.0.14" 1008 | source = "registry+https://github.com/rust-lang/crates.io-index" 1009 | checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" 1010 | 1011 | [[package]] 1012 | name = "petgraph" 1013 | version = "0.6.4" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" 1016 | dependencies = [ 1017 | "fixedbitset", 1018 | "indexmap 2.1.0", 1019 | ] 1020 | 1021 | [[package]] 1022 | name = "pin-project-lite" 1023 | version = "0.2.13" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1026 | 1027 | [[package]] 1028 | name = "pin-utils" 1029 | version = "0.1.0" 1030 | source = "registry+https://github.com/rust-lang/crates.io-index" 1031 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1032 | 1033 | [[package]] 1034 | name = "pkg-config" 1035 | version = "0.3.28" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" 1038 | 1039 | [[package]] 1040 | name = "ppv-lite86" 1041 | version = "0.2.17" 1042 | source = "registry+https://github.com/rust-lang/crates.io-index" 1043 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1044 | 1045 | [[package]] 1046 | name = "presser" 1047 | version = "0.3.1" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" 1050 | 1051 | [[package]] 1052 | name = "proc-macro2" 1053 | version = "1.0.71" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" 1056 | dependencies = [ 1057 | "unicode-ident", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "profiling" 1062 | version = "1.0.13" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "d135ede8821cf6376eb7a64148901e1690b788c11ae94dc297ae917dbc91dc0e" 1065 | 1066 | [[package]] 1067 | name = "quote" 1068 | version = "1.0.33" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 1071 | dependencies = [ 1072 | "proc-macro2", 1073 | ] 1074 | 1075 | [[package]] 1076 | name = "rand" 1077 | version = "0.8.5" 1078 | source = "registry+https://github.com/rust-lang/crates.io-index" 1079 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1080 | dependencies = [ 1081 | "libc", 1082 | "rand_chacha", 1083 | "rand_core", 1084 | ] 1085 | 1086 | [[package]] 1087 | name = "rand_chacha" 1088 | version = "0.3.1" 1089 | source = "registry+https://github.com/rust-lang/crates.io-index" 1090 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1091 | dependencies = [ 1092 | "ppv-lite86", 1093 | "rand_core", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "rand_core" 1098 | version = "0.6.4" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1101 | dependencies = [ 1102 | "getrandom", 1103 | ] 1104 | 1105 | [[package]] 1106 | name = "range-alloc" 1107 | version = "0.1.3" 1108 | source = "registry+https://github.com/rust-lang/crates.io-index" 1109 | checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" 1110 | 1111 | [[package]] 1112 | name = "raw-string" 1113 | version = "0.3.5" 1114 | source = "registry+https://github.com/rust-lang/crates.io-index" 1115 | checksum = "e0501e134c6905fee1f10fed25b0a7e1261bf676cffac9543a7d0730dec01af2" 1116 | 1117 | [[package]] 1118 | name = "raw-window-handle" 1119 | version = "0.5.2" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" 1122 | 1123 | [[package]] 1124 | name = "redox_syscall" 1125 | version = "0.4.1" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 1128 | dependencies = [ 1129 | "bitflags 1.3.2", 1130 | ] 1131 | 1132 | [[package]] 1133 | name = "regex" 1134 | version = "1.10.2" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" 1137 | dependencies = [ 1138 | "aho-corasick", 1139 | "memchr", 1140 | "regex-automata", 1141 | "regex-syntax", 1142 | ] 1143 | 1144 | [[package]] 1145 | name = "regex-automata" 1146 | version = "0.4.3" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" 1149 | dependencies = [ 1150 | "aho-corasick", 1151 | "memchr", 1152 | "regex-syntax", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "regex-syntax" 1157 | version = "0.8.2" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 1160 | 1161 | [[package]] 1162 | name = "renderdoc-sys" 1163 | version = "1.0.0" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b" 1166 | 1167 | [[package]] 1168 | name = "rspirv" 1169 | version = "0.11.0+1.5.4" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "1503993b59ca9ae4127365c3293517576d7ce56be9f3d8abb1625c85ddc583ba" 1172 | dependencies = [ 1173 | "fxhash", 1174 | "num-traits", 1175 | "spirv", 1176 | ] 1177 | 1178 | [[package]] 1179 | name = "rustc-demangle" 1180 | version = "0.1.23" 1181 | source = "registry+https://github.com/rust-lang/crates.io-index" 1182 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1183 | 1184 | [[package]] 1185 | name = "rustc-hash" 1186 | version = "1.1.0" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1189 | 1190 | [[package]] 1191 | name = "rustc_codegen_spirv" 1192 | version = "0.9.0" 1193 | source = "registry+https://github.com/rust-lang/crates.io-index" 1194 | checksum = "00f05d43c1d9ef3b0e5e2be3dcc9025e5ed103f99c36bb29a1b396386bd032ce" 1195 | dependencies = [ 1196 | "ar", 1197 | "either", 1198 | "hashbrown 0.11.2", 1199 | "indexmap 1.9.3", 1200 | "itertools", 1201 | "lazy_static", 1202 | "libc", 1203 | "num-traits", 1204 | "once_cell", 1205 | "regex", 1206 | "rspirv", 1207 | "rustc-demangle", 1208 | "rustc_codegen_spirv-types", 1209 | "sanitize-filename", 1210 | "serde", 1211 | "serde_json", 1212 | "smallvec", 1213 | "spirt", 1214 | "spirv-tools", 1215 | "syn 1.0.109", 1216 | ] 1217 | 1218 | [[package]] 1219 | name = "rustc_codegen_spirv-types" 1220 | version = "0.9.0" 1221 | source = "registry+https://github.com/rust-lang/crates.io-index" 1222 | checksum = "13333711bd68d2a02617c2093fa6535ae40024fef610c37e6826d1ea77e97710" 1223 | dependencies = [ 1224 | "rspirv", 1225 | "serde", 1226 | ] 1227 | 1228 | [[package]] 1229 | name = "rustc_version" 1230 | version = "0.4.0" 1231 | source = "registry+https://github.com/rust-lang/crates.io-index" 1232 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1233 | dependencies = [ 1234 | "semver", 1235 | ] 1236 | 1237 | [[package]] 1238 | name = "rustix" 1239 | version = "0.38.28" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" 1242 | dependencies = [ 1243 | "bitflags 2.4.1", 1244 | "errno", 1245 | "libc", 1246 | "linux-raw-sys", 1247 | "windows-sys 0.52.0", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "ryu" 1252 | version = "1.0.16" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" 1255 | 1256 | [[package]] 1257 | name = "sanitize-filename" 1258 | version = "0.4.0" 1259 | source = "registry+https://github.com/rust-lang/crates.io-index" 1260 | checksum = "08c502bdb638f1396509467cb0580ef3b29aa2a45c5d43e5d84928241280296c" 1261 | dependencies = [ 1262 | "lazy_static", 1263 | "regex", 1264 | ] 1265 | 1266 | [[package]] 1267 | name = "scopeguard" 1268 | version = "1.2.0" 1269 | source = "registry+https://github.com/rust-lang/crates.io-index" 1270 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1271 | 1272 | [[package]] 1273 | name = "semver" 1274 | version = "1.0.20" 1275 | source = "registry+https://github.com/rust-lang/crates.io-index" 1276 | checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" 1277 | 1278 | [[package]] 1279 | name = "serde" 1280 | version = "1.0.193" 1281 | source = "registry+https://github.com/rust-lang/crates.io-index" 1282 | checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" 1283 | dependencies = [ 1284 | "serde_derive", 1285 | ] 1286 | 1287 | [[package]] 1288 | name = "serde_derive" 1289 | version = "1.0.193" 1290 | source = "registry+https://github.com/rust-lang/crates.io-index" 1291 | checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" 1292 | dependencies = [ 1293 | "proc-macro2", 1294 | "quote", 1295 | "syn 2.0.43", 1296 | ] 1297 | 1298 | [[package]] 1299 | name = "serde_json" 1300 | version = "1.0.108" 1301 | source = "registry+https://github.com/rust-lang/crates.io-index" 1302 | checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" 1303 | dependencies = [ 1304 | "itoa", 1305 | "ryu", 1306 | "serde", 1307 | ] 1308 | 1309 | [[package]] 1310 | name = "sha256_rgpu" 1311 | version = "0.2.0" 1312 | dependencies = [ 1313 | "bytemuck", 1314 | "clap", 1315 | "console_error_panic_hook", 1316 | "console_log", 1317 | "csv", 1318 | "flume", 1319 | "futures", 1320 | "hex", 1321 | "log", 1322 | "rand", 1323 | "spirv-builder", 1324 | "wasm-bindgen", 1325 | "wasm-bindgen-futures", 1326 | "web-sys", 1327 | "wgpu", 1328 | ] 1329 | 1330 | [[package]] 1331 | name = "slab" 1332 | version = "0.4.9" 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" 1334 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1335 | dependencies = [ 1336 | "autocfg", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "slotmap" 1341 | version = "1.0.7" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" 1344 | dependencies = [ 1345 | "version_check", 1346 | ] 1347 | 1348 | [[package]] 1349 | name = "smallvec" 1350 | version = "1.11.2" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" 1353 | dependencies = [ 1354 | "serde", 1355 | ] 1356 | 1357 | [[package]] 1358 | name = "spin" 1359 | version = "0.9.8" 1360 | source = "registry+https://github.com/rust-lang/crates.io-index" 1361 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1362 | dependencies = [ 1363 | "lock_api", 1364 | ] 1365 | 1366 | [[package]] 1367 | name = "spirt" 1368 | version = "0.3.0" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "64e1f7903720ff818d6da824edf2c4082c6e7a029a99317fd10c39dd7c40c7ff" 1371 | dependencies = [ 1372 | "arrayvec", 1373 | "bytemuck", 1374 | "derive_more", 1375 | "elsa", 1376 | "indexmap 1.9.3", 1377 | "internal-iterator", 1378 | "itertools", 1379 | "lazy_static", 1380 | "longest-increasing-subsequence", 1381 | "rustc-hash", 1382 | "serde", 1383 | "serde_json", 1384 | "smallvec", 1385 | ] 1386 | 1387 | [[package]] 1388 | name = "spirv" 1389 | version = "0.2.0+1.5.4" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" 1392 | dependencies = [ 1393 | "bitflags 1.3.2", 1394 | "num-traits", 1395 | ] 1396 | 1397 | [[package]] 1398 | name = "spirv-builder" 1399 | version = "0.9.0" 1400 | source = "registry+https://github.com/rust-lang/crates.io-index" 1401 | checksum = "8ee97a4472a73b2f6adc911468b16405fa5b732f510e5ae11a33a914f36fe5ad" 1402 | dependencies = [ 1403 | "memchr", 1404 | "raw-string", 1405 | "rustc_codegen_spirv", 1406 | "rustc_codegen_spirv-types", 1407 | "serde", 1408 | "serde_json", 1409 | ] 1410 | 1411 | [[package]] 1412 | name = "spirv-tools" 1413 | version = "0.9.0" 1414 | source = "registry+https://github.com/rust-lang/crates.io-index" 1415 | checksum = "dc7c8ca2077515286505bd3ccd396e55ac5706e80322e1d6d22a82e1cad4f7c3" 1416 | dependencies = [ 1417 | "memchr", 1418 | "spirv-tools-sys", 1419 | "tempfile", 1420 | ] 1421 | 1422 | [[package]] 1423 | name = "spirv-tools-sys" 1424 | version = "0.7.0" 1425 | source = "registry+https://github.com/rust-lang/crates.io-index" 1426 | checksum = "b4b32d9d6469cd6b50dcd6bd841204b5946b4fb7b70a97872717cdc417659c9a" 1427 | dependencies = [ 1428 | "cc", 1429 | ] 1430 | 1431 | [[package]] 1432 | name = "stable_deref_trait" 1433 | version = "1.2.0" 1434 | source = "registry+https://github.com/rust-lang/crates.io-index" 1435 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1436 | 1437 | [[package]] 1438 | name = "static_assertions" 1439 | version = "1.1.0" 1440 | source = "registry+https://github.com/rust-lang/crates.io-index" 1441 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1442 | 1443 | [[package]] 1444 | name = "strsim" 1445 | version = "0.10.0" 1446 | source = "registry+https://github.com/rust-lang/crates.io-index" 1447 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1448 | 1449 | [[package]] 1450 | name = "syn" 1451 | version = "1.0.109" 1452 | source = "registry+https://github.com/rust-lang/crates.io-index" 1453 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1454 | dependencies = [ 1455 | "proc-macro2", 1456 | "quote", 1457 | "unicode-ident", 1458 | ] 1459 | 1460 | [[package]] 1461 | name = "syn" 1462 | version = "2.0.43" 1463 | source = "registry+https://github.com/rust-lang/crates.io-index" 1464 | checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" 1465 | dependencies = [ 1466 | "proc-macro2", 1467 | "quote", 1468 | "unicode-ident", 1469 | ] 1470 | 1471 | [[package]] 1472 | name = "tempfile" 1473 | version = "3.8.1" 1474 | source = "registry+https://github.com/rust-lang/crates.io-index" 1475 | checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" 1476 | dependencies = [ 1477 | "cfg-if", 1478 | "fastrand", 1479 | "redox_syscall", 1480 | "rustix", 1481 | "windows-sys 0.48.0", 1482 | ] 1483 | 1484 | [[package]] 1485 | name = "termcolor" 1486 | version = "1.4.0" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" 1489 | dependencies = [ 1490 | "winapi-util", 1491 | ] 1492 | 1493 | [[package]] 1494 | name = "thiserror" 1495 | version = "1.0.52" 1496 | source = "registry+https://github.com/rust-lang/crates.io-index" 1497 | checksum = "83a48fd946b02c0a526b2e9481c8e2a17755e47039164a86c4070446e3a4614d" 1498 | dependencies = [ 1499 | "thiserror-impl", 1500 | ] 1501 | 1502 | [[package]] 1503 | name = "thiserror-impl" 1504 | version = "1.0.52" 1505 | source = "registry+https://github.com/rust-lang/crates.io-index" 1506 | checksum = "e7fbe9b594d6568a6a1443250a7e67d80b74e1e96f6d1715e1e21cc1888291d3" 1507 | dependencies = [ 1508 | "proc-macro2", 1509 | "quote", 1510 | "syn 2.0.43", 1511 | ] 1512 | 1513 | [[package]] 1514 | name = "unicode-ident" 1515 | version = "1.0.12" 1516 | source = "registry+https://github.com/rust-lang/crates.io-index" 1517 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1518 | 1519 | [[package]] 1520 | name = "unicode-width" 1521 | version = "0.1.11" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" 1524 | 1525 | [[package]] 1526 | name = "unicode-xid" 1527 | version = "0.2.4" 1528 | source = "registry+https://github.com/rust-lang/crates.io-index" 1529 | checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" 1530 | 1531 | [[package]] 1532 | name = "utf8parse" 1533 | version = "0.2.1" 1534 | source = "registry+https://github.com/rust-lang/crates.io-index" 1535 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 1536 | 1537 | [[package]] 1538 | name = "version_check" 1539 | version = "0.9.4" 1540 | source = "registry+https://github.com/rust-lang/crates.io-index" 1541 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1542 | 1543 | [[package]] 1544 | name = "wasi" 1545 | version = "0.11.0+wasi-snapshot-preview1" 1546 | source = "registry+https://github.com/rust-lang/crates.io-index" 1547 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1548 | 1549 | [[package]] 1550 | name = "wasm-bindgen" 1551 | version = "0.2.89" 1552 | source = "registry+https://github.com/rust-lang/crates.io-index" 1553 | checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" 1554 | dependencies = [ 1555 | "cfg-if", 1556 | "wasm-bindgen-macro", 1557 | ] 1558 | 1559 | [[package]] 1560 | name = "wasm-bindgen-backend" 1561 | version = "0.2.89" 1562 | source = "registry+https://github.com/rust-lang/crates.io-index" 1563 | checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" 1564 | dependencies = [ 1565 | "bumpalo", 1566 | "log", 1567 | "once_cell", 1568 | "proc-macro2", 1569 | "quote", 1570 | "syn 2.0.43", 1571 | "wasm-bindgen-shared", 1572 | ] 1573 | 1574 | [[package]] 1575 | name = "wasm-bindgen-futures" 1576 | version = "0.4.39" 1577 | source = "registry+https://github.com/rust-lang/crates.io-index" 1578 | checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" 1579 | dependencies = [ 1580 | "cfg-if", 1581 | "js-sys", 1582 | "wasm-bindgen", 1583 | "web-sys", 1584 | ] 1585 | 1586 | [[package]] 1587 | name = "wasm-bindgen-macro" 1588 | version = "0.2.89" 1589 | source = "registry+https://github.com/rust-lang/crates.io-index" 1590 | checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" 1591 | dependencies = [ 1592 | "quote", 1593 | "wasm-bindgen-macro-support", 1594 | ] 1595 | 1596 | [[package]] 1597 | name = "wasm-bindgen-macro-support" 1598 | version = "0.2.89" 1599 | source = "registry+https://github.com/rust-lang/crates.io-index" 1600 | checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" 1601 | dependencies = [ 1602 | "proc-macro2", 1603 | "quote", 1604 | "syn 2.0.43", 1605 | "wasm-bindgen-backend", 1606 | "wasm-bindgen-shared", 1607 | ] 1608 | 1609 | [[package]] 1610 | name = "wasm-bindgen-shared" 1611 | version = "0.2.89" 1612 | source = "registry+https://github.com/rust-lang/crates.io-index" 1613 | checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" 1614 | 1615 | [[package]] 1616 | name = "web-sys" 1617 | version = "0.3.64" 1618 | source = "registry+https://github.com/rust-lang/crates.io-index" 1619 | checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" 1620 | dependencies = [ 1621 | "js-sys", 1622 | "wasm-bindgen", 1623 | ] 1624 | 1625 | [[package]] 1626 | name = "wgpu" 1627 | version = "0.18.0" 1628 | source = "registry+https://github.com/rust-lang/crates.io-index" 1629 | checksum = "30e7d227c9f961f2061c26f4cb0fbd4df0ef37e056edd0931783599d6c94ef24" 1630 | dependencies = [ 1631 | "arrayvec", 1632 | "cfg-if", 1633 | "flume", 1634 | "js-sys", 1635 | "log", 1636 | "naga", 1637 | "parking_lot", 1638 | "profiling", 1639 | "raw-window-handle", 1640 | "smallvec", 1641 | "static_assertions", 1642 | "wasm-bindgen", 1643 | "wasm-bindgen-futures", 1644 | "web-sys", 1645 | "wgpu-core", 1646 | "wgpu-hal", 1647 | "wgpu-types", 1648 | ] 1649 | 1650 | [[package]] 1651 | name = "wgpu-core" 1652 | version = "0.18.1" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "ef91c1d62d1e9e81c79e600131a258edf75c9531cbdbde09c44a011a47312726" 1655 | dependencies = [ 1656 | "arrayvec", 1657 | "bit-vec", 1658 | "bitflags 2.4.1", 1659 | "codespan-reporting", 1660 | "log", 1661 | "naga", 1662 | "parking_lot", 1663 | "profiling", 1664 | "raw-window-handle", 1665 | "rustc-hash", 1666 | "smallvec", 1667 | "thiserror", 1668 | "web-sys", 1669 | "wgpu-hal", 1670 | "wgpu-types", 1671 | ] 1672 | 1673 | [[package]] 1674 | name = "wgpu-hal" 1675 | version = "0.18.1" 1676 | source = "registry+https://github.com/rust-lang/crates.io-index" 1677 | checksum = "b84ecc802da3eb67b4cf3dd9ea6fe45bbb47ef13e6c49c5c3240868a9cc6cdd9" 1678 | dependencies = [ 1679 | "android_system_properties", 1680 | "arrayvec", 1681 | "ash", 1682 | "bit-set", 1683 | "bitflags 2.4.1", 1684 | "block", 1685 | "core-graphics-types", 1686 | "d3d12", 1687 | "glow", 1688 | "glutin_wgl_sys", 1689 | "gpu-alloc", 1690 | "gpu-allocator", 1691 | "gpu-descriptor", 1692 | "hassle-rs", 1693 | "js-sys", 1694 | "khronos-egl", 1695 | "libc", 1696 | "libloading 0.8.1", 1697 | "log", 1698 | "metal", 1699 | "naga", 1700 | "objc", 1701 | "once_cell", 1702 | "parking_lot", 1703 | "profiling", 1704 | "range-alloc", 1705 | "raw-window-handle", 1706 | "renderdoc-sys", 1707 | "rustc-hash", 1708 | "smallvec", 1709 | "thiserror", 1710 | "wasm-bindgen", 1711 | "web-sys", 1712 | "wgpu-types", 1713 | "winapi", 1714 | ] 1715 | 1716 | [[package]] 1717 | name = "wgpu-types" 1718 | version = "0.18.0" 1719 | source = "registry+https://github.com/rust-lang/crates.io-index" 1720 | checksum = "0d5ed5f0edf0de351fe311c53304986315ce866f394a2e6df0c4b3c70774bcdd" 1721 | dependencies = [ 1722 | "bitflags 2.4.1", 1723 | "js-sys", 1724 | "web-sys", 1725 | ] 1726 | 1727 | [[package]] 1728 | name = "widestring" 1729 | version = "1.0.2" 1730 | source = "registry+https://github.com/rust-lang/crates.io-index" 1731 | checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" 1732 | 1733 | [[package]] 1734 | name = "winapi" 1735 | version = "0.3.9" 1736 | source = "registry+https://github.com/rust-lang/crates.io-index" 1737 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1738 | dependencies = [ 1739 | "winapi-i686-pc-windows-gnu", 1740 | "winapi-x86_64-pc-windows-gnu", 1741 | ] 1742 | 1743 | [[package]] 1744 | name = "winapi-i686-pc-windows-gnu" 1745 | version = "0.4.0" 1746 | source = "registry+https://github.com/rust-lang/crates.io-index" 1747 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1748 | 1749 | [[package]] 1750 | name = "winapi-util" 1751 | version = "0.1.6" 1752 | source = "registry+https://github.com/rust-lang/crates.io-index" 1753 | checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" 1754 | dependencies = [ 1755 | "winapi", 1756 | ] 1757 | 1758 | [[package]] 1759 | name = "winapi-x86_64-pc-windows-gnu" 1760 | version = "0.4.0" 1761 | source = "registry+https://github.com/rust-lang/crates.io-index" 1762 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1763 | 1764 | [[package]] 1765 | name = "windows" 1766 | version = "0.51.1" 1767 | source = "registry+https://github.com/rust-lang/crates.io-index" 1768 | checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" 1769 | dependencies = [ 1770 | "windows-core", 1771 | "windows-targets 0.48.5", 1772 | ] 1773 | 1774 | [[package]] 1775 | name = "windows-core" 1776 | version = "0.51.1" 1777 | source = "registry+https://github.com/rust-lang/crates.io-index" 1778 | checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" 1779 | dependencies = [ 1780 | "windows-targets 0.48.5", 1781 | ] 1782 | 1783 | [[package]] 1784 | name = "windows-sys" 1785 | version = "0.48.0" 1786 | source = "registry+https://github.com/rust-lang/crates.io-index" 1787 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1788 | dependencies = [ 1789 | "windows-targets 0.48.5", 1790 | ] 1791 | 1792 | [[package]] 1793 | name = "windows-sys" 1794 | version = "0.52.0" 1795 | source = "registry+https://github.com/rust-lang/crates.io-index" 1796 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1797 | dependencies = [ 1798 | "windows-targets 0.52.0", 1799 | ] 1800 | 1801 | [[package]] 1802 | name = "windows-targets" 1803 | version = "0.48.5" 1804 | source = "registry+https://github.com/rust-lang/crates.io-index" 1805 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1806 | dependencies = [ 1807 | "windows_aarch64_gnullvm 0.48.5", 1808 | "windows_aarch64_msvc 0.48.5", 1809 | "windows_i686_gnu 0.48.5", 1810 | "windows_i686_msvc 0.48.5", 1811 | "windows_x86_64_gnu 0.48.5", 1812 | "windows_x86_64_gnullvm 0.48.5", 1813 | "windows_x86_64_msvc 0.48.5", 1814 | ] 1815 | 1816 | [[package]] 1817 | name = "windows-targets" 1818 | version = "0.52.0" 1819 | source = "registry+https://github.com/rust-lang/crates.io-index" 1820 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 1821 | dependencies = [ 1822 | "windows_aarch64_gnullvm 0.52.0", 1823 | "windows_aarch64_msvc 0.52.0", 1824 | "windows_i686_gnu 0.52.0", 1825 | "windows_i686_msvc 0.52.0", 1826 | "windows_x86_64_gnu 0.52.0", 1827 | "windows_x86_64_gnullvm 0.52.0", 1828 | "windows_x86_64_msvc 0.52.0", 1829 | ] 1830 | 1831 | [[package]] 1832 | name = "windows_aarch64_gnullvm" 1833 | version = "0.48.5" 1834 | source = "registry+https://github.com/rust-lang/crates.io-index" 1835 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1836 | 1837 | [[package]] 1838 | name = "windows_aarch64_gnullvm" 1839 | version = "0.52.0" 1840 | source = "registry+https://github.com/rust-lang/crates.io-index" 1841 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 1842 | 1843 | [[package]] 1844 | name = "windows_aarch64_msvc" 1845 | version = "0.48.5" 1846 | source = "registry+https://github.com/rust-lang/crates.io-index" 1847 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1848 | 1849 | [[package]] 1850 | name = "windows_aarch64_msvc" 1851 | version = "0.52.0" 1852 | source = "registry+https://github.com/rust-lang/crates.io-index" 1853 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 1854 | 1855 | [[package]] 1856 | name = "windows_i686_gnu" 1857 | version = "0.48.5" 1858 | source = "registry+https://github.com/rust-lang/crates.io-index" 1859 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1860 | 1861 | [[package]] 1862 | name = "windows_i686_gnu" 1863 | version = "0.52.0" 1864 | source = "registry+https://github.com/rust-lang/crates.io-index" 1865 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 1866 | 1867 | [[package]] 1868 | name = "windows_i686_msvc" 1869 | version = "0.48.5" 1870 | source = "registry+https://github.com/rust-lang/crates.io-index" 1871 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1872 | 1873 | [[package]] 1874 | name = "windows_i686_msvc" 1875 | version = "0.52.0" 1876 | source = "registry+https://github.com/rust-lang/crates.io-index" 1877 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 1878 | 1879 | [[package]] 1880 | name = "windows_x86_64_gnu" 1881 | version = "0.48.5" 1882 | source = "registry+https://github.com/rust-lang/crates.io-index" 1883 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1884 | 1885 | [[package]] 1886 | name = "windows_x86_64_gnu" 1887 | version = "0.52.0" 1888 | source = "registry+https://github.com/rust-lang/crates.io-index" 1889 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 1890 | 1891 | [[package]] 1892 | name = "windows_x86_64_gnullvm" 1893 | version = "0.48.5" 1894 | source = "registry+https://github.com/rust-lang/crates.io-index" 1895 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1896 | 1897 | [[package]] 1898 | name = "windows_x86_64_gnullvm" 1899 | version = "0.52.0" 1900 | source = "registry+https://github.com/rust-lang/crates.io-index" 1901 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 1902 | 1903 | [[package]] 1904 | name = "windows_x86_64_msvc" 1905 | version = "0.48.5" 1906 | source = "registry+https://github.com/rust-lang/crates.io-index" 1907 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1908 | 1909 | [[package]] 1910 | name = "windows_x86_64_msvc" 1911 | version = "0.52.0" 1912 | source = "registry+https://github.com/rust-lang/crates.io-index" 1913 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 1914 | 1915 | [[package]] 1916 | name = "xml-rs" 1917 | version = "0.8.19" 1918 | source = "registry+https://github.com/rust-lang/crates.io-index" 1919 | checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" 1920 | 1921 | [[package]] 1922 | name = "zerocopy" 1923 | version = "0.7.32" 1924 | source = "registry+https://github.com/rust-lang/crates.io-index" 1925 | checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" 1926 | dependencies = [ 1927 | "zerocopy-derive", 1928 | ] 1929 | 1930 | [[package]] 1931 | name = "zerocopy-derive" 1932 | version = "0.7.32" 1933 | source = "registry+https://github.com/rust-lang/crates.io-index" 1934 | checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" 1935 | dependencies = [ 1936 | "proc-macro2", 1937 | "quote", 1938 | "syn 2.0.43", 1939 | ] 1940 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sha256_rgpu" 3 | version = "0.2.0" 4 | authors = ["RustyBamboo "] 5 | edition = "2018" 6 | 7 | [[bin]] 8 | name = "sha256_rgpu" 9 | path = "src/main.rs" 10 | 11 | [lib] 12 | path = "src/lib.rs" 13 | crate-type = ["cdylib"] 14 | 15 | [features] 16 | default = ["use-compiled-tools"] 17 | use-installed-tools = ["spirv-builder/use-installed-tools"] 18 | use-compiled-tools = ["spirv-builder/use-compiled-tools"] 19 | 20 | [dependencies] 21 | wgpu = { version="0.18.0", features=["spirv"] } 22 | futures = "0.3.30" 23 | bytemuck = "1.14.0" 24 | flume = "0.11.0" 25 | rand = "0.8.5" 26 | clap = { version = "4.4.11", features = ["derive"] } 27 | 28 | [target.'cfg(target_arch = "wasm32")'.dependencies] 29 | console_error_panic_hook = "0.1.6" 30 | log = "0.4.20" 31 | hex = "0.4.3" 32 | console_log = "1.0" 33 | wgpu = { version = "0.18.0" } 34 | wasm-bindgen = "0.2" 35 | wasm-bindgen-futures = "0.4.30" 36 | web-sys = { version = "0.3" } 37 | 38 | [build-dependencies] 39 | spirv-builder = "0.9" 40 | 41 | [dev-dependencies] 42 | hex = "0.4.3" 43 | csv = "1.3.0" 44 | 45 | [profile.release.build-override] 46 | opt-level = 3 47 | codegen-units = 16 48 | [profile.dev.build-override] 49 | opt-level = 3 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 RustyBamboo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sha256_rgpu 2 | 3 | SHA256 Compute Shader (Kernel) Written in Rust. Aka a "hash-shader". 4 | 5 | This project contains the following goals: 6 | - Write Rust code for computing SHA256 on GPUs using [rust-gpu](https://github.com/EmbarkStudios/rust-gpu) 7 | - Use [wgpu](https://github.com/gfx-rs/wgpu) for cross-platform GPU compute 8 | - Reference implementation for writing compute kernels and WebGPU runners in Rust 9 | - `sha256_rgpu` command-line tool for assessing data integrity, similiar to `sha256sum` 10 | 11 | ### On the web 12 | 13 | Try at [https://rustybamboo.github.io/hash-shader/](https://rustybamboo.github.io/hash-shader/) 14 | 15 | Note that you will need a browser that supports WebGPU. 16 | 17 | ### Screenshot of sha256_rgpu 18 | 19 | ![](gfx/screenshot.png) 20 | 21 | ### Building 22 | 23 | This code is written in Rust, so you'll need to grab a [Rust installation](https://www.rust-lang.org/learn/get-started) in order to compile it. Note that compilation of the compute kernel for GPUs requires the nightly [toolchain](./rust-toolchain), but this should automatically be installed in the following steps. 24 | 25 | ``` 26 | $ git clone https://github.com/RustyBamboo/hash-shader/ 27 | $ cd hash_shader 28 | $ cargo build --release 29 | $ ./target/release/sha256_rgpu --help 30 | ``` 31 | 32 | 33 | 34 | ### Example: Run blockchain validator 35 | 36 | SHA256 is a key part of the bitcoin blockchain. The following example tests the integrity of a large porition of the blockchain. 37 | 38 | First, generate the csv file with rows as `block_header_hex,expected_hash`: 39 | 40 | ``` 41 | $ python3 examples/prepare_blockchain.py 42 | ``` 43 | 44 | Now, pass the csv file to the `blockchain_val` example. 45 | 46 | ``` 47 | $ cargo run --release --example blockchain_val block_data.csv 48 | 49 | Validated 4998 blocks 50 | 57.035164ms + 42.468205ms = 99.503369ms 51 | ``` 52 | 53 | 54 | ### Tests 55 | This will run GPU tests: 56 | ``` 57 | cargo test --release 58 | ``` 59 | 60 | This will run CPU tests of the kernel: 61 | ``` 62 | cd kernel 63 | cargo test --release 64 | ``` 65 | 66 | ### Code Layout 67 | 68 | ``` 69 | . 70 | ├── build.rs 71 | ├── Cargo.lock 72 | ├── Cargo.toml 73 | ├── examples 74 | │ ├── benckmark.rs 75 | │ ├── blockchain_val.rs 76 | │ └── prepare_blockchain.py 77 | ├── gfx 78 | │ └── screenshot.png 79 | ├── kernel <-- Rust code that is compiled to SPIR-V 80 | │ ├── Cargo.lock 81 | │ ├── Cargo.toml 82 | │ └── src 83 | │ └── lib.rs 84 | ├── LICENSE 85 | ├── README.md 86 | ├── rust-toolchain 87 | ├── src 88 | │ ├── helpers.rs 89 | │ ├── main.rs 90 | │ └── runner.rs 91 | ``` 92 | 93 | ### C + CUDA 94 | 95 | The [CUDA branch](https://github.com/RustyBamboo/hash-shader/tree/cuda) contains an implementation of SHA256 using the CUDA API. 96 | 97 | ### Web + wasm 98 | 99 | ``` 100 | cargo install web-pack 101 | ``` 102 | 103 | ``` 104 | RUSTFLAGS=--cfg=web_sys_unstable_apis wasm-pack build --target web --out-dir=web/pkg 105 | ``` 106 | 107 | ### License 108 | 109 | Please see [LICENSE](./LICENSE) -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use spirv_builder::{MetadataPrintout, SpirvBuilder}; 2 | use std::error::Error; 3 | 4 | fn main() -> Result<(), Box> { 5 | SpirvBuilder::new("./kernel", "spirv-unknown-spv1.5") 6 | .print_metadata(MetadataPrintout::Full) 7 | .build()?; 8 | Ok(()) 9 | } -------------------------------------------------------------------------------- /examples/benckmark.rs: -------------------------------------------------------------------------------- 1 | #[path = "../src/runner.rs"] 2 | mod runner; 3 | 4 | use rand::Rng; 5 | use std::env; 6 | 7 | use std::time::{Duration, Instant}; 8 | 9 | 10 | fn rand_hash(count: usize) -> Duration { 11 | // Generate random strings of size 512 bits 12 | let texts: Vec> = (0..count) 13 | .map(|_| (0..16).map(|_| rand::thread_rng().gen()).collect()) 14 | .collect(); 15 | let texts: Vec = texts.into_iter().flatten().collect(); 16 | let sizes: Vec = (0..count).map(|_| 1).collect(); 17 | let hash = vec![0u32; count * 8]; 18 | 19 | assert_eq!(hash.len() * core::mem::size_of::() * 8, 8 * 32 * count); 20 | 21 | let mut device = runner::Device::new(0); 22 | let text_gpu = device.to_device(texts.as_slice()); 23 | let hash_gpu = device.to_device(hash.as_slice()); 24 | let size_gpu = device.to_device(sizes.as_slice()); 25 | 26 | let shader = wgpu::include_spirv!(env!("kernel.spv")); 27 | 28 | let args = runner::ParamsBuilder::new() 29 | .param(Some(&text_gpu), true) 30 | .param(Some(&hash_gpu), false) 31 | .param(Some(&size_gpu), true) 32 | .build(Some(0)); 33 | 34 | let start_1 = Instant::now(); 35 | 36 | let compute = device.compile("main_cs", shader, &args.0).unwrap(); 37 | 38 | device.call(compute, (count as u32, 1, 1), &args.1); 39 | 40 | let hash_res = futures::executor::block_on(device.get(&hash_gpu)).unwrap(); 41 | let duration_1 = start_1.elapsed(); 42 | 43 | let hash_res = &hash_res[0..hash.len()]; 44 | 45 | let result: String = hash_res.into_iter().map(|x| format!("{:08x}", x)).collect(); 46 | let _chunks = result 47 | .as_bytes() 48 | .chunks(64) 49 | .map(std::str::from_utf8) 50 | .collect::, _>>() 51 | .unwrap(); 52 | return duration_1; 53 | } 54 | 55 | fn run_benchmark(count:usize, f:&dyn Fn(usize)->Duration) -> f64{ 56 | let times: Vec = (0..30).map(|_| f(count)).collect(); 57 | let times: Vec = times.iter().map(|x| x.as_millis()).collect(); 58 | return times.iter().sum::() as f64 / times.len() as f64; 59 | } 60 | 61 | fn main() { 62 | let count = env::args().nth(1).expect("Enter number of hashes"); 63 | let count = count.parse::().expect("Not a number"); 64 | println!("{} ms", run_benchmark(count, &rand_hash)); 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /examples/blockchain_val.rs: -------------------------------------------------------------------------------- 1 | #[path = "../src/runner.rs"] 2 | mod runner; 3 | 4 | #[path = "../src/helpers.rs"] 5 | mod helpers; 6 | 7 | use std::env; 8 | use std::time::{Duration, Instant}; 9 | 10 | use helpers::prepare_for_gpu_u8; 11 | 12 | fn sha<'a>(words: Vec) -> (Box<[u32]>, Duration) { 13 | let count = words.len(); 14 | 15 | // A Vec of bit strings, and a vec of "number of iterations" 16 | let (texts, sizes): (Vec>, Vec) = 17 | words.into_iter().map(|x| prepare_for_gpu_u8(hex::decode(x).expect("Input was not hex"))).unzip(); 18 | 19 | let texts: Vec = texts.into_iter().flatten().collect(); 20 | 21 | let hash = vec![0u32; count * 8]; 22 | 23 | // Check number of bits 24 | assert_eq!(hash.len() * core::mem::size_of::() * 8, 8 * 32 * count); 25 | 26 | let mut device = runner::Device::new(0); 27 | 28 | let text_gpu = device.to_device(texts.as_slice()); 29 | let hash_gpu = device.to_device(hash.as_slice()); 30 | let size_gpu = device.to_device(sizes.as_slice()); 31 | 32 | let shader = wgpu::include_spirv!(env!("kernel.spv")); 33 | 34 | let args = runner::ParamsBuilder::new() 35 | .param(Some(&text_gpu), true) 36 | .param(Some(&hash_gpu), false) 37 | .param(Some(&size_gpu), true) 38 | .build(Some(0)); 39 | 40 | let start_1 = Instant::now(); 41 | let compute = device.compile("main_cs", shader, &args.0).unwrap(); 42 | 43 | device.call(compute, (count as u32, 1, 1), &args.1); 44 | 45 | let hash_res = futures::executor::block_on(device.get(&hash_gpu)).unwrap(); 46 | let duration_1 = start_1.elapsed(); 47 | (hash_res, duration_1) 48 | } 49 | 50 | fn main() { 51 | let paths: Vec = env::args().skip(1).collect(); 52 | if paths.len() == 0 { 53 | println!("Input path to CSV file containing blockchain data: [block header],[block hash] 54 | \nThe following will create a CSV file with this information from the real bitcoin blockchain: 55 | \n\tpython3 examples/prepare_blockchain.py\n"); 56 | return; 57 | } 58 | let max_blocks: i32; 59 | if paths.len() > 1 { 60 | max_blocks = paths[1].parse().unwrap() 61 | } else { 62 | max_blocks = -1; 63 | } 64 | 65 | let mut rdr = csv::Reader::from_path(&paths[0]).expect("Failed to open file"); 66 | 67 | let mut words = Vec::new(); 68 | let mut expected = Vec::new(); 69 | 70 | let mut i = 0; 71 | for record in rdr.records() { 72 | if max_blocks != -1 && i == max_blocks { 73 | break; 74 | } 75 | let record = record.expect("Failed"); 76 | words.push(record[0].to_string()); 77 | expected.push(record[1].to_string()); 78 | i += 1; 79 | } 80 | 81 | // ROUND 1 OF SHA 82 | 83 | let (hash_res, duration_1) = sha(words); 84 | let hash_res = &hash_res; 85 | 86 | let result: String = hash_res.into_iter().map(|x| format!("{:08x}", x)).collect(); 87 | let chunks = result 88 | .as_bytes() 89 | .chunks(64) 90 | .map(std::str::from_utf8) 91 | .collect::, _>>() 92 | .unwrap(); 93 | 94 | let words = chunks.into_iter().map(|s| s.to_string()).collect(); 95 | 96 | // ROUND 2 OF SHA 97 | 98 | let (hash_res, duration_2) = sha(words); 99 | let hash_res = &hash_res; 100 | 101 | let result: String = hash_res.into_iter().map(|x| format!("{:08x}", x)).collect(); 102 | let chunks = result 103 | .as_bytes() 104 | .chunks(64) 105 | .map(std::str::from_utf8) 106 | .collect::, _>>() 107 | .unwrap(); 108 | 109 | for c in 0..chunks.len() { 110 | assert_eq!(expected[c], chunks[c]); 111 | } 112 | print!("{} {}", chunks.len(), (duration_1 + duration_2).as_millis()); 113 | } 114 | -------------------------------------------------------------------------------- /examples/prepare_blockchain.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | 4 | import urllib.request, json 5 | 6 | blocks = range(201290, 300000) 7 | 8 | 9 | for b in blocks: 10 | print("Downloading block %s"%b) 11 | f = open("block_data_200000_300000.csv", "a") 12 | with urllib.request.urlopen("https://blockchain.info/block-height/%s?format=json"%b) as url: 13 | data = json.loads(url.read().decode()) 14 | 15 | block = data['blocks'][0] 16 | 17 | ver = block['ver'].to_bytes(4, byteorder = 'little').hex() 18 | prev_block = int(block['prev_block'],16).to_bytes(32, byteorder='little').hex() 19 | mrkl_root = int(block['mrkl_root'], 16).to_bytes(32, byteorder='little').hex() 20 | time = block['time'].to_bytes(4, byteorder='little').hex() 21 | bits = block['bits'].to_bytes(4, byteorder='little').hex() 22 | nonce = block['nonce'].to_bytes(4, byteorder='little').hex() 23 | 24 | expected_hash = block['hash'] 25 | flip_hash = int(expected_hash, 16).to_bytes(32, byteorder="little").hex() 26 | 27 | header = ver + prev_block + mrkl_root + time + bits + nonce 28 | 29 | f.write("%s,%s\n"%(header, flip_hash)) 30 | f.close() # so that is actually saves 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /gfx/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustyBamboo/hash-shader/22b6aaba2ba17453e5d1f3f59e9877c032820dcc/gfx/screenshot.png -------------------------------------------------------------------------------- /kernel/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "autocfg" 7 | version = "1.0.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 10 | 11 | [[package]] 12 | name = "bitflags" 13 | version = "1.3.2" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 16 | 17 | [[package]] 18 | name = "glam" 19 | version = "0.24.2" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" 22 | dependencies = [ 23 | "libm", 24 | ] 25 | 26 | [[package]] 27 | name = "kernel" 28 | version = "0.1.0" 29 | dependencies = [ 30 | "spirv-std", 31 | ] 32 | 33 | [[package]] 34 | name = "libm" 35 | version = "0.2.1" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" 38 | 39 | [[package]] 40 | name = "num-traits" 41 | version = "0.2.17" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 44 | dependencies = [ 45 | "autocfg", 46 | "libm", 47 | ] 48 | 49 | [[package]] 50 | name = "proc-macro2" 51 | version = "1.0.71" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" 54 | dependencies = [ 55 | "unicode-ident", 56 | ] 57 | 58 | [[package]] 59 | name = "quote" 60 | version = "1.0.9" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" 63 | dependencies = [ 64 | "proc-macro2", 65 | ] 66 | 67 | [[package]] 68 | name = "spirv-std" 69 | version = "0.9.0" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "68c3c0972a2df79abe2c8af2fe7f7937a9aa558b6a1f78fc5edf93f4d480d757" 72 | dependencies = [ 73 | "bitflags", 74 | "glam", 75 | "num-traits", 76 | "spirv-std-macros", 77 | "spirv-std-types", 78 | ] 79 | 80 | [[package]] 81 | name = "spirv-std-macros" 82 | version = "0.9.0" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "73f776bf9f2897ea7acff15d7753711fdf1693592bd7459a01c394262b1df45c" 85 | dependencies = [ 86 | "proc-macro2", 87 | "quote", 88 | "spirv-std-types", 89 | "syn", 90 | ] 91 | 92 | [[package]] 93 | name = "spirv-std-types" 94 | version = "0.9.0" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "a73417b7d72d95b4995c840dceb4e3b4bcbad4ff7f35df9c1655b6826c18d3a9" 97 | 98 | [[package]] 99 | name = "syn" 100 | version = "1.0.109" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 103 | dependencies = [ 104 | "proc-macro2", 105 | "quote", 106 | "unicode-ident", 107 | ] 108 | 109 | [[package]] 110 | name = "unicode-ident" 111 | version = "1.0.12" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 114 | -------------------------------------------------------------------------------- /kernel/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kernel" 3 | version = "0.1.0" 4 | authors = ["RustyBamboo "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [lib] 10 | crate-type = ["dylib"] 11 | 12 | [dependencies] 13 | spirv-std = { version = "0.9" } -------------------------------------------------------------------------------- /kernel/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(target_arch = "spirv", no_std)] 2 | 3 | use spirv_std::{glam, spirv}; 4 | use glam::UVec3; 5 | 6 | // Rotation right: u32.rotate_right(n: u32) 7 | fn rot_r(x: u32, n: u32) -> u32 { 8 | x >> n | (x << (32 - n)) 9 | } 10 | 11 | fn Sigma0(x: u32) -> u32 { 12 | rot_r(x, 2) ^ rot_r(x, 13) ^ rot_r(x, 22) 13 | //x.rotate_right(2) ^ x.rotate_right(13) ^ x.rotate_right(22) 14 | } 15 | #[test] 16 | fn test_Sigma0() { 17 | let x: u32 = 0b00000000000000000011111111111111; 18 | let y: u32 = 0b00111111000001111111001111111110; 19 | let r = Sigma0(x); 20 | assert_eq!( 21 | r, y, 22 | "Testing choice:\n x:{:#034b}\n y:{:#034b}\n e:{:#034b}", 23 | x, y, r 24 | ); 25 | } 26 | 27 | fn Sigma1(x: u32) -> u32 { 28 | rot_r(x, 6) ^ rot_r(x, 11) ^ rot_r(x, 25) 29 | //x.rotate_right(6) ^ x.rotate_right(11) ^ x.rotate_right(25) 30 | } 31 | #[test] 32 | fn test_Sigma1() { 33 | let x: u32 = 0b00000000000000000011111111111111; 34 | let y: u32 = 0b00000011111111111111111101111000; 35 | let r = Sigma1(x); 36 | assert_eq!( 37 | r, y, 38 | "Testing choice:\n x:{:#034b}\n y:{:#034b}\n e:{:#034b}", 39 | x, y, r 40 | ); 41 | } 42 | fn sigma0(x: u32) -> u32 { 43 | rot_r(x, 7) ^ rot_r(x, 18) ^ (x >> 3) 44 | //x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3) 45 | } 46 | #[test] 47 | fn test_sigma0() { 48 | let x: u32 = 0b00000000000000000011111111111111; 49 | let y: u32 = 0b11110001111111111100011110000000; 50 | let r = sigma0(x); 51 | assert_eq!( 52 | r, y, 53 | "Testing choice:\n x:{:#034b}\n y:{:#034b}\n e:{:#034b}", 54 | x, y, r 55 | ); 56 | } 57 | 58 | fn sigma1(x: u32) -> u32 { 59 | rot_r(x, 17) ^ rot_r(x, 19) ^ (x >> 10) 60 | //x.rotate_right(17) ^ x.rotate_right(19) ^ (x >> 10) 61 | } 62 | #[test] 63 | fn test_sigma1() { 64 | let x: u32 = 0b00000000000000000011111111111111; 65 | let y: u32 = 0b00011000000000000110000000001111; 66 | let r = sigma1(x); 67 | assert_eq!( 68 | r, y, 69 | "Testing choice:\n x:{:#034b}\n y:{:#034b}\n e:{:#034b}", 70 | x, y, r 71 | ); 72 | 73 | let x: u32 = 0b00000000000000000000000000011000; 74 | let y: u32 = 0b00000000000011110000000000000000; 75 | let r = sigma1(x); 76 | assert_eq!( 77 | r, y, 78 | "Testing choice:\n x:{:#034b}\n y:{:#034b}\n e:{:#034b}", 79 | x, y, r 80 | ); 81 | } 82 | 83 | // Choice operation 84 | fn ch(x: u32, y: u32, z: u32) -> u32 { 85 | (x & y) ^ (!x & z) 86 | } 87 | 88 | #[test] 89 | fn test_ch() { 90 | let x: u32 = 0b0000000111111110000000011111111; 91 | let y: u32 = 0b0000000000000001111111111111111; 92 | let z: u32 = 0b1111111111111110000000000000000; 93 | let w: u32 = 0b1111111000000000000000011111111; 94 | assert_eq!( 95 | ch(x, y, z), 96 | w, 97 | "Testing choice:\n x:{:#034b}\n y:{:#034b}\n z:{:#034b}\n w:{:#034b}", 98 | x, 99 | y, 100 | z, 101 | w 102 | ); 103 | } 104 | 105 | // Majority operation 106 | fn maj(x: u32, y: u32, z: u32) -> u32 { 107 | (x & y) ^ (x & z) ^ (y & z) 108 | } 109 | 110 | #[test] 111 | fn test_maj() { 112 | let x: u32 = 0b0000000111111110000000011111111; 113 | let y: u32 = 0b0000000000000001111111111111111; 114 | let z: u32 = 0b1111111111111110000000000000000; 115 | let w: u32 = 0b0000000111111110000000011111111; 116 | assert_eq!( 117 | maj(x, y, z), 118 | w, 119 | "Testing choice:\n x:{:#034b}\n y:{:#034b}\n z:{:#034b}\n w:{:#034b}", 120 | x, 121 | y, 122 | z, 123 | w 124 | ); 125 | } 126 | 127 | const K: [u32; 64] = [ 128 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 129 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 130 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 131 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 132 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 133 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 134 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 135 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, 136 | ]; 137 | 138 | #[test] 139 | fn test_K() { 140 | let primes = vec![ 141 | 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 142 | 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 143 | 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 144 | 283, 293, 307, 311, 145 | ]; 146 | for (ix, n) in primes.into_iter().enumerate() { 147 | // Get the fractional part as hex 148 | let mut fractional = (n as f64).cbrt().fract(); 149 | let mut hex = [0u8; 8]; 150 | for h in 0..hex.len() { 151 | let product = fractional * 16.; 152 | let carry = product.floor() as u8; 153 | fractional = product - product.floor(); 154 | hex[h] = carry; 155 | } 156 | // Convert the hex array (4 bits but represented as u8) to a u32 157 | let mut value: u32 = hex[7] as u32; 158 | for (i, h) in (0..hex.len() - 1).rev().enumerate() { 159 | value += hex[h] as u32 * 16_u32.pow(i as u32 + 1); 160 | } 161 | assert_eq!(K[ix], value); 162 | } 163 | } 164 | 165 | const INIT_HASH: [u32; 8] = [ 166 | 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, 167 | ]; 168 | 169 | fn hash_fn(text: &[u32], hash: &mut [u32], x: usize, offset: usize, iter: usize) { 170 | // Offsets for loading and storing in data buffers 171 | let load_offset = (iter + x + offset) * 16; 172 | let store_offset = x * 8; 173 | 174 | let (mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h, mut t1, mut t2): ( 175 | u32, 176 | u32, 177 | u32, 178 | u32, 179 | u32, 180 | u32, 181 | u32, 182 | u32, 183 | u32, 184 | u32, 185 | ); 186 | 187 | // Need to manually unroll declaration 188 | let mut m: [u32; 64] = [ 189 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191 | 0, 0, 0, 0, 192 | ]; 193 | 194 | // Create the message schedule 195 | // The first 16 are assumed to be given 196 | for i in 0..16 { 197 | m[i] = text[load_offset + i]; 198 | } 199 | 200 | // Compute the remaining message schedule 201 | for i in 16..64 { 202 | m[i] = sigma1(m[i - 2]) + m[i - 7] + sigma0(m[i - 15]) + m[i - 16]; 203 | //println!("{} {:#034b}", i, m[i]); 204 | } 205 | 206 | // Do compression 207 | // The initial hash value as sqrt of primes 208 | if iter == 0 { 209 | a = INIT_HASH[0]; 210 | b = INIT_HASH[1]; 211 | c = INIT_HASH[2]; 212 | d = INIT_HASH[3]; 213 | e = INIT_HASH[4]; 214 | f = INIT_HASH[5]; 215 | g = INIT_HASH[6]; 216 | h = INIT_HASH[7]; 217 | } else { 218 | a = hash[store_offset + 0]; 219 | b = hash[store_offset + 1]; 220 | c = hash[store_offset + 2]; 221 | d = hash[store_offset + 3]; 222 | e = hash[store_offset + 4]; 223 | f = hash[store_offset + 5]; 224 | g = hash[store_offset + 6]; 225 | h = hash[store_offset + 7]; 226 | } 227 | 228 | for i in 0..64 { 229 | t1 = Sigma1(e) + ch(e, f, g) + h + K[i] + m[i]; 230 | t2 = Sigma0(a) + maj(a, b, c); 231 | h = g; 232 | g = f; 233 | f = e; 234 | e = d + t1; 235 | d = c; 236 | c = b; 237 | b = a; 238 | a = t1 + t2; 239 | } 240 | 241 | // Add the original hashed message with initial hash 242 | if iter == 0 { 243 | a += INIT_HASH[0]; 244 | b += INIT_HASH[1]; 245 | c += INIT_HASH[2]; 246 | d += INIT_HASH[3]; 247 | e += INIT_HASH[4]; 248 | f += INIT_HASH[5]; 249 | g += INIT_HASH[6]; 250 | h += INIT_HASH[7]; 251 | } else { 252 | a += hash[store_offset + 0]; 253 | b += hash[store_offset + 1]; 254 | c += hash[store_offset + 2]; 255 | d += hash[store_offset + 3]; 256 | e += hash[store_offset + 4]; 257 | f += hash[store_offset + 5]; 258 | g += hash[store_offset + 6]; 259 | h += hash[store_offset + 7]; 260 | } 261 | 262 | // Store result 263 | hash[store_offset + 0] = a; 264 | hash[store_offset + 1] = b; 265 | hash[store_offset + 2] = c; 266 | hash[store_offset + 3] = d; 267 | hash[store_offset + 4] = e; 268 | hash[store_offset + 5] = f; 269 | hash[store_offset + 6] = g; 270 | hash[store_offset + 7] = h; 271 | } 272 | 273 | #[test] 274 | fn test_hash_fn() { 275 | let word: String = String::from("abc"); 276 | let mut init: Vec = word.into_bytes(); 277 | 278 | let msg_size = (init.len() * 8) as u64; // in bits 279 | 280 | // Add a 1 as a delimiter 281 | init.push(0x80 as u8); 282 | let size: usize = (448u32 / 8u32 - init.len() as u32) as usize; 283 | 284 | // Pad with zeros 285 | let remaining = vec![0u8; size]; 286 | init.extend(&remaining); 287 | 288 | // Make the last 64 bits be the size 289 | let size = (msg_size).to_be_bytes(); 290 | init.extend(&size); 291 | 292 | let mut text = Vec::new(); 293 | 294 | use std::convert::TryInto; 295 | for i in 0..16 { 296 | let val = u32::from_be_bytes(init[i * 4..(i + 1) * 4].try_into().unwrap()); 297 | text.push(val); 298 | } 299 | 300 | let mut hash = vec![0u32; 8]; 301 | 302 | hash_fn(text.as_slice(), hash.as_mut_slice(), 0, 0, 0); 303 | 304 | let result: String = hash.into_iter().map(|x| format!("{:x}", x)).collect(); 305 | assert_eq!( 306 | result, 307 | "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" 308 | ); 309 | } 310 | 311 | #[allow(unused_attributes)] 312 | #[spirv(compute(threads(64)))] 313 | pub fn main_cs( 314 | #[spirv(global_invocation_id)] gid: UVec3, 315 | #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] text: &[u32], 316 | #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] hash: &mut [u32], 317 | #[spirv(storage_buffer, descriptor_set = 0, binding = 2)] iter: &[u32], 318 | ) { 319 | // The sha specification loops in blocks of 512 320 | let num_loops: usize = iter[gid.x as usize] as usize; 321 | 322 | // Calculate where the memory offset for each kernel instance 323 | // which depends upon the number of iterations required by all previous 324 | // kernel invocations 325 | let mut offset = 0; 326 | for i in 0..gid.x as usize { 327 | offset += iter[i] as usize - 1; 328 | } 329 | 330 | for i in 0..num_loops { 331 | hash_fn(text, hash, gid.x as usize, offset, i); 332 | } 333 | } 334 | -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2023-05-27" 3 | components = ["rust-src", "rustc-dev", "llvm-tools"] -------------------------------------------------------------------------------- /src/helpers.rs: -------------------------------------------------------------------------------- 1 | #[allow(dead_code)] 2 | pub fn prepare_for_gpu(word: String) -> (Vec, u32) { 3 | let init = word.into_bytes(); 4 | return prepare_for_gpu_u8(init); 5 | } 6 | 7 | /// Prepare the text data for GPU by padding the bits to multiples of 512 8 | /// - Append 1 as a delimiter 9 | /// - Append 0s 10 | /// - The last 64 bits denote the size of original message 11 | pub fn prepare_for_gpu_u8(mut init: Vec) -> (Vec, u32) { 12 | 13 | let msg_size = (init.len() * 8) as u64; // in bits 14 | 15 | let mut desired_size = (msg_size / 512 + 1) * 512; 16 | 17 | // Ensure that desired_size is large enough to accommodate the initial message, 18 | // the 0x80 byte, and the 64-bit length field 19 | while desired_size < msg_size + 8 + 64 { 20 | desired_size += 512; 21 | } 22 | 23 | // Add a 1 as a delimiter 24 | init.push(0x80 as u8); 25 | let size: usize = ((desired_size - 64) as u32 / 8u32 - init.len() as u32) as usize; 26 | 27 | // Pad with zeros 28 | let remaining = vec![0u8; size]; 29 | init.extend(&remaining); 30 | 31 | // Make the last 64 bits be the size 32 | let size = (msg_size).to_be_bytes(); 33 | init.extend(&size); 34 | 35 | let mut text = Vec::new(); 36 | 37 | use std::convert::TryInto; 38 | for i in 0..(desired_size / 32) as usize { 39 | let val = u32::from_be_bytes(init[i * 4..(i + 1) * 4].try_into().unwrap()); 40 | text.push(val); 41 | } 42 | 43 | (text, (desired_size / 512) as u32) 44 | } -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | mod helpers; 2 | mod runner; 3 | 4 | #[cfg(target_arch = "wasm32")] 5 | pub mod my_wasm_module { 6 | 7 | const KERNEL: &[u8] = include_bytes!(env!("kernel.spv")); 8 | 9 | use crate::helpers; 10 | use crate::runner; 11 | 12 | use wasm_bindgen::prelude::*; 13 | 14 | #[wasm_bindgen] 15 | pub async fn hash(name: &str, ty: bool) -> String { 16 | let mut device = runner::Device::new().await; 17 | 18 | let words = vec![name.to_string()]; 19 | let count = words.len(); 20 | 21 | let (texts, sizes): (Vec>, Vec) = if ty { 22 | words 23 | .into_iter() 24 | .map(|x| helpers::prepare_for_gpu(x)) 25 | .unzip() 26 | } else { 27 | words 28 | .into_iter() 29 | .map(|x| helpers::prepare_for_gpu_u8(hex::decode(x).expect("Input was not hex"))) 30 | .unzip() 31 | }; 32 | 33 | let texts: Vec = texts.into_iter().flatten().collect(); 34 | let hash = vec![0u32; count * 8]; 35 | 36 | web_sys::console::log_1(&"Sending data to GPU...".into()); 37 | 38 | let text_gpu = device.to_device(texts.as_slice()); 39 | let hash_gpu = device.to_device(hash.as_slice()); 40 | let size_gpu = device.to_device(sizes.as_slice()); 41 | 42 | let shader = wgpu::ShaderModuleDescriptor { 43 | label: Some("Shader"), 44 | source: wgpu::util::make_spirv(KERNEL), 45 | }; 46 | 47 | web_sys::console::log_1(&"Loaded shader and now running...".into()); 48 | 49 | let args_gpu = runner::ParamsBuilder::new() 50 | .param(Some(&text_gpu), true) 51 | .param(Some(&hash_gpu), false) 52 | .param(Some(&size_gpu), true) 53 | .build(Some(0)); 54 | web_sys::console::log_1(&"Loading compute...".into()); 55 | 56 | let compute = device.compile("main_cs", shader, &args_gpu.0).unwrap(); 57 | device.call(compute, (count as u32, 1, 1), &args_gpu.1); 58 | 59 | web_sys::console::log_1(&"Running...".into()); 60 | 61 | let hash_res = device.get(&hash_gpu).await.unwrap(); 62 | let hash_res = &hash_res[0..hash.len()]; 63 | 64 | web_sys::console::log_1(&"Retrieving...".into()); 65 | 66 | let result: String = hash_res.into_iter().map(|x| format!("{:08x}", x)).collect(); 67 | let chunks = result 68 | .as_bytes() 69 | .chunks(64) 70 | .map(std::str::from_utf8) 71 | .collect::, _>>() 72 | .unwrap(); 73 | 74 | for c in &chunks { 75 | web_sys::console::log_1(&format!("{}", c).into()); 76 | } 77 | 78 | let d_info = &device.info.as_ref().unwrap().info; 79 | 80 | let d_name = &d_info.name; 81 | let d_type = &d_info.device_type; 82 | let d_driver = &d_info.driver; 83 | let d_driver_info = &d_info.driver_info; 84 | let d_backend = &d_info.backend; 85 | 86 | web_sys::console::log_1( 87 | &format!( 88 | "{}\n Type: {:?}\n Driver: {} ({})\n Backend: {:?}", 89 | d_name, d_type, d_driver, d_driver_info, d_backend 90 | ) 91 | .into(), 92 | ); 93 | return chunks.first().expect("No input?").to_string(); 94 | } 95 | 96 | #[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))] 97 | pub fn run() { 98 | std::panic::set_hook(Box::new(console_error_panic_hook::hook)); 99 | console_log::init_with_level(log::Level::Warn).expect("Couldn't initialize logger"); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod helpers; 2 | mod runner; 3 | 4 | use std::{ 5 | env, fs, 6 | io::{BufRead, BufReader}, 7 | }; 8 | 9 | use clap::Parser; 10 | 11 | use crate::helpers::prepare_for_gpu_u8; 12 | 13 | const KERNEL: &[u8] = include_bytes!(env!("kernel.spv")); 14 | 15 | /// Print or check SHA256 (256-bit) checksums. 16 | /// Computing SHA256 hash is performed on a GPU backend. 17 | #[derive(Parser, Debug)] 18 | #[command(author, version, about, arg_required_else_help(true), long_about = None, after_help = "Example: \n sha256_rgpu MYFILE > hash.sha256sum \n sha256_rgpu -c hash.sha256sum")] 19 | struct Args { 20 | /// read checksums from file and check them 21 | #[arg(short, long)] 22 | check: bool, 23 | 24 | /// files to hash, or checksum files (if check) 25 | files: Vec, 26 | 27 | /// id of compute device 28 | #[arg(short, long, default_value_t = 0)] 29 | device: usize, 30 | 31 | /// verbose mode 32 | #[arg(short, long, default_value_t = false)] 33 | verbose: bool, 34 | } 35 | 36 | struct HashAndFile { 37 | hash: String, 38 | file: String, 39 | } 40 | 41 | /// 42 | /// Read lines from a checksum file and extract hash value and file path 43 | /// 44 | fn lines_from_file(filename: &str) -> Vec { 45 | let file = fs::File::open(filename).expect("no such file"); 46 | let buf = BufReader::new(file); 47 | let lines = buf 48 | .lines() 49 | .map(|l| l.expect("Could not parse line")) 50 | .map(|l| { 51 | let parts: Vec<&str> = l.split(" ").collect(); 52 | if parts.len() != 2 { 53 | panic!("Line does not contain exactly two parts"); 54 | } 55 | HashAndFile { 56 | hash: parts[0].to_string(), 57 | file: parts[1].to_string(), 58 | } 59 | }) 60 | .collect(); 61 | 62 | lines 63 | } 64 | 65 | fn main() { 66 | let args = Args::parse(); 67 | 68 | // Read all files and obtain a list of hash values and corresponding file paths 69 | let (files, hashes) = if args.check { 70 | let hf: Vec = args 71 | .files 72 | .iter() 73 | .map(|f| lines_from_file(f)) 74 | .flatten() 75 | .collect(); 76 | let (files, hashes): (Vec<_>, Vec<_>) = hf.into_iter().map(|x| (x.file, x.hash)).unzip(); 77 | (files, Some(hashes)) 78 | } else { 79 | (args.files, None) 80 | }; 81 | let contents: Vec> = files 82 | .iter() 83 | .map(|f| fs::read(&f).expect("Should have been able to read the file")) 84 | .collect(); 85 | 86 | let count = files.len(); 87 | 88 | // A Vec of bit strings, and a vec of "number of iterations" 89 | let (texts, sizes): (Vec>, Vec) = 90 | contents.into_iter().map(|x| prepare_for_gpu_u8(x)).unzip(); 91 | 92 | for &s in &sizes { 93 | if s > 10000 { 94 | todo!("Sorry, the file is too large and will crash your GPU. This will change in the future by sending data in chunks to the GPU.") 95 | } 96 | } 97 | 98 | // Flatten the data to send to GPUs 99 | let texts: Vec = texts.into_iter().flatten().collect(); 100 | 101 | // Prepare buffer to store the results 102 | let hash = vec![0u32; count * 8]; 103 | 104 | // Check number of bits 105 | assert_eq!(hash.len() * core::mem::size_of::() * 8, 8 * 32 * count); 106 | 107 | let mut device = runner::Device::new(args.device); 108 | let text_gpu = device.to_device(texts.as_slice()); 109 | let hash_gpu = device.to_device(hash.as_slice()); 110 | let size_gpu = device.to_device(sizes.as_slice()); 111 | 112 | let shader = wgpu::ShaderModuleDescriptor { 113 | label: Some("Shader"), 114 | source: wgpu::util::make_spirv(KERNEL), 115 | }; 116 | 117 | let args_gpu = runner::ParamsBuilder::new() 118 | .param(Some(&text_gpu), true) 119 | .param(Some(&hash_gpu), false) 120 | .param(Some(&size_gpu), true) 121 | .build(Some(0)); 122 | 123 | let compute = device.compile("main_cs", shader, &args_gpu.0).unwrap(); 124 | 125 | device.call(compute, (count as u32, 1, 1), &args_gpu.1); 126 | 127 | let hash_res = futures::executor::block_on(device.get(&hash_gpu)).unwrap(); 128 | let hash_res = &hash_res[0..hash.len()]; 129 | 130 | let result: String = hash_res.into_iter().map(|x| format!("{:08x}", x)).collect(); 131 | let chunks = result 132 | .as_bytes() 133 | .chunks(64) 134 | .map(std::str::from_utf8) 135 | .collect::, _>>() 136 | .unwrap(); 137 | 138 | if let Some(hashes) = hashes { 139 | let mut count_bad = 0; 140 | for i in 0..files.len() { 141 | let f = &files[i]; 142 | let c = chunks[i]; 143 | let h: &str = hashes[i].as_ref(); 144 | 145 | let status = c == h; 146 | 147 | if !status { 148 | count_bad += 1; 149 | } 150 | 151 | println!("{}: {}", f, if status { "OK" } else { "FAILURE" }); 152 | } 153 | if count_bad > 0 { 154 | println!( 155 | "sha256_rgpu: WARNING: {} computed checksum did NOT match", 156 | count_bad 157 | ); 158 | } 159 | } else { 160 | for (f, c) in files.iter().zip(chunks.iter()) { 161 | println!("{} {}", c, f); 162 | } 163 | } 164 | 165 | if args.verbose { 166 | let d_info = &device.info.as_ref().unwrap().info; 167 | let d_name = &d_info.name; 168 | let d_type = &d_info.device_type; 169 | let d_driver = &d_info.driver; 170 | let d_driver_info = &d_info.driver_info; 171 | let d_backend = &d_info.backend; 172 | 173 | println!( 174 | "{}\n Type: {:?}\n Driver: {} ({})\n Backend: {:?}", 175 | d_name, d_type, d_driver, d_driver_info, d_backend 176 | ); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /src/runner.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(target_arch = "wasm32"))] 2 | use futures::executor::block_on; 3 | 4 | use std::collections::HashMap; 5 | use std::marker::PhantomData; 6 | use wgpu::util::DeviceExt; 7 | 8 | pub struct DeviceInfo { 9 | pub info: wgpu::AdapterInfo, 10 | } 11 | 12 | // #[cfg(target_arch = "wasm32")] 13 | // pub struct Device { 14 | // pub device: wgpu::Device, 15 | // pub queue: wgpu::Queue, 16 | // } 17 | // #[cfg(not(target_arch = "wasm32"))] 18 | pub struct Device { 19 | pub device: wgpu::Device, 20 | pub queue: wgpu::Queue, 21 | pub info: Option, 22 | } 23 | 24 | pub struct GPUData { 25 | pub staging_buffer: wgpu::Buffer, 26 | pub storage_buffer: wgpu::Buffer, 27 | pub size: u64, 28 | pub phantom: PhantomData, 29 | } 30 | 31 | impl Device { 32 | #[cfg(target_arch = "wasm32")] 33 | pub async fn new() -> Self { 34 | let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { 35 | backends: wgpu::Backends::all(), 36 | ..Default::default() 37 | }); 38 | 39 | let adapter = instance 40 | .request_adapter(&wgpu::RequestAdapterOptions { 41 | power_preference: wgpu::PowerPreference::default(), 42 | compatible_surface: None, 43 | force_fallback_adapter: true, 44 | }) 45 | .await 46 | .expect("No adapter?"); 47 | 48 | let supported_limits = adapter.limits(); 49 | 50 | let (device, queue) = adapter 51 | .request_device( 52 | &wgpu::DeviceDescriptor { 53 | features: wgpu::Features::default(), 54 | limits: supported_limits, 55 | label: None, 56 | }, 57 | None, 58 | ) 59 | .await 60 | .expect("No devices?"); 61 | 62 | let info = adapter.get_info().clone(); 63 | let info = DeviceInfo { info }; 64 | 65 | Device { 66 | device, 67 | queue, 68 | info: Some(info), 69 | } 70 | } 71 | #[cfg(not(target_arch = "wasm32"))] 72 | pub fn new(device_index: usize) -> Self { 73 | let instance = wgpu::Instance::default(); 74 | let mut adapter = instance.enumerate_adapters(wgpu::Backends::PRIMARY); 75 | let adapter = adapter 76 | .nth(device_index) 77 | .expect("Device not found. Try using a different device."); 78 | let (device, queue) = block_on(adapter.request_device( 79 | &wgpu::DeviceDescriptor { 80 | features: wgpu::Features::MAPPABLE_PRIMARY_BUFFERS, 81 | limits: wgpu::Limits::default(), 82 | label: None, 83 | }, 84 | None, 85 | )) 86 | .unwrap(); 87 | let info = adapter.get_info().clone(); 88 | let info = DeviceInfo { info }; 89 | 90 | Device { 91 | device, 92 | queue, 93 | info: Some(info), 94 | } 95 | } 96 | 97 | pub fn to_device(&mut self, data: &[T]) -> GPUData<[T]> { 98 | let bytes = bytemuck::cast_slice(data); 99 | 100 | let staging_buffer = if cfg!(not(target_arch = "wasm32")) { 101 | self.device 102 | .create_buffer_init(&wgpu::util::BufferInitDescriptor { 103 | label: Some("Staging Buffer"), 104 | contents: &bytes, 105 | usage: wgpu::BufferUsages::MAP_READ 106 | | wgpu::BufferUsages::COPY_DST 107 | | wgpu::BufferUsages::COPY_SRC, 108 | }) 109 | } else { 110 | self.device.create_buffer(&wgpu::BufferDescriptor { 111 | label: None, 112 | size: bytes.len() as u64, 113 | usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, 114 | mapped_at_creation: false, 115 | }) 116 | }; 117 | 118 | let storage_buffer = if cfg!(not(target_arch = "wasm32")) { 119 | self.device.create_buffer(&wgpu::BufferDescriptor { 120 | label: None, 121 | size: bytes.len() as u64, 122 | usage: wgpu::BufferUsages::STORAGE 123 | | wgpu::BufferUsages::COPY_DST 124 | | wgpu::BufferUsages::COPY_SRC, 125 | mapped_at_creation: false, 126 | }) 127 | } else { 128 | // Preload the buffer with data if we are on web 129 | self.device 130 | .create_buffer_init(&wgpu::util::BufferInitDescriptor { 131 | label: Some("Storage Buffer"), 132 | contents: &bytes, 133 | usage: wgpu::BufferUsages::STORAGE 134 | | wgpu::BufferUsages::COPY_DST 135 | | wgpu::BufferUsages::COPY_SRC, 136 | }) 137 | }; 138 | 139 | #[cfg(not(target_arch = "wasm32"))] 140 | { 141 | let mut encoder = self 142 | .device 143 | .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); 144 | encoder.copy_buffer_to_buffer( 145 | &staging_buffer, 146 | 0, 147 | &storage_buffer, 148 | 0, 149 | bytes.len() as u64, 150 | ); 151 | 152 | self.queue.submit(Some(encoder.finish())); 153 | } 154 | 155 | GPUData { 156 | staging_buffer, 157 | storage_buffer, 158 | size: bytes.len() as u64, 159 | phantom: PhantomData, 160 | } 161 | } 162 | 163 | pub async fn get(&mut self, gpu: &GPUData<[T]>) -> Option> 164 | where 165 | T: bytemuck::Pod, 166 | { 167 | let mut encoder = self 168 | .device 169 | .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); 170 | encoder.copy_buffer_to_buffer(&gpu.storage_buffer, 0, &gpu.staging_buffer, 0, gpu.size); 171 | self.queue.submit(Some(encoder.finish())); 172 | 173 | let buffer_slice = gpu.staging_buffer.slice(0..); 174 | let (sender, receiver) = flume::bounded(1); 175 | buffer_slice.map_async(wgpu::MapMode::Read, move |v| sender.send(v).unwrap()); 176 | // let buffer_future = buffer_slice.map_async(wgpu::MapMode::Read); 177 | 178 | self.device.poll(wgpu::Maintain::Wait); 179 | 180 | // Gets contents of buffer 181 | if let Ok(Ok(())) = receiver.recv_async().await { 182 | let data = buffer_slice.get_mapped_range(); 183 | let result = data 184 | .chunks_exact(std::mem::size_of::()) 185 | .map(|b| bytemuck::from_bytes::(b).clone()) 186 | .collect(); 187 | drop(data); 188 | gpu.staging_buffer.unmap(); 189 | return Some(result); 190 | } 191 | None 192 | } 193 | 194 | pub fn compile( 195 | &self, 196 | entry: &str, 197 | shader: wgpu::ShaderModuleDescriptor, 198 | params: &GPUSetGroupLayout, 199 | ) -> Result { 200 | let mut bind_group_layouts: HashMap = HashMap::new(); 201 | let mut param_types = HashMap::new(); 202 | 203 | for (set_id, set) in ¶ms.set_bind_group_layouts { 204 | for (binding_num, binding) in set { 205 | if !param_types.contains_key(&set_id) { 206 | param_types.insert(set_id, HashMap::new()); 207 | } 208 | param_types 209 | .get_mut(&set_id) 210 | .unwrap() 211 | .insert(*binding_num, binding.1.clone()); 212 | } 213 | bind_group_layouts.insert( 214 | *set_id, 215 | self.device 216 | .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { 217 | label: None, 218 | entries: set 219 | .values() 220 | .map(|binding_layout| binding_layout.0.clone()) 221 | .collect::>() 222 | .as_slice(), 223 | }), 224 | ); 225 | } 226 | 227 | let cs_module = self.device.create_shader_module(shader); 228 | 229 | let pipeline_layout = self 230 | .device 231 | .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { 232 | label: None, 233 | bind_group_layouts: bind_group_layouts 234 | .values() 235 | .collect::>() 236 | .as_slice(), 237 | push_constant_ranges: &[], 238 | }); 239 | 240 | let pipeline = self 241 | .device 242 | .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { 243 | label: None, 244 | layout: Some(&pipeline_layout), 245 | module: &cs_module, 246 | entry_point: entry, 247 | }); 248 | 249 | Ok(GPUCompute { 250 | // param_types, 251 | bind_group_layouts, 252 | compute_pipeline: pipeline, 253 | }) 254 | } 255 | 256 | pub fn call<'a>( 257 | &mut self, 258 | gpu_compute: GPUCompute, 259 | workspace: (u32, u32, u32), 260 | args: &HashMap>, 261 | ) { 262 | let mut encoder = self 263 | .device 264 | .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); 265 | 266 | let set_num = 0; 267 | let mut bind_groups = vec![]; 268 | // for (set_num, bind_group) in &args { 269 | bind_groups.push( 270 | self.device.create_bind_group(&wgpu::BindGroupDescriptor { 271 | label: None, // TODO maybe in all these label fields, we should actually use a label 272 | layout: &gpu_compute.bind_group_layouts[&set_num], 273 | entries: args 274 | .values() 275 | .map(|binding| binding.clone()) 276 | .collect::>() 277 | .as_slice(), 278 | }), 279 | ); 280 | // } 281 | { 282 | let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { 283 | label: None, 284 | timestamp_writes: None, 285 | }); 286 | cpass.set_pipeline(&gpu_compute.compute_pipeline); 287 | 288 | for (set_num, _bind_group) in gpu_compute.bind_group_layouts { 289 | // bind_group = collection of bindings 290 | // let offsets : Vec= (0..args.len()-1).map(|_| 0).collect(); 291 | cpass.set_bind_group(set_num, &bind_groups[set_num as usize], &[]); 292 | } 293 | cpass.dispatch_workgroups(workspace.0, workspace.1, workspace.2); 294 | } 295 | self.queue.submit(Some(encoder.finish())); 296 | } 297 | } 298 | 299 | pub struct GPUCompute { 300 | // param_types: HashMap>, 301 | bind_group_layouts: HashMap, 302 | compute_pipeline: wgpu::ComputePipeline, 303 | } 304 | 305 | pub struct GPUSetGroupLayout { 306 | pub set_bind_group_layouts: HashMap>, 307 | } 308 | 309 | /// 310 | /// Helper to create the layout of bindings (along with set information.) 311 | /// This returns a `GPUSetGroupLayout` which is a HashMap with a key for a set, 312 | /// which contains a HashMap of Layout index and BindGroupLayoutEntry 313 | /// ``` 314 | /// let args = ParamsBuilder::new() 315 | /// .param::<&[i32]>(None) 316 | /// .param::(None) 317 | /// .build(Some(0)); 318 | /// ``` 319 | /// 320 | /// 321 | pub struct ParamsBuilder<'a> { 322 | pub binding_layouts: HashMap, 323 | pub binding_entry: HashMap>, 324 | } 325 | 326 | impl<'a> ParamsBuilder<'a> { 327 | pub fn new() -> Self { 328 | Self { 329 | binding_layouts: HashMap::new(), 330 | binding_entry: HashMap::new(), 331 | } 332 | } 333 | 334 | pub fn param(mut self, gpu_data: Option<&'a GPUData<[T]>>, read_only: bool) -> Self { 335 | let new_binding_layout_idx = self.binding_layouts.len() as u32; 336 | // println!("{}", String::from(core::any::type_name::())); 337 | // println!("{}",) 338 | 339 | self.binding_layouts.insert( 340 | new_binding_layout_idx, 341 | ( 342 | wgpu::BindGroupLayoutEntry { 343 | binding: new_binding_layout_idx, 344 | visibility: wgpu::ShaderStages::COMPUTE, 345 | ty: wgpu::BindingType::Buffer { 346 | ty: wgpu::BufferBindingType::Storage { 347 | read_only: read_only, 348 | }, 349 | has_dynamic_offset: false, 350 | min_binding_size: None, 351 | }, 352 | count: None, 353 | }, 354 | String::from(core::any::type_name::()), 355 | ), 356 | ); 357 | 358 | if let Some(gpu) = gpu_data { 359 | // let x = Rc::new(gpu.storage_buffer); 360 | self.binding_entry.insert( 361 | new_binding_layout_idx, 362 | wgpu::BindGroupEntry { 363 | binding: new_binding_layout_idx, 364 | resource: gpu.storage_buffer.as_entire_binding(), 365 | }, 366 | ); 367 | } 368 | self 369 | } 370 | 371 | pub fn build( 372 | self, 373 | set: Option, 374 | ) -> (GPUSetGroupLayout, HashMap>) { 375 | let mut set_bind_group_layouts = HashMap::new(); 376 | set_bind_group_layouts.insert( 377 | match set { 378 | Some(s) => s, 379 | None => 0, 380 | }, 381 | self.binding_layouts, 382 | ); 383 | ( 384 | GPUSetGroupLayout { 385 | set_bind_group_layouts, 386 | }, 387 | self.binding_entry, 388 | ) 389 | } 390 | } 391 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | sha256_rgpu 7 | 8 | 9 | 10 |

sha256_rgpu

11 |

Computes the SHA256 hash using WASM and WebGPU. GitHub

12 |

WebGPU is now available in latest Chromium / Google chrome on desktop behind an experimental flag. You can enable it at chrome://flags/#enable-unsafe-webgpu (on linux you also need to launch Chromium with --enable-features=Vulkan)

13 |

Read more about WebGPU implementation status

14 |
15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 |
23 | 24 | 46 | 47 | 48 | --------------------------------------------------------------------------------