gpu.js icon indicating copy to clipboard operation
gpu.js copied to clipboard

SHA256 Hashing

Open SpookyPool opened this issue 4 years ago • 33 comments

Hello people,

I was wondering if it's possible to do SH256 hashing with GPU.JS. If so, how would I approach this?

Thanks in advance.

SpookyPool avatar Dec 03 '20 11:12 SpookyPool

I think accelerating a single hash won't be possible or if possible, not practical. But multiple hashes can be done in parallel, provided that you have the algorithm (written in js) for a single hash.

harshkhandeparkar avatar Dec 03 '20 12:12 harshkhandeparkar

I'm working on that writing the SHA256 algo as we speak. Running it in parallel you mean with

.setOutput([100,100]);

for example?

SpookyPool avatar Dec 03 '20 14:12 SpookyPool

setOutput([100, 100]) means that the output is going to be a 100x100 array where each element in the array is going to be computed in parallel, on an independent thread on the gpu.

harshkhandeparkar avatar Dec 03 '20 14:12 harshkhandeparkar

My goal is to make a SHA256 hasher that will add a nonce. How could I add that nonce on every new thread? I'm really new to this GPU stuff

SpookyPool avatar Dec 03 '20 15:12 SpookyPool

Just like I am new to SHA lol

harshkhandeparkar avatar Dec 03 '20 16:12 harshkhandeparkar

This is pulling out my hairs... It's amazing that something like this exist. But figuring this out as a noob is terrible

SpookyPool avatar Dec 03 '20 16:12 SpookyPool

Figuring something like this as an expert is terrible, lol.

robertleeplummerjr avatar Dec 03 '20 16:12 robertleeplummerjr

Wdym by that?

SpookyPool avatar Dec 03 '20 16:12 SpookyPool

Is there a simpler version of your problem so that we can help you?

harshkhandeparkar avatar Dec 03 '20 16:12 harshkhandeparkar

SHA256 is one of the more complex algorithms you'll be up against creating to run on a GPU.

robertleeplummerjr avatar Dec 03 '20 16:12 robertleeplummerjr

Yup. I have tried to understand it a countless number of times with 0 success.

harshkhandeparkar avatar Dec 03 '20 16:12 harshkhandeparkar

Is there a simpler version of your problem so that we can help you?

Is it possible to run a calculation in the kernel and let a number (nonce) bump it up by 1 on every thread, for example. Thread 1 calculates something with nonce 0 and thread 2 calculates something with nonce 1 etc, etc,

SHA256 is one of the more complex algorithms you'll be up against creating to run on a GPU.

It is not easy indeed though. I found some javascript code to calculate SHA256 and got it almost working on the gpu.js library but I had some small issue with some operators like '|=' and lvalue.

SpookyPool avatar Dec 03 '20 16:12 SpookyPool

Is it possible to run a calculation in the kernel and let a number (nonce) bump it up by 1 on every thread, for example. Thread 1 calculates something with nonce 0 and thread 2 calculates something with nonce 1 etc, etc,

If the threads are calculating something independently then yes. You can use the this.thread.x variable as nonce.

harshkhandeparkar avatar Dec 03 '20 16:12 harshkhandeparkar

Did you get something working? I'm actually looking for something very similar and I keep getting an error with the function I'm trying based off my existing code.

It is not easy indeed though. I found some javascript code to calculate SHA256 and got it almost working on the gpu.js library but I had some small issue with some operators like '|=' and lvalue.

0xrgg avatar Dec 07 '20 00:12 0xrgg

Did you get something working? I'm actually looking for something very similar and I keep getting an error with the function I'm trying based off my existing code.

It is not easy indeed though. I found some javascript code to calculate SHA256 and got it almost working on the gpu.js library but I had some small issue with some operators like '|=' and lvalue.

No I did not. It is already very hard to do the calculation stuff with limited operators and limited Array ouputs. Also I don't know a few other things that is required for my project

SpookyPool avatar Dec 07 '20 02:12 SpookyPool

No I did not. It is already very hard to do the calculation stuff with limited operators and limited Array ouputs. Also I don't know a few other things that is required for my project

Ah man that sucks, I was looking through the documentation and it suggests you can pass functions to it, so I assumed you could make an array and for each "this.thread.x" being your nonce compute the hash into this.thread.y.... I tried this myself and just ended up with errors, but I figured that was me just using it incorrectly and there are very few examples online of people not using the library to do graphical computations.

0xrgg avatar Dec 07 '20 12:12 0xrgg

You can use just a 2D array with .setOutput(100 or 1000 or whatever) and then there will just be this.thread.x. You can return the hash. The output will have an array of all the hashes.

harshkhandeparkar avatar Dec 07 '20 12:12 harshkhandeparkar

For operators that are not supported, you might have to implement them yourself using other ones.

harshkhandeparkar avatar Dec 07 '20 12:12 harshkhandeparkar

@HarshKhandeparkar It's reassuring to know that what I want to do is possible, but I just can't figure it out. I've tried to methods so far:

Using a function with my variables declared to feed into the function and return the hash (with const kernel modified to use kernelFunction) function kernelFunction(index, lasthash, timestamp, data, nonce) { return SHA256(index + lasthash + timestamp + JSON.stringify(data) + nonce).toString(); }

Then I tried just doing it all inside createKernel, as is done on the Caesar cipher example.. const kernel = gpu.createKernel(function (index, lasthash, timestamp, data, nonce) { return SHA256(index, lasthash, timestamp, data, [this.thread.x]); }).setOutput(1024);

I get the following error with the above: const [width, height] = this.output;

TypeError: this.output is not iterable

I'm confused as to whether I need to generate an empty matrix first to populate with the hash or not (this isn't done in the Caesar cipher example)?

P.s: Apologies for hijacking the issue @SpookyPool

0xrgg avatar Dec 07 '20 13:12 0xrgg

What is SHA256 and where is it defined?

harshkhandeparkar avatar Dec 07 '20 13:12 harshkhandeparkar

NOTE: string outputs are not supported at all. Nor are strings supported inside kernels.

harshkhandeparkar avatar Dec 07 '20 13:12 harshkhandeparkar

So SHA256 is just defined as a requre: const SHA256 = require('crypto-js/sha256');

Though I did not realise strings aren't supported, I suppose I'll have to play around with the JSON object and convert before feeding to the kernel then

0xrgg avatar Dec 07 '20 13:12 0xrgg

Could you guys add me onto discord?! So we can create a group and figure this out together?! Appeljuice#0420

SpookyPool avatar Dec 07 '20 13:12 SpookyPool

So SHA256 is just defined as a requre: const SHA256 = require('crypto-js/sha256');

Though I did not realise strings aren't supported, I suppose I'll have to play around with the JSON object and convert before feeding to the kernel then

I did got my sha256 generation almost working by coverting my string to bytes array and passing that into the sha256 inside the kernel and then do the magic. But he part of the whole magic is just way beyond my limits

SpookyPool avatar Dec 07 '20 13:12 SpookyPool

External JS functions cannot be used on the GPU :(

harshkhandeparkar avatar Dec 07 '20 13:12 harshkhandeparkar

Could you guys add me onto discord?! So we can create a group and figure this out together?! Appeljuice#0420

All of us can talk on gitter if you don't mind. I don't mind discord either but gitter already has a gpu.js community. https://gitter.im/gpujs/gpu.js

harshkhandeparkar avatar Dec 07 '20 13:12 harshkhandeparkar

@HarshKhandeparkar Ahhh okay that makes sense - I just had a quick look through the sha256 script and it looks like it's calling multiple other libraries from Crypto (core, hmac256) so not sure it would be possible to just adapt that code into the same file as to avoid calling an external function. Can you think of any potential workarounds?

0xrgg avatar Dec 07 '20 13:12 0xrgg

Could you guys add me onto discord?! So we can create a group and figure this out together?! Appeljuice#0420

All of us can talk on gitter if you don't mind. I don't mind discord either but gitter already has a gpu.js community. https://gitter.im/gpujs/gpu.js

Gitter seems fine! I posted already there. U cannot use any external librarys in the kernel. You have to create your own because everything is done in numbers. I'm willing to take another shot on this sha256 stuff but I'm not sure if I will be able to get it working

SpookyPool avatar Dec 07 '20 13:12 SpookyPool

@SpookyPool Did you rewrite from the original script? Seems like such a daunting task, but it's the last step in my project before I can 100% complete it so between two minds as to whether or not I leave with current functionality

Was just trying to speculate whether or not the calculation ran by my original function would be equal to that of the GPU kernel once deviating from the library - which might break my app altogether 😮

0xrgg avatar Dec 07 '20 14:12 0xrgg

GPU.js transpiles javascript into GLSL(a much lower level language) under the hood. This compiled code is then run on the GPU. And it is a compiled language, in fact, it doesn't even support strings. Whatever you write as the kernel function will be first converted to a string and then compiled to GLSL, so whatever is defined inside the kernel function only will be transpiled. If you try to reference something undefined like the function SHA256 in your case, it will throw an error.

If at all you want external functions, you will either have to implement them yourself or transpile library function(if possible) directly. Useful: https://github.com/gpujs/gpu.js#adding-custom-functions

harshkhandeparkar avatar Dec 07 '20 14:12 harshkhandeparkar