summaryrefslogtreecommitdiff
path: root/vendor/github.com/zeebo/blake3/api.go
diff options
context:
space:
mode:
authorLibravatar tsmethurst <tobi.smethurst@protonmail.com>2022-01-16 18:52:30 +0100
committerLibravatar tsmethurst <tobi.smethurst@protonmail.com>2022-01-16 18:52:30 +0100
commit6f5ccf435585e43a00e3cc50f4bcefac36ada818 (patch)
treeba368d27464b79b1e5d010c0662fd3e340bf108e /vendor/github.com/zeebo/blake3/api.go
parentadd go-runners to readme (diff)
downloadgotosocial-6f5ccf435585e43a00e3cc50f4bcefac36ada818.tar.xz
update dependencies
Diffstat (limited to 'vendor/github.com/zeebo/blake3/api.go')
-rw-r--r--vendor/github.com/zeebo/blake3/api.go166
1 files changed, 166 insertions, 0 deletions
diff --git a/vendor/github.com/zeebo/blake3/api.go b/vendor/github.com/zeebo/blake3/api.go
new file mode 100644
index 000000000..5de263f08
--- /dev/null
+++ b/vendor/github.com/zeebo/blake3/api.go
@@ -0,0 +1,166 @@
+// Package blake3 provides an SSE4.1/AVX2 accelerated BLAKE3 implementation.
+package blake3
+
+import (
+ "errors"
+
+ "github.com/zeebo/blake3/internal/consts"
+ "github.com/zeebo/blake3/internal/utils"
+)
+
+// Hasher is a hash.Hash for BLAKE3.
+type Hasher struct {
+ size int
+ h hasher
+}
+
+// New returns a new Hasher that has a digest size of 32 bytes.
+//
+// If you need more or less output bytes than that, use Digest method.
+func New() *Hasher {
+ return &Hasher{
+ size: 32,
+ h: hasher{
+ key: consts.IV,
+ },
+ }
+}
+
+// NewKeyed returns a new Hasher that uses the 32 byte input key and has
+// a digest size of 32 bytes.
+//
+// If you need more or less output bytes than that, use the Digest method.
+func NewKeyed(key []byte) (*Hasher, error) {
+ if len(key) != 32 {
+ return nil, errors.New("invalid key size")
+ }
+
+ h := &Hasher{
+ size: 32,
+ h: hasher{
+ flags: consts.Flag_Keyed,
+ },
+ }
+ utils.KeyFromBytes(key, &h.h.key)
+
+ return h, nil
+}
+
+// DeriveKey derives a key based on reusable key material of any
+// length, in the given context. The key will be stored in out, using
+// all of its current length.
+//
+// Context strings must be hardcoded constants, and the recommended
+// format is "[application] [commit timestamp] [purpose]", e.g.,
+// "example.com 2019-12-25 16:18:03 session tokens v1".
+func DeriveKey(context string, material []byte, out []byte) {
+ h := NewDeriveKey(context)
+ _, _ = h.Write(material)
+ _, _ = h.Digest().Read(out)
+}
+
+// NewDeriveKey returns a Hasher that is initialized with the context
+// string. See DeriveKey for details. It has a digest size of 32 bytes.
+//
+// If you need more or less output bytes than that, use the Digest method.
+func NewDeriveKey(context string) *Hasher {
+ // hash the context string and use that instead of IV
+ h := &Hasher{
+ size: 32,
+ h: hasher{
+ key: consts.IV,
+ flags: consts.Flag_DeriveKeyContext,
+ },
+ }
+
+ var buf [32]byte
+ _, _ = h.WriteString(context)
+ _, _ = h.Digest().Read(buf[:])
+
+ h.Reset()
+ utils.KeyFromBytes(buf[:], &h.h.key)
+ h.h.flags = consts.Flag_DeriveKeyMaterial
+
+ return h
+}
+
+// Write implements part of the hash.Hash interface. It never returns an error.
+func (h *Hasher) Write(p []byte) (int, error) {
+ h.h.update(p)
+ return len(p), nil
+}
+
+// WriteString is like Write but specialized to strings to avoid allocations.
+func (h *Hasher) WriteString(p string) (int, error) {
+ h.h.updateString(p)
+ return len(p), nil
+}
+
+// Reset implements part of the hash.Hash interface. It causes the Hasher to
+// act as if it was newly created.
+func (h *Hasher) Reset() {
+ h.h.reset()
+}
+
+// Clone returns a new Hasher with the same internal state.
+//
+// Modifying the resulting Hasher will not modify the original Hasher, and vice versa.
+func (h *Hasher) Clone() *Hasher {
+ return &Hasher{size: h.size, h: h.h}
+}
+
+// Size implements part of the hash.Hash interface. It returns the number of
+// bytes the hash will output in Sum.
+func (h *Hasher) Size() int {
+ return h.size
+}
+
+// BlockSize implements part of the hash.Hash interface. It returns the most
+// natural size to write to the Hasher.
+func (h *Hasher) BlockSize() int {
+ // TODO: is there a downside to picking this large size?
+ return 8192
+}
+
+// Sum implements part of the hash.Hash interface. It appends the digest of
+// the Hasher to the provided buffer and returns it.
+func (h *Hasher) Sum(b []byte) []byte {
+ if top := len(b) + h.size; top <= cap(b) && top >= len(b) {
+ h.h.finalize(b[len(b):top])
+ return b[:top]
+ }
+
+ tmp := make([]byte, h.size)
+ h.h.finalize(tmp)
+ return append(b, tmp...)
+}
+
+// Digest takes a snapshot of the hash state and returns an object that can
+// be used to read and seek through 2^64 bytes of digest output.
+func (h *Hasher) Digest() *Digest {
+ var d Digest
+ h.h.finalizeDigest(&d)
+ return &d
+}
+
+// Sum256 returns the first 256 bits of the unkeyed digest of the data.
+func Sum256(data []byte) (sum [32]byte) {
+ out := Sum512(data)
+ copy(sum[:], out[:32])
+ return sum
+}
+
+// Sum512 returns the first 512 bits of the unkeyed digest of the data.
+func Sum512(data []byte) (sum [64]byte) {
+ if len(data) <= consts.ChunkLen {
+ var d Digest
+ compressAll(&d, data, 0, consts.IV)
+ _, _ = d.Read(sum[:])
+ return sum
+ } else {
+ h := hasher{key: consts.IV}
+ h.update(data)
+ h.finalize(sum[:])
+ return sum
+ }
+}