diff --git a/tth.go b/tth.go new file mode 100644 index 0000000..b7c3892 --- /dev/null +++ b/tth.go @@ -0,0 +1,40 @@ +package libnmdc + +import ( + "encoding/base32" + "errors" + + "github.com/cxmcc/tiger" +) + +func tth(input []byte) (string, error) { + if len(input) > 1024 { + return "", errors.New("TTH content exceeded 1024 bytes") + } + + leafHash := tiger.New() + + //buff := make([]byte, 1024) + //leafHash.Write([]byte("\x00")) + //copy(buff[1:], []byte(input)) + //leafHash.Write(buff) + //fmt.Printf("%#v\n", buff) + + leafHash.Write([]byte("\x00" + string(input))) + leafHashBytes := leafHash.Sum(nil) + + rootHash := tiger.New() + //rootHash.Write([]byte("\x01")) + //rootHash.Write(leafHashBytes) + rootHash.Write([]byte("\x01" + string(leafHashBytes))) + rootHashBytes := rootHash.Sum(nil) + + /* + * The Tiger Hash function, modified to prepend the specified byte to the input + * data. This is useful for the THEX algorithm which prepends a 0x00 to leaf + * nodes and 0x01 to the hash nodes. + **/ + + // Definitely StdEncoding + return base32.StdEncoding.EncodeToString(rootHashBytes), nil +} diff --git a/tth_test.go b/tth_test.go new file mode 100644 index 0000000..e4be70c --- /dev/null +++ b/tth_test.go @@ -0,0 +1,25 @@ +package libnmdc + +import ( + "testing" +) + +func TestTTH(t *testing.T) { + + // echo -n 'hello world' | tthsum + testCases := [][2]string{ + [2]string{"hello world", "ZIIVRZDR2FD3W4KKNMNYUU3765LPPK7BWY64CHI"}, + [2]string{"", "LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ"}, + } + + for _, testCase := range testCases { + input, expected := testCase[0], testCase[1] + result, err := tth([]byte(input)) + if err != nil { + t.Fatalf("Error getting TTH for '%s': %s", input, err.Error()) + } + if result != expected { + t.Fatalf("Wrong TTH for '%s' (got '%s' expected '%s')", input, result, expected) + } + } +}