You've already forked go-digest
mirror of
https://github.com/opencontainers/go-digest.git
synced 2025-10-28 00:55:30 +03:00
Add BLAKE3 support
This adds support for the BLAKE3 hash family with a default output size of 256-bit. Signed-off-by: Sargun Dhillon <sargun@sargun.me>
This commit is contained in:
@@ -34,6 +34,9 @@ const (
|
|||||||
// project. Other digests may be used but this one is the primary storage
|
// project. Other digests may be used but this one is the primary storage
|
||||||
// digest.
|
// digest.
|
||||||
Canonical = SHA256
|
Canonical = SHA256
|
||||||
|
// BLAKE3 is the blake3 algorithm with the default 256-bit output size
|
||||||
|
// github.com/opencontainers/go-digest/blake3 should be imported to make it available
|
||||||
|
BLAKE3 Algorithm = "blake3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
39
blake3/blake3.go
Normal file
39
blake3/blake3.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2021 OCI Contributors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
package blake3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash"
|
||||||
|
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
|
"github.com/zeebo/blake3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
digest.RegisterAlgorithm(digest.BLAKE3, &blake3hash{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type blake3hash struct{}
|
||||||
|
|
||||||
|
func (blake3hash) Available() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blake3hash) Size() int {
|
||||||
|
return blake3.New().Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blake3hash) New() hash.Hash {
|
||||||
|
return blake3.New()
|
||||||
|
}
|
||||||
38
blake3/blake3_test.go
Normal file
38
blake3/blake3_test.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2021 OCI Contributors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
package blake3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
|
"github.com/opencontainers/go-digest/testdigest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBLAKE3(t *testing.T) {
|
||||||
|
testdigest.RunTestCase(t, testdigest.TestCase{
|
||||||
|
Input: "blake3:af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262",
|
||||||
|
Algorithm: "blake3",
|
||||||
|
Encoded: "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBLAKE3Vector(t *testing.T) {
|
||||||
|
// From the BLAKE3 test vectors.
|
||||||
|
testvector := digest.BLAKE3.FromBytes([]byte{0, 1, 2, 3, 4})
|
||||||
|
expected := "blake3:b40b44dfd97e7a84a996a91af8b85188c66c126940ba7aad2e7ae6b385402aa2"
|
||||||
|
if string(testvector) != expected {
|
||||||
|
t.Fatalf("Expected: %s; Got: %s", expected, testvector)
|
||||||
|
}
|
||||||
|
}
|
||||||
12
blake3/go.mod
Normal file
12
blake3/go.mod
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
module github.com/opencontainers/go-digest/blake3
|
||||||
|
|
||||||
|
go 1.15
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/opencontainers/go-digest v0.0.0
|
||||||
|
github.com/zeebo/blake3 v0.1.1
|
||||||
|
)
|
||||||
|
|
||||||
|
replace (
|
||||||
|
github.com/opencontainers/go-digest => ../
|
||||||
|
)
|
||||||
152
digest_test.go
152
digest_test.go
@@ -1,152 +0,0 @@
|
|||||||
// Copyright 2019, 2020 OCI Contributors
|
|
||||||
// Copyright 2017 Docker, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package digest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseDigest(t *testing.T) {
|
|
||||||
for _, testcase := range []struct {
|
|
||||||
input string
|
|
||||||
err error
|
|
||||||
algorithm Algorithm
|
|
||||||
encoded string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
input: "sha256:e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b",
|
|
||||||
algorithm: "sha256",
|
|
||||||
encoded: "e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
input: "sha384:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
|
||||||
algorithm: "sha384",
|
|
||||||
encoded: "d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// empty
|
|
||||||
input: "",
|
|
||||||
err: ErrDigestInvalidFormat,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// whitespace only
|
|
||||||
input: " ",
|
|
||||||
err: ErrDigestInvalidFormat,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// empty hex
|
|
||||||
input: "sha256:",
|
|
||||||
err: ErrDigestInvalidFormat,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// hex with correct length, but whitespace only
|
|
||||||
input: "sha256: ",
|
|
||||||
err: ErrDigestInvalidFormat,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// empty hex
|
|
||||||
input: ":",
|
|
||||||
err: ErrDigestInvalidFormat,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// just hex
|
|
||||||
input: "d41d8cd98f00b204e9800998ecf8427e",
|
|
||||||
err: ErrDigestInvalidFormat,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// not hex
|
|
||||||
input: "sha256:d41d8cd98f00b204e9800m98ecf8427e",
|
|
||||||
err: ErrDigestInvalidLength,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// too short
|
|
||||||
input: "sha256:abcdef0123456789",
|
|
||||||
err: ErrDigestInvalidLength,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// too short (from different algorithm)
|
|
||||||
input: "sha512:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789",
|
|
||||||
err: ErrDigestInvalidLength,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
input: "foo:d41d8cd98f00b204e9800998ecf8427e",
|
|
||||||
err: ErrDigestUnsupported,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// repeated separators
|
|
||||||
input: "sha384__foo+bar:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
|
||||||
err: ErrDigestInvalidFormat,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// ensure that we parse, but we don't have support for the algorithm
|
|
||||||
input: "sha384.foo+bar:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
|
||||||
algorithm: "sha384.foo+bar",
|
|
||||||
encoded: "d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
|
||||||
err: ErrDigestUnsupported,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
input: "sha384_foo+bar:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
|
||||||
algorithm: "sha384_foo+bar",
|
|
||||||
encoded: "d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
|
||||||
err: ErrDigestUnsupported,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
input: "sha256+b64:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
|
||||||
algorithm: "sha256+b64",
|
|
||||||
encoded: "LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
|
||||||
err: ErrDigestUnsupported,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
input: "sha256:E58FCF7418D4390DEC8E8FB69D88C06EC07039D651FEDD3AA72AF9972E7D046B",
|
|
||||||
err: ErrDigestInvalidFormat,
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
t.Run(testcase.input, func(t *testing.T) {
|
|
||||||
digest, err := Parse(testcase.input)
|
|
||||||
if err != testcase.err {
|
|
||||||
t.Fatalf("error differed from expected while parsing %q: %v != %v", testcase.input, err, testcase.err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if testcase.err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if digest.Algorithm() != testcase.algorithm {
|
|
||||||
t.Fatalf("incorrect algorithm for parsed digest: %q != %q", digest.Algorithm(), testcase.algorithm)
|
|
||||||
}
|
|
||||||
|
|
||||||
if digest.Encoded() != testcase.encoded {
|
|
||||||
t.Fatalf("incorrect hex for parsed digest: %q != %q", digest.Encoded(), testcase.encoded)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse string return value and check equality
|
|
||||||
newParsed, err := Parse(digest.String())
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error parsing input %q: %v", testcase.input, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if newParsed != digest {
|
|
||||||
t.Fatalf("expected equal: %q != %q", newParsed, digest)
|
|
||||||
}
|
|
||||||
|
|
||||||
newFromHex := NewDigestFromEncoded(newParsed.Algorithm(), newParsed.Encoded())
|
|
||||||
if newFromHex != digest {
|
|
||||||
t.Fatalf("%v != %v", newFromHex, digest)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
80
testdigest/testdigest.go
Normal file
80
testdigest/testdigest.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
// Copyright 2021 OCI Contributors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// testdigest is a separate package, because it has some testing utilities in it that may be useful
|
||||||
|
// to other internal Algorithm implementors.
|
||||||
|
//
|
||||||
|
// It is not a stable interface and not meant for consumption outside of digest developers.
|
||||||
|
|
||||||
|
package testdigest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
pkgdigest "github.com/opencontainers/go-digest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestCase struct {
|
||||||
|
// Input the formal format of the hash, for example sha256:e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b
|
||||||
|
Input string
|
||||||
|
// If err is non-nil, then the parsing of Input is expected to return this error
|
||||||
|
Err error
|
||||||
|
// Algorithm should be an available or registered algorithm
|
||||||
|
Algorithm pkgdigest.Algorithm
|
||||||
|
// Encoded is the the encoded portion of the digest to expect, for example e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b
|
||||||
|
Encoded string
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunTestCase(t *testing.T, testcase TestCase) {
|
||||||
|
digest, err := pkgdigest.Parse(testcase.Input)
|
||||||
|
if err != testcase.Err {
|
||||||
|
t.Fatalf("error differed from expected while parsing %q: %v != %v", testcase.Input, err, testcase.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if testcase.Err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if digest.Algorithm() != testcase.Algorithm {
|
||||||
|
t.Fatalf("incorrect Algorithm for parsed digest: %q != %q", digest.Algorithm(), testcase.Algorithm)
|
||||||
|
}
|
||||||
|
|
||||||
|
if digest.Encoded() != testcase.Encoded {
|
||||||
|
t.Fatalf("incorrect hex for parsed digest: %q != %q", digest.Encoded(), testcase.Encoded)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse string return value and check equality
|
||||||
|
newParsed, err := pkgdigest.Parse(digest.String())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error parsing Input %q: %v", testcase.Input, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if newParsed != digest {
|
||||||
|
t.Fatalf("expected equal: %q != %q", newParsed, digest)
|
||||||
|
}
|
||||||
|
|
||||||
|
newFromHex := pkgdigest.NewDigestFromEncoded(newParsed.Algorithm(), newParsed.Encoded())
|
||||||
|
if newFromHex != digest {
|
||||||
|
t.Fatalf("%v != %v", newFromHex, digest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunTestCases(t *testing.T, testcases []TestCase) {
|
||||||
|
for _, testcase := range testcases {
|
||||||
|
t.Run(testcase.Input, func(t *testing.T) {
|
||||||
|
RunTestCase(t, testcase)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
116
testdigest/testdigest_test.go
Normal file
116
testdigest/testdigest_test.go
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
// Copyright 2021 OCI Contributors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package testdigest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
_ "crypto/sha256"
|
||||||
|
_ "crypto/sha512"
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseDigest(t *testing.T) {
|
||||||
|
RunTestCases(t, []TestCase{
|
||||||
|
{
|
||||||
|
Input: "sha256:e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b",
|
||||||
|
Algorithm: "sha256",
|
||||||
|
Encoded: "e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Input: "sha384:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
||||||
|
Algorithm: "sha384",
|
||||||
|
Encoded: "d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// empty
|
||||||
|
Input: "",
|
||||||
|
Err: digest.ErrDigestInvalidFormat,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// whitespace only
|
||||||
|
Input: " ",
|
||||||
|
Err: digest.ErrDigestInvalidFormat,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// empty hex
|
||||||
|
Input: "sha256:",
|
||||||
|
Err: digest.ErrDigestInvalidFormat,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// hex with correct length, but whitespace only
|
||||||
|
Input: "sha256: ",
|
||||||
|
Err: digest.ErrDigestInvalidFormat,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// empty hex
|
||||||
|
Input: ":",
|
||||||
|
Err: digest.ErrDigestInvalidFormat,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// just hex
|
||||||
|
Input: "d41d8cd98f00b204e9800998ecf8427e",
|
||||||
|
Err: digest.ErrDigestInvalidFormat,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// not hex
|
||||||
|
Input: "sha256:d41d8cd98f00b204e9800m98ecf8427e",
|
||||||
|
Err: digest. ErrDigestInvalidLength,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// too short
|
||||||
|
Input: "sha256:abcdef0123456789",
|
||||||
|
Err: digest. ErrDigestInvalidLength,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// too short (from different Algorithm)
|
||||||
|
Input: "sha512:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789",
|
||||||
|
Err: digest.ErrDigestInvalidLength,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Input: "foo:d41d8cd98f00b204e9800998ecf8427e",
|
||||||
|
Err: digest.ErrDigestUnsupported,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// repeated separators
|
||||||
|
Input: "sha384__foo+bar:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
||||||
|
Err: digest.ErrDigestInvalidFormat,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// ensure that we parse, but we don't have support for the Algorithm
|
||||||
|
Input: "sha384.foo+bar:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
||||||
|
Algorithm: "sha384.foo+bar",
|
||||||
|
Encoded: "d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
||||||
|
Err: digest. ErrDigestUnsupported,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Input: "sha384_foo+bar:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
||||||
|
Algorithm: "sha384_foo+bar",
|
||||||
|
Encoded: "d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
|
||||||
|
Err: digest. ErrDigestUnsupported,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Input: "sha256+b64:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
||||||
|
Algorithm: "sha256+b64",
|
||||||
|
Encoded: "LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
||||||
|
Err: digest. ErrDigestUnsupported,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Input: "sha256:E58FCF7418D4390DEC8E8FB69D88C06EC07039D651FEDD3AA72AF9972E7D046B",
|
||||||
|
Err: digest. ErrDigestInvalidFormat,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user