The SHA256 for this sentence begins with: one, eight, two, a, seven, c and nine.

by ispon 9/11/2023, 10:08 AMwith 143 comments

by oefrhaon 9/11/2023, 4:06 PM

Since I'm slacking off, here's a straightforward, not at all optimized Go implementation:

  package main
  
  import (
      "bytes"
      "crypto/sha256"
      "encoding/hex"
      "fmt"
  )
  
  var (
      _chars = []byte("0123456789abcdef")
      _names = []string{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "a", "b", "c", "d", "e", "f"}
      _size  = len(_chars)
  )
  
  func main() {
      hexsum := make([]byte, 64)
      for i1 := 0; i1 < _size; i1++ {
          for i2 := 0; i2 < _size; i2++ {
              for i3 := 0; i3 < _size; i3++ {
                  for i4 := 0; i4 < _size; i4++ {
                      for i5 := 0; i5 < _size; i5++ {
                          for i6 := 0; i6 < _size; i6++ {
                              for i7 := 0; i7 < _size; i7++ {
                                  s := fmt.Sprintf("The SHA256 for this sentence begins with: %s, %s, %s, %s, %s, %s and %s.", _names[i1], _names[i2], _names[i3], _names[i4], _names[i5], _names[i6], _names[i7])
                                  sum := sha256.Sum256([]byte(s))
                                  hex.Encode(hexsum, sum[:])
                                  prefix := []byte{_chars[i1], _chars[i2], _chars[i3], _chars[i4], _chars[i5], _chars[i6], _chars[i7]}
                                  if bytes.HasPrefix(hexsum, prefix) {
                                      fmt.Printf("%s\n", s)
                                      fmt.Printf("%s\n", hexsum)
                                  }
                              }
                          }
                      }
                  }
              }
          }
      }
  }
Takes a few minutes on common consumer hardware. There's exactly one hit.

(Easiest optimization is wrapping the loop body in a goroutine. GOEXPERIMENT=loopvar really makes this nicer btw.)

The reply is obviously more interesting, need to come up with a lot of variations.

by rawlingon 9/11/2023, 10:17 AM

> Was just verifying your tweet's hash, and then...omg!!! I couldn't believe what I realised. The SHA256 of THIS tweet starts with exactly the same 7 characters as your tweet's hash. What are the chances of that?

As always, the real WTF is in the comments.

by gtrubetskoyon 9/11/2023, 3:49 PM

The original from July 2019 https://twitter.com/humblehack/status/1088982929940848647

$ echo -n 'The SHA256 for this sentence begins with seven, seven, f, zero, a, b, b and five.' | sha256sum 77f0abb54cd09ad7b654bd5e762d7be58e7daffd1a0da6a56f5135bd667856a3 -

by Someoneon 9/11/2023, 10:36 AM

That’s 28 bits. Loop through 256 million of these strings, and you’re bound to find a hit.

Bitcoin difficulty is at around 50 bits (https://ycharts.com/indicators/bitcoin_average_difficulty#:~....)

It also uses SHA256.

So, if my logic is right (is it? That seems awfully cheap to me), this is about 2^22 times as easy as mining a bitcoin. Bitcoin is at about $25k, so there are people who can find hits like this one for way less than a cent.

by nneonneoon 9/11/2023, 10:24 PM

Well, I got bored too, so here's some results with CUDA (on an RTX 3090):

    The SHA256 hash of this message begins with 534d765
    The SHA256 hash of this message begins with c18b2de
    The SHA256 hash of this message begins with 7fe17da2
    The SHA256 hash of this message begins with a7fdc855d
    The SHA256 hash of this message begins with 46eae34f1
My unoptimized implementation takes about 40s for 9 digits, so it will probably take about 10 minutes for 10 digits, about 3 hours for 11 digits, etc. It shouldn't be hard to use words instead of hex digits, if that's desired.

by curtisfon 9/11/2023, 5:13 PM

A semi-useful variant of this technique was posted nine months ago on Hacker News:

https://news.ycombinator.com/item?id=33704297

Generating sequential Git short commits! It's so pleasant looking I'm tempted to try using it one of my projects, but deep down I know it's not worth the hassle.

by jphon 9/11/2023, 8:54 PM

Rust implementation...

The code searches permutations of increasing length. Benchmark is 8 seconds on a MacBook Pro M1 to discover the match of 182a7c9. The code is not yet optimized.

    use std::time::SystemTime;
    use itertools::Itertools;
    use sha256::digest;

    fn main() {
        let digits: [usize; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
        let chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
        let words = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "a", "b", "c", "d", "e", "f"];
        let mut length = 2;
        let start = SystemTime::now();
        loop {
            for permutation in digits.iter().permutations(length) {
                let parts = permutation.iter().map(|x| words[**x]).collect_vec();
                let sentence = format!(
                    "The SHA256 for this sentence begins with: {} and {}.",
                    &parts[0..(parts.len() - 1)].join(", "), 
                    &parts[parts.len() - 1]
                );            
                let checksum: String = digest(&sentence);
                let starts: String = permutation.iter().map(|x| chars[**x]).collect();
                if checksum.starts_with(&starts) {
                    println!("milliseconds: {:?}, {} ", start.elapsed().unwrap().as_millis(), &sentence);
                }
            };
            length += 1;
        }
    }
Output:

    milliseconds: 3, The SHA256 for this sentence begins with: zero, b, six and two. 
    milliseconds: 54, The SHA256 for this sentence begins with: zero, e, d, eight and f. 
    milliseconds: 8279, The SHA256 for this sentence begins with: one, eight, two, a, seven, c and nine.
Repository:

https://github.com/joelparkerhenderson/sha256-sentence

by skilledon 9/11/2023, 10:19 AM

It appears to have been taken from here,

https://news.ycombinator.com/item?id=19003644 (2019)

by mgdmon 9/11/2023, 7:28 PM

Something that I'm not seeing mentioned in these comments (I may just have missed it) is that you can precompute the hash of the static part of the string and then extend it with the numbers in a loop, saving some cycles. This is because the full hex representation of a SHA hash gives you the entire internal state of the algorithm. This can lead to security vulnerabilities:

https://en.m.wikipedia.org/wiki/Length_extension_attack

by chriskwon 9/11/2023, 5:51 PM

I did something similar once (with a bit of a twist) for my bio when I was a TA in college:

"Hi! I’m a senior studying CS. My hobbies include making semantic paradoxes and my bio includes eight a’s, seventeen e’s, fourteen i’s, eight o’s, six u’s, and one wrong number"

by ispon 9/11/2023, 10:09 AM

    $ echo -n "The SHA256 for this sentence begins with: one, eight, two, a, seven, c and nine." | sha256sum
    182a7c930b0e5227ff8d24b5f4500ff2fa3ee1a57bd35e52d98c6e24c2749ae0  -

by sirabenon 9/12/2023, 5:05 AM

With some clever information hiding, you can sort of mask the brute force:

  On 2015/7/6 at 00:00, I wrote this message's hash down. It started with 1337.

  Thought #335552803: I love beef so much I made sure the sha256 of this message started with 0xbeef!
A longer example:

  $ cat predestination.txt 
  (1991/4/7 at 00:16) <siraben> I know the hash of this message before you do!
  (1991/4/7 at 00:17) <larsivi> Huh. What is it?
  (1991/4/7 at 00:18) <siraben> It starts with 1337.

  $ sha256sum predestination.txt
  1337a4654163ab48761bf8acc75a407179e700f67f97d754b08c7afeac7da70a  predestination.txt

by omoikaneon 9/11/2023, 5:03 PM

Related, here is a program that prints its own SHA-512 hash:

https://www.ioccc.org/years.html#2019_diels-grabsch2

by danbrucon 9/11/2023, 8:13 PM

After picking some scheme to generate messages that predict n bits of their hash in some form, the chance of finding at least one message that correctly predicts its hash is 1 - (1 - 1/x)^x where x is 2^n. This approaches 1 - 1/e = 63.2 % for large n. So by trying a few different schemes, for example slightly varying the prefix »The SHA256 for this sentence begins with:«, it becomes quickly very likely to succeed. In the limit of large n, for example only 5 different schemes will yield at least one correct message with 99 %.

With 5 patterns, 24 bits and SHA-1.

  The SHA-1 hash of this text starts with 051E35.
  The hash of this text starts with A943BD.
  The SHA-1 hash of this text starts with B6640C.
  The SHA-1 hash of this message starts with C3B03D.
  The SHA-1 hash of this message starts with D93717.
Or the same as before but as patterns just padding the 6 hex digits with zero zero to eight dots.

  0AF3DE..
  2AF7DF.......
  3E0E50.
  8EE84C.....
  919025...
  A57198....
  B20775.....
  DA525A........
  ED20F4..

by olafaloon 9/11/2023, 9:01 PM

Well, this nerd sniped me... I made a quick Go tool for this. You simply write a string {like|this}, and then it finds a hash with the same prefix automatically. (Hash this comment, it's also 182a7c9)

by nneonneoon 9/11/2023, 9:19 PM

I bet you could hack hashcat (or just use CUDA) to find these quickly for larger prefixes. Might make a fun (silly) challenge. Hashcat can do 21B SHA256 hashes per second on an RTX 4090; this translates into bruteforcing a 9-digit prefix in 4 seconds, a 10-digit prefix in 52 seconds, or a 11-digit prefix in about 14 minutes.

by SethTroon 9/11/2023, 10:41 PM

Took less than a minute to find a seven digit example in python

The SHA-256 of this sentence begins with 0, three, 9, four, 8, four, and 1 amazing!

The SHA256 for this sentence begins with 0, 4, five, 5, eight, 6, and 7 amazing!

Suffix extensions (hence the "amazing!") are several times faster to try than throwing away the entire sha256 state for each attempt.

by pontifieron 9/11/2023, 7:23 PM

This is similar to the vanity address generation for Bitcoin and other cryptocurrency addresses.

by dragontameron 9/12/2023, 5:23 AM

28 bits of entropy? That's definitely within brute-force regions with CPU. Possibly even single-threaded CPU honestly.

-------

GPU-level brute force is pushing ~40-bits. Assuming ~1 week of solid compute, a 6 TFlop computer has ~3.7 sextillion compute cycles. Or alternatively, that's ~3 billion clock cycles (single thread) per check to reach 2^40 bits of entropy. More than easily doable for most simple brute-force computational problems IMO.

If you go multi-GPU on top of that, you'll have even more computational work available.

by ms0on 9/15/2023, 5:31 PM

Beneath the veil of binary territories, in a subtle symphony of stillness, sevenfold zeros rise and conjure a calm masterpiece. As if celestial beacons in an ethereal night sky, they materialize in the form of an arcanum with heptadic serenity, with divine grace.

by istjohnon 9/12/2023, 3:42 AM

I now see that eyeballing the first and/or last few characters of a checksum is not going to detect a skillfully altered executable or ISO.

by Obscurity4340on 9/11/2023, 10:07 PM

Dumb question but what are the implications here? Is this problematic⌨ or is it more of an Easter egg?

by lionkoron 9/12/2023, 6:07 AM

You would get more possibilities if you allowed "eighteen" instead of "one, eight"

by sagebirdon 9/13/2023, 6:15 PM

I made https://lowhash.com to collect string with low hashes.

I am not sure who submitted "byzBLFAM4Penguin"...

by kifon 9/11/2023, 6:40 PM

Whereas the SHA256 for this sentence begins with: five, three, e, two, one, f and e.

by Alifatiskon 9/12/2023, 10:52 AM

Here's an implementation for this https://github.com/joelparkerhenderson/sha256-sentence

by Ekaroson 9/11/2023, 8:18 PM

Now a SHA256 hash that hashes to itself would be more interesting.

by nabla9on 9/11/2023, 5:20 PM

Would you believe in God if sha256 of "I am God. My name is BOB " would be 4920616D20476F642E204D79206E616D6520697320424F4220202020202020 (the text in hex)?

by Gunnerheadon 9/11/2023, 3:00 PM

I’m not sure I understand the significance. Can anyone explain?

by narcindinon 9/11/2023, 6:08 PM

This is cool. Isn't finding these the same as minting a new block of bitcoin? So definitially hard using our best understanding of algorithms, math, etc.

by bizzleDawgon 9/11/2023, 4:32 PM

It's way above my head mathematically as to if this is even possible, but it is hilarious how screwed so many things would be if sha256 was discovered to have a means to more quickly reverse at least a partial hash. Just off the top of my head:

  - SSL
  - Bitcoin (bonus: unlimited money hack if you can keep the discovery under wraps)
  - Signed updates for devices
Goodness only knows what I am missing, but that first one along is enough to cause an unmitigated disaster.

I assume these tweets are effectively brute forced given the fairly short prefix though and we're all safe

by grantmnzon 9/12/2023, 12:41 AM

See also: https://github.com/grantm/no-more-f-s-repo

by nuancebydefaulton 9/11/2023, 7:07 PM

It took some time for me to sink in why no explanation was needed. Is there a general term for such a thing, self-reflection or something the like?

by wholesomepotatoon 9/11/2023, 4:37 PM

This is only 7 * 4 bits. That's really nothing.

by matt3210on 9/11/2023, 7:09 PM

Why is X covering code as “sensitive material”?

by PaulHouleon 9/11/2023, 4:52 PM

You have to try like what, 2^24 ~ 16 million sentences to make that work?

by ms0on 9/15/2023, 5:27 PM

sha-256 of the above is 182a7c95ae9e1149eb48f0f5eedee0a184764a45e8a2cb5d986b7c57c9a42022

by Uptrendaon 9/11/2023, 11:58 PM

It's like a human-readable PoW, lol.

by fleekonpointon 9/11/2023, 8:22 PM

Reminds me of this xkcd:

https://xkcd.com/917/

by kjroseon 9/11/2023, 3:46 PM

Yay pigeon-hole principle combined with birthday attack.

by kazinatoron 9/11/2023, 2:58 PM

In this game, the rules should be that the digit 9 counts as either "nine" and "quine".