Skip to content

Commit cebc9f8

Browse files
committed
Add core package (min deps) and give root package full transitive deps again.
The transitive dependencies in the root package are still managed by this whole registry system (which now resides in the 'core' package), so we have parity and *mostly* just one suite of code to maintain. You can now use this 'core' package when interested in dependency minimization. In exchange, the "register/*" imports may be required. You can just also just yank updates to go-multihash, and if you were already using it (and happen to be using one of these now-optional(-but-only-if-you-use-core))... nothing should actually change; the "register/*" imports won't be required because the root package does them for you. Some constants are replicated. This was the minimum step necessary to avoid import cycles. I'm not spending time prettifying it because we really probably ought to be refactoring this to use the package of constants in go-multicodec that's automatically generated, and yet, that is a scope limit we're trying not to cross during this changeset.
1 parent 1a96911 commit cebc9f8

File tree

8 files changed

+125
-66
lines changed

8 files changed

+125
-66
lines changed
File renamed without changes.

core/magic.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package multihash
2+
3+
import "errors"
4+
5+
// ErrSumNotSupported is returned when the Sum function code is not implemented
6+
var ErrSumNotSupported = errors.New("no such hash registered")
7+
8+
// constants
9+
const (
10+
IDENTITY = 0x00
11+
SHA1 = 0x11
12+
SHA2_256 = 0x12
13+
SHA2_512 = 0x13
14+
SHA3_224 = 0x17
15+
SHA3_256 = 0x16
16+
SHA3_384 = 0x15
17+
SHA3_512 = 0x14
18+
KECCAK_224 = 0x1A
19+
KECCAK_256 = 0x1B
20+
KECCAK_384 = 0x1C
21+
KECCAK_512 = 0x1D
22+
SHAKE_128 = 0x18
23+
SHAKE_256 = 0x19
24+
MD5 = 0xd5
25+
DBL_SHA2_256 = 0x56
26+
)

core/registry.go

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package multihash
2+
3+
import (
4+
"crypto/md5"
5+
"crypto/sha1"
6+
"crypto/sha256"
7+
"crypto/sha512"
8+
"fmt"
9+
"hash"
10+
)
11+
12+
// registry is a simple map which maps a multihash indicator number
13+
// to a standard golang Hash interface.
14+
//
15+
// Multihash indicator numbers are reserved and described in
16+
// https://github.com/multiformats/multicodec/blob/master/table.csv .
17+
// The keys used in this map must match those reservations.
18+
//
19+
// Hashers which are available in the golang stdlib will be registered automatically.
20+
// Others can be added using the Register function.
21+
var registry = make(map[uint64]func() hash.Hash)
22+
23+
// Register adds a new hash to the set available from GetHasher and Sum.
24+
//
25+
// Register has a global effect and should only be used at package init time to avoid data races.
26+
//
27+
// The indicator code should be per the numbers reserved and described in
28+
// https://github.com/multiformats/multicodec/blob/master/table.csv .
29+
//
30+
// If Register is called with the same indicator code more than once, the last call wins.
31+
// In practice, this means that if an application has a strong opinion about what implementation to use for a certain hash
32+
// (e.g., perhaps they want to override the sha256 implementation to use a special hand-rolled assembly variant
33+
// rather than the stdlib one which is registered by default),
34+
// then this can be done by making a Register call with that effect at init time in the application's main package.
35+
// This should have the desired effect because the root of the import tree has its init time effect last.
36+
func Register(indicator uint64, hasherFactory func() hash.Hash) {
37+
if hasherFactory == nil {
38+
panic("not sensible to attempt to register a nil function")
39+
}
40+
registry[indicator] = hasherFactory
41+
DefaultLengths[indicator] = hasherFactory().Size()
42+
}
43+
44+
// GetHasher returns a new hash.Hash according to the indicator code number provided.
45+
//
46+
// The indicator code should be per the numbers reserved and described in
47+
// https://github.com/multiformats/multicodec/blob/master/table.csv .
48+
//
49+
// The actual hashers available are determined by what has been registered.
50+
// The registry automatically contains those hashers which are available in the golang standard libraries
51+
// (which includes md5, sha1, sha256, sha384, sha512, and the "identity" mulithash, among others).
52+
// Other hash implementations can be made available by using the Register function.
53+
// The 'go-mulithash/register/*' packages can also be imported to gain more common hash functions.
54+
//
55+
// If an error is returned, it will match `errors.Is(err, ErrSumNotSupported)`.
56+
func GetHasher(indicator uint64) (hash.Hash, error) {
57+
factory, exists := registry[indicator]
58+
if !exists {
59+
return nil, fmt.Errorf("unknown multihash code %d (0x%x): %w", indicator, indicator, ErrSumNotSupported)
60+
}
61+
return factory(), nil
62+
}
63+
64+
// DefaultLengths maps a multihash indicator code to the output size for that hash, in units of bytes.
65+
//
66+
// This map is populated when a hash function is registered by the Register function.
67+
// It's effectively a shortcut for asking Size() on the hash.Hash.
68+
var DefaultLengths = map[uint64]int{}
69+
70+
func init() {
71+
Register(IDENTITY, func() hash.Hash { return &identityMultihash{} })
72+
Register(MD5, md5.New)
73+
Register(SHA1, sha1.New)
74+
Register(SHA2_256, sha256.New)
75+
Register(SHA2_512, sha512.New)
76+
Register(DBL_SHA2_256, func() hash.Hash { return &doubleSha256{sha256.New()} })
77+
}

register/blake2/multihash_blake2.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"github.com/minio/blake2b-simd"
1919
"golang.org/x/crypto/blake2s"
2020

21-
"github.com/multiformats/go-multihash"
21+
"github.com/multiformats/go-multihash/core"
2222
)
2323

2424
const (

register/miniosha256/multihash_miniosha256.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ package miniosha256
1515
import (
1616
"github.com/minio/sha256-simd"
1717

18-
"github.com/multiformats/go-multihash"
18+
"github.com/multiformats/go-multihash/core"
1919
)
2020

2121
func init() {

register/sha3/multihash_sha3.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818

1919
"golang.org/x/crypto/sha3"
2020

21-
"github.com/multiformats/go-multihash"
21+
"github.com/multiformats/go-multihash/core"
2222
)
2323

2424
func init() {

registry.go

+16-62
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,31 @@
11
package multihash
22

33
import (
4-
"crypto/md5"
5-
"crypto/sha1"
6-
"crypto/sha256"
7-
"crypto/sha512"
8-
"fmt"
94
"hash"
10-
)
115

12-
// registry is a simple map which maps a multihash indicator number
13-
// to a standard golang Hash interface.
14-
//
15-
// Multihash indicator numbers are reserved and described in
16-
// https://github.com/multiformats/multicodec/blob/master/table.csv .
17-
// The keys used in this map must match those reservations.
18-
//
19-
// Hashers which are available in the golang stdlib will be registered automatically.
20-
// Others can be added using the Register function.
21-
var registry = make(map[uint64]func() hash.Hash)
6+
mhreg "github.com/multiformats/go-multihash/core"
227

23-
// Register adds a new hash to the set available from GetHasher and Sum.
24-
//
25-
// Register has a global effect and should only be used at package init time to avoid data races.
26-
//
27-
// The indicator code should be per the numbers reserved and described in
28-
// https://github.com/multiformats/multicodec/blob/master/table.csv .
8+
_ "github.com/multiformats/go-multihash/register/all"
9+
_ "github.com/multiformats/go-multihash/register/miniosha256"
10+
)
11+
12+
// Register is an alias for Register in the core package.
2913
//
30-
// If Register is called with the same indicator code more than once, the last call wins.
31-
// In practice, this means that if an application has a strong opinion about what implementation to use for a certain hash
32-
// (e.g., perhaps they want to override the sha256 implementation to use a special hand-rolled assembly variant
33-
// rather than the stdlib one which is registered by default),
34-
// then this can be done by making a Register call with that effect at init time in the application's main package.
35-
// This should have the desired effect because the root of the import tree has its init time effect last.
14+
// Consider using the core package instead of this multihash package;
15+
// that package does not introduce transitive dependencies except for those you opt into,
16+
// and will can result in smaller application builds.
3617
func Register(indicator uint64, hasherFactory func() hash.Hash) {
37-
if hasherFactory == nil {
38-
panic("not sensible to attempt to register a nil function")
39-
}
40-
registry[indicator] = hasherFactory
41-
DefaultLengths[indicator] = hasherFactory().Size()
18+
mhreg.Register(indicator, hasherFactory)
4219
}
4320

44-
// GetHasher returns a new hash.Hash according to the indicator code number provided.
45-
//
46-
// The indicator code should be per the numbers reserved and described in
47-
// https://github.com/multiformats/multicodec/blob/master/table.csv .
48-
//
49-
// The actual hashers available are determined by what has been registered.
50-
// The registry automatically contains those hashers which are available in the golang standard libraries
51-
// (which includes md5, sha1, sha256, sha384, sha512, and the "identity" mulithash, among others).
52-
// Other hash implementations can be made available by using the Register function.
53-
// The 'go-mulithash/register/*' packages can also be imported to gain more common hash functions.
21+
// Register is an alias for Register in the core package.
5422
//
55-
// If an error is returned, it will match `errors.Is(err, ErrSumNotSupported)`.
23+
// Consider using the core package instead of this multihash package;
24+
// that package does not introduce transitive dependencies except for those you opt into,
25+
// and will can result in smaller application builds.
5626
func GetHasher(indicator uint64) (hash.Hash, error) {
57-
factory, exists := registry[indicator]
58-
if !exists {
59-
return nil, fmt.Errorf("unknown multihash code %d (0x%x): %w", indicator, indicator, ErrSumNotSupported)
60-
}
61-
return factory(), nil
27+
return mhreg.GetHasher(indicator)
6228
}
6329

6430
// DefaultLengths maps a multihash indicator code to the output size for that hash, in units of bytes.
65-
//
66-
// This map is populated when a hash function is registered by the Register function.
67-
// It's effectively a shortcut for asking Size() on the hash.Hash.
68-
var DefaultLengths = map[uint64]int{}
69-
70-
func init() {
71-
Register(IDENTITY, func() hash.Hash { return &identityMultihash{} })
72-
Register(MD5, md5.New)
73-
Register(SHA1, sha1.New)
74-
Register(SHA2_256, sha256.New)
75-
Register(SHA2_512, sha512.New)
76-
Register(DBL_SHA2_256, func() hash.Hash { return &doubleSha256{sha256.New()} })
77-
}
31+
var DefaultLengths = mhreg.DefaultLengths

sum.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ package multihash
33
import (
44
"errors"
55
"fmt"
6+
7+
mhreg "github.com/multiformats/go-multihash/core"
68
)
79

810
// ErrSumNotSupported is returned when the Sum function code is not implemented
9-
var ErrSumNotSupported = errors.New("no such hash registered")
11+
var ErrSumNotSupported = mhreg.ErrSumNotSupported
1012

1113
var ErrLenTooLarge = errors.New("requested length was too large for digest")
1214

0 commit comments

Comments
 (0)