Help with sha256 code [Solved]

Not sure what’s am i missing here in this piece of code. The output is not matching with the correct value and possibly rightfully so as sha256 changes significantly with minor changes.

package main

import (
	"fmt"
  "crypto/sha256"
  "encoding/hex"
  )

func main() {

  serializedstring := "00000020b7ad78103f526078f2be76b76c6e0f8e7e4cc48d204d26000000000000000000da9a6ff076bd145134d6a590aa7b41fea803a976f3842239cffe2b33cf910783b41c885af8e96117dc1a8566\n"
  expectedvalueofhash := "4a79e221c63a7953e2606d359c3394834e237c2d04c836000000000000000000"

  first := sha256.New()
  first.Write([]byte(serializedstring))
  firstout := hex.EncodeToString(first.Sum(nil))
  second := sha256.New()
  second.Write([]byte(firstout))
  secondout := hex.EncodeToString(second.Sum(nil))

  fmt.Println("Hash Value derived   :", secondout)
  fmt.Println("Hash Value expected  :", expectedvalueofhash)
	
}

play url : https://play.golang.org/p/HvMjOaa2_Aa

Appreciate your help and looking forward for your feedback.

What makes you expect the value you expect?

(One guess, without any context - do you mean to hash the actual bytes and not their hex representation?)

the expected value is correct as you can see from below command line output. I am getting the same output with code/libraries in Ruby and Python.

$ echo -n 00000020b7ad78103f526078f2be76b76c6e0f8e7e4cc48d204d26000000000000000000da9a6ff076bd145134d6a590aa7b41fea803a976f3842239cffe2b33cf910783b41c885af8e96117dc1a8566 | xxd -r -p | openssl dgst -sha256
(stdin)= e194ddb3b8a9cd6f7a8514558dee067c09bc9bc957fe5cf7eb20d554e34f09c4
$ echo -n e194ddb3b8a9cd6f7a8514558dee067c09bc9bc957fe5cf7eb20d554e34f09c4 | xxd -r -p | openssl dgst -sha256
(stdin)= 4a79e221c63a7953e2606d359c3394834e237c2d04c836000000000000000000

  1. echo -n has explicitly no newline
  2. xxd -r -p does a transformation to your input that you do not do in your go code.

Guessing from the following output, i’d say xxd -r -p does actually the reverse of hex.EncodeToString

echo -n 00000020b7ad78103f526078f2be76b76c6e0f8e7e4cc48d204d26000000000000000000da9a6ff076bd145134d6a590aa7b41fea803a976f3842239cffe2b33cf910783b41c885af8e96117dc1a8566 | xxd -r -p
 ·­x?R`xò¾v·ln~Lč M&ښoðv½Q4֥ª{Aþ¨©vó"9Ïþ+3ϑ´ZøéaÜf%

(The % is a marker in my shell for “No EOL before EOF” and in the terminal its easily distinguishable from the actual output because of its inverted colors)

So we remove the \n from your original input and also use hex.DecodeString as a substitution for xxd -r -p, last but not least let us remove the superflous back and forth encoding from bytes to hex and back between getting the first hash and using it as input in the second stage, and then you get the following code:

package main

import (
	"fmt"
  	"crypto/sha256"
  	"encoding/hex"
)

func main() {

  serializedstring := "00000020b7ad78103f526078f2be76b76c6e0f8e7e4cc48d204d26000000000000000000da9a6ff076bd145134d6a590aa7b41fea803a976f3842239cffe2b33cf910783b41c885af8e96117dc1a8566"
  expectedvalueofhash := "4a79e221c63a7953e2606d359c3394834e237c2d04c836000000000000000000"

  first := sha256.New()
  firstBytes, _ := hex.DecodeString(serializedstring)
  first.Write(firstBytes)

  second := sha256.New()
  second.Write(first.Sum(nil))
  secondout := hex.EncodeToString(second.Sum(nil))

  fmt.Println("Hash Value derived   :", secondout)
  fmt.Println("Hash Value expected  :", expectedvalueofhash)
	
}

Diff:

--- a.go	2018-02-20 22:19:46.458371985 +0100
+++ b.go	2018-02-20 22:20:11.081566093 +0100
@@ -8,14 +8,15 @@
 
 func main() {
 
-  serializedstring := "00000020b7ad78103f526078f2be76b76c6e0f8e7e4cc48d204d26000000000000000000da9a6ff076bd145134d6a590aa7b41fea803a976f3842239cffe2b33cf910783b41c885af8e96117dc1a8566\n"
+  serializedstring := "00000020b7ad78103f526078f2be76b76c6e0f8e7e4cc48d204d26000000000000000000da9a6ff076bd145134d6a590aa7b41fea803a976f3842239cffe2b33cf910783b41c885af8e96117dc1a8566"
   expectedvalueofhash := "4a79e221c63a7953e2606d359c3394834e237c2d04c836000000000000000000"
 
   first := sha256.New()
-  first.Write([]byte(serializedstring))
-  firstout := hex.EncodeToString(first.Sum(nil))
+  firstBytes, _ := hex.DecodeString(serializedstring)
+  first.Write(firstBytes)
+
   second := sha256.New()
-  second.Write([]byte(firstout))
+  second.Write(first.Sum(nil))
   secondout := hex.EncodeToString(second.Sum(nil))
 
   fmt.Println("Hash Value derived   :", secondout)

play

2 Likes

Great, thanks @NobbZ

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.