vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.8k stars 2.16k forks source link

Behavioural bug of `crypto.sha256.Digest.checksum` and maybe other crypto hashing #19696

Closed blackshirt closed 1 year ago

blackshirt commented 1 year ago

Describe the bug

Its based my question on discord channel, at here. so, i'm going to refer to example of golang version of sha256 hash calculation. Its available as en example on golang playground at here. If we run this example, the output seem like this:

sha256 this string
736861323536207468697320737472696e67e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
1af1dfa857bf1d8814fe1af8983c18080019922e557f15a8a0d3db739d77aacb
1af1dfa857bf1d8814fe1af8983c18080019922e557f15a8a0d3db739d77aacb
1af1dfa857bf1d8814fe1af8983c18080019922e557f15a8a0d3db739d77aacb
1af1dfa857bf1d8814fe1af8983c18080019922e557f15a8a0d3db739d77aacb
1af1dfa857bf1d8814fe1af8983c18080019922e557f15a8a0d3db739d77aacb

Lets the v version of this at play.vosca.dev here...correct me if i'm wrong. if we run this example, we get output

[code.v:7] s.bytestr(): sha256 this string
[code.v:9] o1.hex(): 736861323536207468697320737472696e67e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
[code.v:12] n: 18
[code.v:18] ro2.hex(): 1af1dfa857bf1d8814fe1af8983c18080019922e557f15a8a0d3db739d77aacb
[code.v:19] ro3.hex(): e8835e9cdd1700f565412ae42fafe3359f1a79d923f50ba009661e5a1c61718f
[code.v:20] ro4.hex(): 9a22ac856d1394526387570327f61c2ae54317112adb116677ad2f22d6d87e44
[code.v:21] ro5.hex(): dd3cc3acf6f46d5b300ef4b12910c9c853be6600b3bdb4731f6cfbfbc5d56866

if we compare both of them, first Digest by call to .sum(bytes_input) directyly produces the same output with go version. but, the second Digest, with write call and then sum (or checksum) ..differs after the first sum/checksum ...only first cheksum is matching with go version. On the golang side, multiples call to .Sum(nil) or with empty bytes after .Write call ..does not change current hash output, its slightly differ with v version

Reproduction Steps

See above link and description

Expected Behavior

I think it should produce same behaviour with go version, multiple calls to .checksum() should not change current hash state..its should be changed by .write(bytes_input) call

Current Behavior

Its slightly produces different output with go version

Possible Solution

No response

Additional Information/Context

No response

V version

V 0.4.2 fae46a8

Environment details (OS name and version, etc.)

Os Windows

[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.

blackshirt commented 1 year ago

I think, this bug has been fixed, we can close this issue now.

JalonSolov commented 1 year ago

Even with latest version of V 0.4.2 690ec7d, I still get the same (incorrect) output, using the example code shown.

shove70 commented 1 year ago

Even with latest version of V 0.4.2 690ec7d, I still get the same (incorrect) output, using the example code shown.

import crypto.sha256

fn main() {
    s := 'sha256 this string'.bytes()
    dump(s.hex())

    mut d1 := sha256.new()
    o1 := d1.sum(s)
    dump(o1.hex())

    mut d2 := sha256.new()
    n := d2.write(s)!
    dump(n)

    o2 := d2.sum([]u8{})
    o3 := d2.sum([]u8{})
    dump(o2.hex())
    dump(o3.hex())
}

@JalonSolov , Is this the code?

shove70 commented 1 year ago

It outputs on my MacOS:

image

I'll test linux again, just a second

shove70 commented 1 year ago

on centos8:

image
shove70 commented 1 year ago

Could you give me some details about your environment? I'll try to reproduce it, thanks, @JalonSolov

blackshirt commented 1 year ago
import crypto.sha256

fn main() {
    s := 'sha256 this string'.bytes()
    mut d1 := sha256.new()
    mut d2 := sha256.new()
    dump(s.hex())
    o1 := d1.sum(s)
    dump(o1.hex())

    n := d2.write(s)!
    dump(n)

    ro2 := d2.checksum()
    ro3 := d2.checksum()
    ro4 := d2.checksum()
    ro5 := d2.checksum()
    dump(ro2.hex())
    dump(ro3.hex())
    dump(ro4.hex())
    dump(ro5.hex())
}

produces output

[code.v:7] s.hex(): 736861323536207468697320737472696e67
[code.v:9] o1.hex(): 736861323536207468697320737472696e67e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
[code.v:12] n: 18
[code.v:18] ro2.hex(): 1af1dfa857bf1d8814fe1af8983c18080019922e557f15a8a0d3db739d77aacb
[code.v:19] ro3.hex(): e8835e9cdd1700f565412ae42fafe3359f1a79d923f50ba009661e5a1c61718f
[code.v:20] ro4.hex(): 9a22ac856d1394526387570327f61c2ae54317112adb116677ad2f22d6d87e44
[code.v:21] ro5.hex(): dd3cc3acf6f46d5b300ef4b12910c9c853be6600b3bdb4731f6cfbfbc5d56866

is it should not change ? i dont know comparable of golang of .checksum ... the golang version has only .Sum

JalonSolov commented 1 year ago

I got the code from the playground link from the issue opening comment, which is what @blackshirt pasted just above.

shove70 commented 1 year ago

Uh-huh, I'll investigate about checksum. If necessary, I'll supplement PR :)