Go: x/crypto: argon2id hash mismatch with reference implementation

Created on 17 Apr 2019  路  3Comments  路  Source: golang/go

What version of Go are you using (go version)?

$ go version
go version go1.12.4 linux/amd64

Does this issue reproduce with the latest release?

I'm already using latest.

What operating system and processor architecture are you using (go env)?

Archlinux from 16.04.2019
CPU:

lscpu output

Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
Address sizes: 39 bits physical, 48 bits virtual
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 2
Core(s) per socket: 4
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 142
Model name: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
Stepping: 10
CPU MHz: 800.009
CPU max MHz: 4000.0000
CPU min MHz: 400.0000
BogoMIPS: 3985.00
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 8192K
NUMA node0 CPU(s): 0-7
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp flush_l1d

go env Output

$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/zmey/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/zmey/.gopath"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build851107517=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I was using argon2 library (golang.org/x/crypto/argon2) and decid thed to check reproducibility of hash result with reference implemetation, which can be found at https://github.com/P-H-C/phc-winner-argon2 (https://godoc.org/golang.org/x/crypto/argon2 has a reference to it).

What did you expect to see?

Executing argon2() with same parameters for x/crypto lib and ref version I would expect at least same hash result and ideally similar execution time.

What did you see instead?

Instead i'v got totally irrelevant results. I'v written program and script for testing:

package main

import (
    "fmt"
    "golang.org/x/crypto/argon2"
    "time"
)

func main() {
    for iters := 2; iters <= 70000; iters *= 2 {
        tStart := time.Now()
        dkey := argon2.IDKey([]byte("SomeKey16CharLen"), []byte("somesalt"), uint32(iters), 2^16, 1, 8)
        tEnd := time.Now()
        fmt.Printf("iters: %d\tresult: %x\ttime: %v\n", iters, dkey, tEnd.Sub(tStart))
    }
}
#!/bin/bash

for ITERS in 2 4 8 16 32 64 128 256 512; do
    RESULT="$((time eval 'echo -n "SomeKey16CharLen" | phc/argon2 somesalt -id -t ${ITERS} -m 16 -p 1 -l 8') 2>&1)"
    HASH="$(grep Hash <<< "$RESULT" | awk '{print $2}')"
    TIME="$(grep real <<< "$RESULT" | awk '{print $2}')"
    echo -e "iters: ${ITERS}\tresult: ${HASH}\ttime: ${TIME}"
done



md5-0d1c00180eb6b86a0910163d1c30f70b



iters: 2    result: 1a16f5cf58fb06fd    time: 139.74碌s
iters: 4    result: e399b76071673961    time: 148.875碌s
iters: 8    result: 2556103bad749067    time: 244.746碌s
iters: 16   result: 9d2996926dabcf35    time: 439.948碌s
iters: 32   result: d42584fbf7303d72    time: 914.983碌s
iters: 64   result: e12ae1f5e7f6a6d2    time: 1.792167ms
iters: 128  result: 9d3505856901773f    time: 3.435604ms
iters: 256  result: 4029f33fc2b33910    time: 6.883196ms
iters: 512  result: aa6732b30a0bef04    time: 14.113788ms
iters: 1024 result: 04618924fc9a7dbf    time: 25.822188ms
iters: 2048 result: 662aa679f8737cb9    time: 47.643061ms
iters: 4096 result: cb5634a3bad2f2f2    time: 93.270525ms
iters: 8192 result: 021547747e42a912    time: 178.898982ms
iters: 16384    result: b4bdc42c8340cff5    time: 348.955178ms
iters: 32768    result: 6a053e39123c7f79    time: 683.547191ms
iters: 65536    result: 2f664e3585ebe007    time: 1.356076541s



md5-9b8b3020049adcdf27e6c5ecab06c3fe



iters: 2    result: 4d3ce6425c81d309    time: 0m0.193s
iters: 4    result: 7ba2b8fc42ca755d    time: 0m0.310s
iters: 8    result: de25c04e0123aba5    time: 0m0.562s
iters: 16   result: d017f15189665f13    time: 0m1.068s
iters: 32   result: 13bd536d9f5e017a    time: 0m2.048s
iters: 64   result: 5696809b6c932ce2    time: 0m3.972s
iters: 128  result: 557fd8e526c5ac81    time: 0m7.824s
iters: 256  result: 25bde0bff7f73888    time: 0m15.583s
iters: 512  result: 30585dbb577a2d31    time: 0m31.017s

So, am i dumb somewhere or it's just a bug in one of implementations?

FrozenDueToAge

Most helpful comment

I have made the same mistake at least thrice :)

All 3 comments

You used 2^16 instead of 65536 for your test code for the memory usage . The ^ operator here is actually a bitwise xor, not an exponent. With 65536 there it matches the reference binary. :)

I feel so stupid right now... :disappointed:
Thanks a lot!

I have made the same mistake at least thrice :)

Was this page helpful?
0 / 5 - 0 ratings