zawy12 / difficulty-algorithms

See the Issues for difficulty algorithms
MIT License
107 stars 25 forks source link

Difficulty algorithm for interesting hashes instead of lowest target #74

Open zawy12 opened 1 year ago

zawy12 commented 1 year ago

If you use sha256 on this message: The Fed Sux $8.135031041634 trillion's worth. You'll see the hash is: ccccca55112f200bbbadd7944477442228750ee76bba5dd520faa7be00d460fc The decimal part after in the $8.1 T was functioning as the nonce in looking for an interesting hash as opposed to looking for the lowest target. As it indicates, it took 35 billion nonces. I defined "order" in the search as the most hex symbols that are repeats. The number of repeats in the hash is 21. The expected number of leading zeros in 35 B hashes is only 8. It has a lot more of repeats because they don't need to be leading, contiguous, or restricted to "0". Even just 300k hashes can find some simple-looking strings.

Perl on my systems was just as fast as Python in solving sha256 (1 M/s) after installing SHA256 module with:

$ cpan install Crypt:Digest:SHA256

The script:

#!usr/bin/perl
# usage:  $ perl file_name.pl
use Crypt::Digest::SHA256 sha256_hex;
$|=1; # flush output immediately.
$nonce = 1; 
$win = 14;   # initial difficulty
while(1) {
  $nonce++;
  $message = "The Fed Sux \$8.$nonce trillion's worth.";
  $k = $hash = sha256_hex($m);  # get hex hash
  next if $k !~ /^.?(.)\1+.?(.)\2+/;  # go to next nonce if it's probably not a good winner.
  $k = ~s/(.)\1+/\1/g;                   # remove all chars that repeat previous char. The slowest step.
  $s = 64 - length($k);                  # count chars removed
  next if $score < $win;                # go to next nonce if it's not at least as good as previous win
  $win = $score;  
  print "$hash $score $message\n\07"; # print winner. The \07 causes a beep
  open(F,">>fed_sux.txt"); print F "$hash $score $message\n"; close F;   # save winners in file
}

The above can be run as a compressed 1-liner directly on the command line (after Crypt::Digest module is installed) by copy-pasting the following.

perl -e 'use Crypt::Digest::SHA256 sha256_hex;$|=1;$nonce=1;$w=14;while(1){$nonce++;$m="The Fed Sux \$8.$nonce trillion'\''s worth.";$k=$j=sha256_hex($m);next if $k!~/^.?(.)\1+.?(.)\2+/;$k=~s/(.)\1+/\1/g;$s=64-length($k);next if $s<$w;$w=$s;print "$j $s $m\n\07";open(F,">>fed_sux.txt");print F "$j $s $m\n";close F;}'

Instead of printing just the best winners, I gave the above a difficulty algorithm (WTEMA = ~ASERT) to keep changing the difficulty up and down to let good hashes print to the command line according to a block time. Each message with its nonce is the same as a block header except it doesn't include the prior block's hash. Here's the Perl script with plenty of comments.

https://github.com/zawy12/difficulty-algorithms/blob/master/fed_sux.pl

Each step up in difficulty would be 16x harder if this just counted leading (hex) zeros.

Each of the following metrics for "order" took about 100 M hashes

The above method:
$out2 =~ s/(.)\1+/$1/g; # remove all sequential repeats. The shortest resulting string is the highest "order"

c5551118690e5216e04cc727dbe3eee0ee660681fecf99112555c7777d455111

Biased towards 3's
$out2 =~ s/(.)\1\1+/$1/g;  # at least 2 repeats
3dddc793ee0b5b34e3c61111abbb9788810fff2ec65a3456f7c6aaa48ad22299

Shannon entropy at 140 M hashes had 3.2 instead of 4 bits per hex and you can 
intuitively see there's some order but have to reason out why.
ba8a56220650d15120e53a2bb0102e2e65ed0215212b5922a2e2b929221b2a26

PoW
0000000ea5cded1564efef1223ec9783bff30511d754b27a9454765b12e86a85

An 8x8 matrix of hex values looking for any adjacent repeats in the matrix gave this after only 8 M hashes. Notice it found a lot of a's in the middle of the matrix. b6a6dd000ee31d2a6aaaa85967aaaccb189aaac29bf3aaa3718ccc5005bc414f

The following string was found at 13 B hashes is the result of giving 2x credit if next hex was the same, zero credit for the one after, and then 1 credit for the 3rd & 4th. It gave interesting results quickly at 330k. This gave 21 "repeats" (not necessarily sequential due to the scoring) in 1/3 the hashes it took the above "direct repeat" method. 799b1a255555557917787cbbbb82d42292ea6222c766a5d13333f42fffd18c81

This 2.87 B number hashes to something that has only numbers and a's in the hex:

2873302938
16a1672809451a31932425263276a01529707039473360a5201491241722a824

This was a little lucky because you'd expect one of these that's missing 5 of the possible symbols to occur only once every 16^64 / (16-5)^64 = 26 B hashes

Displaying the sha256 outputs in a 16x16 binary matrix to represent black and white pixels failed to show any recognizable match to a target image. For example, I tried to let a random search match a heart that was 3 pixels wide by scoring a 1 for each correct pixel. A compression scheme that allows a lot of error in the compressed values might work better.