Skip to content

Commit 6096f89

Browse files
authored
Add MarshalBinary/UnmarshalBinary support (#68)
1 parent d9c3aea commit 6096f89

File tree

4 files changed

+253
-2
lines changed

4 files changed

+253
-2
lines changed

.github/workflows/go.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
max-parallel: 4
1717
matrix:
18-
go-version: [1.16.x, 1.15.x, 1.14.x]
18+
go-version: [1.20.x, 1.19.x, 1.18.x]
1919
os: [ubuntu-latest, windows-latest, macos-latest]
2020
steps:
2121
- name: Set up Go ${{ matrix.go-version }}

go.mod

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module github.com/minio/sha256-simd
22

3-
go 1.13
3+
go 1.17
44

55
require github.com/klauspost/cpuid/v2 v2.2.3
6+
7+
require golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e // indirect

sha256.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package sha256
1919
import (
2020
"crypto/sha256"
2121
"encoding/binary"
22+
"errors"
2223
"hash"
2324
)
2425

@@ -386,3 +387,82 @@ var _K = []uint32{
386387
0xbef9a3f7,
387388
0xc67178f2,
388389
}
390+
391+
const (
392+
magic256 = "sha\x03"
393+
marshaledSize = len(magic256) + 8*4 + chunk + 8
394+
)
395+
396+
func (d *digest) MarshalBinary() ([]byte, error) {
397+
b := make([]byte, 0, marshaledSize)
398+
b = append(b, magic256...)
399+
b = appendUint32(b, d.h[0])
400+
b = appendUint32(b, d.h[1])
401+
b = appendUint32(b, d.h[2])
402+
b = appendUint32(b, d.h[3])
403+
b = appendUint32(b, d.h[4])
404+
b = appendUint32(b, d.h[5])
405+
b = appendUint32(b, d.h[6])
406+
b = appendUint32(b, d.h[7])
407+
b = append(b, d.x[:d.nx]...)
408+
b = b[:len(b)+len(d.x)-d.nx] // already zero
409+
b = appendUint64(b, d.len)
410+
return b, nil
411+
}
412+
413+
func (d *digest) UnmarshalBinary(b []byte) error {
414+
if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 {
415+
return errors.New("crypto/sha256: invalid hash state identifier")
416+
}
417+
if len(b) != marshaledSize {
418+
return errors.New("crypto/sha256: invalid hash state size")
419+
}
420+
b = b[len(magic256):]
421+
b, d.h[0] = consumeUint32(b)
422+
b, d.h[1] = consumeUint32(b)
423+
b, d.h[2] = consumeUint32(b)
424+
b, d.h[3] = consumeUint32(b)
425+
b, d.h[4] = consumeUint32(b)
426+
b, d.h[5] = consumeUint32(b)
427+
b, d.h[6] = consumeUint32(b)
428+
b, d.h[7] = consumeUint32(b)
429+
b = b[copy(d.x[:], b):]
430+
b, d.len = consumeUint64(b)
431+
d.nx = int(d.len % chunk)
432+
return nil
433+
}
434+
435+
func appendUint32(b []byte, v uint32) []byte {
436+
return append(b,
437+
byte(v>>24),
438+
byte(v>>16),
439+
byte(v>>8),
440+
byte(v),
441+
)
442+
}
443+
444+
func appendUint64(b []byte, v uint64) []byte {
445+
return append(b,
446+
byte(v>>56),
447+
byte(v>>48),
448+
byte(v>>40),
449+
byte(v>>32),
450+
byte(v>>24),
451+
byte(v>>16),
452+
byte(v>>8),
453+
byte(v),
454+
)
455+
}
456+
457+
func consumeUint64(b []byte) ([]byte, uint64) {
458+
_ = b[7]
459+
x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
460+
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
461+
return b[8:], x
462+
}
463+
464+
func consumeUint32(b []byte) ([]byte, uint32) {
465+
_ = b[3]
466+
x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
467+
return b[4:], x
468+
}

0 commit comments

Comments
 (0)