2021-10-27 07:44:59 +00:00
|
|
|
package checksum
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/hex"
|
2022-07-07 10:51:05 +00:00
|
|
|
"errors"
|
2021-10-27 07:44:59 +00:00
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
2021-03-22 10:56:18 +00:00
|
|
|
"github.com/nspcc-dev/tzhash/tz"
|
2021-10-27 07:44:59 +00:00
|
|
|
)
|
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
// Checksum represents checksum of some digital data.
|
|
|
|
//
|
|
|
|
// Checksum is mutually compatible with github.com/nspcc-dev/neofs-api-go/v2/refs.Checksum
|
|
|
|
// message. See ReadFromV2 / WriteToV2 methods.
|
|
|
|
//
|
|
|
|
// Instances can be created using built-in var declaration.
|
|
|
|
//
|
|
|
|
// Note that direct typecast is not safe and may result in loss of compatibility:
|
|
|
|
// _ = Checksum(refs.Checksum{}) // not recommended
|
2021-10-27 07:44:59 +00:00
|
|
|
type Checksum refs.Checksum
|
|
|
|
|
|
|
|
// Type represents the enumeration
|
|
|
|
// of checksum types.
|
|
|
|
type Type uint8
|
|
|
|
|
|
|
|
const (
|
|
|
|
// Unknown is an undefined checksum type.
|
|
|
|
Unknown Type = iota
|
|
|
|
|
|
|
|
// SHA256 is a SHA256 checksum type.
|
|
|
|
SHA256
|
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
// TZ is a Tillich-Zémor checksum type.
|
2021-10-27 07:44:59 +00:00
|
|
|
TZ
|
|
|
|
)
|
|
|
|
|
2022-07-07 10:51:05 +00:00
|
|
|
// ReadFromV2 reads Checksum from the refs.Checksum message. Checks if the
|
|
|
|
// message conforms to NeoFS API V2 protocol.
|
2021-10-27 07:44:59 +00:00
|
|
|
//
|
2021-03-22 10:56:18 +00:00
|
|
|
// See also WriteToV2.
|
2022-07-07 10:51:05 +00:00
|
|
|
func (c *Checksum) ReadFromV2(m refs.Checksum) error {
|
|
|
|
if len(m.GetSum()) == 0 {
|
|
|
|
return errors.New("missing value")
|
|
|
|
}
|
|
|
|
|
|
|
|
switch m.GetType() {
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("unsupported type %v", m.GetType())
|
|
|
|
case refs.SHA256, refs.TillichZemor:
|
|
|
|
}
|
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
*c = Checksum(m)
|
2022-07-07 10:51:05 +00:00
|
|
|
|
|
|
|
return nil
|
2021-10-27 07:44:59 +00:00
|
|
|
}
|
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
// WriteToV2 writes Checksum to the refs.Checksum message.
|
|
|
|
// The message must not be nil.
|
2021-10-27 07:44:59 +00:00
|
|
|
//
|
2021-03-22 10:56:18 +00:00
|
|
|
// See also ReadFromV2.
|
|
|
|
func (c Checksum) WriteToV2(m *refs.Checksum) {
|
|
|
|
*m = (refs.Checksum)(c)
|
2021-10-27 07:44:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Type returns checksum type.
|
2021-03-22 10:56:18 +00:00
|
|
|
//
|
|
|
|
// Zero Checksum has Unknown checksum type.
|
|
|
|
//
|
|
|
|
// See also SetTillichZemor and SetSHA256.
|
|
|
|
func (c Checksum) Type() Type {
|
|
|
|
v2 := (refs.Checksum)(c)
|
|
|
|
switch v2.GetType() {
|
2021-10-27 07:44:59 +00:00
|
|
|
case refs.SHA256:
|
|
|
|
return SHA256
|
|
|
|
case refs.TillichZemor:
|
|
|
|
return TZ
|
|
|
|
default:
|
|
|
|
return Unknown
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
// Value returns checksum bytes. Return value
|
|
|
|
// MUST NOT be mutated.
|
|
|
|
//
|
|
|
|
// Zero Checksum has nil sum.
|
|
|
|
//
|
|
|
|
// See also SetTillichZemor and SetSHA256.
|
|
|
|
func (c Checksum) Value() []byte {
|
|
|
|
v2 := (refs.Checksum)(c)
|
|
|
|
return v2.GetSum()
|
2021-10-27 07:44:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetSHA256 sets checksum to SHA256 hash.
|
2021-03-22 10:56:18 +00:00
|
|
|
//
|
|
|
|
// See also Calculate.
|
2021-10-27 07:44:59 +00:00
|
|
|
func (c *Checksum) SetSHA256(v [sha256.Size]byte) {
|
2021-03-22 10:56:18 +00:00
|
|
|
v2 := (*refs.Checksum)(c)
|
2021-10-27 07:44:59 +00:00
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
v2.SetType(refs.SHA256)
|
|
|
|
v2.SetSum(v[:])
|
2021-10-27 07:44:59 +00:00
|
|
|
}
|
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
// Calculate calculates checksum and sets it
|
|
|
|
// to the passed checksum. Checksum must not be nil.
|
2021-10-27 07:44:59 +00:00
|
|
|
//
|
2021-03-22 10:56:18 +00:00
|
|
|
// Does nothing if the passed type is not one of the:
|
|
|
|
// * SHA256;
|
|
|
|
// * TZ.
|
|
|
|
//
|
|
|
|
// Does not mutate the passed value.
|
|
|
|
//
|
|
|
|
// See also SetSHA256, SetTillichZemor.
|
|
|
|
func Calculate(c *Checksum, t Type, v []byte) {
|
|
|
|
switch t {
|
|
|
|
case SHA256:
|
|
|
|
c.SetSHA256(sha256.Sum256(v))
|
|
|
|
case TZ:
|
|
|
|
c.SetTillichZemor(tz.Sum(v))
|
|
|
|
default:
|
|
|
|
}
|
2021-10-27 07:44:59 +00:00
|
|
|
}
|
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
// SetTillichZemor sets checksum to Tillich-Zémor hash.
|
|
|
|
//
|
|
|
|
// See also Calculate.
|
|
|
|
func (c *Checksum) SetTillichZemor(v [tz.Size]byte) {
|
|
|
|
v2 := (*refs.Checksum)(c)
|
2021-10-27 07:44:59 +00:00
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
v2.SetType(refs.TillichZemor)
|
|
|
|
v2.SetSum(v[:])
|
2021-10-27 07:44:59 +00:00
|
|
|
}
|
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
// String implements fmt.Stringer.
|
|
|
|
//
|
|
|
|
// String is designed to be human-readable, and its format MAY differ between
|
|
|
|
// SDK versions.
|
|
|
|
func (c Checksum) String() string {
|
|
|
|
v2 := (refs.Checksum)(c)
|
|
|
|
return fmt.Sprintf("%s:%s", c.Type(), hex.EncodeToString(v2.GetSum()))
|
2021-10-27 07:44:59 +00:00
|
|
|
}
|
|
|
|
|
2021-03-22 10:56:18 +00:00
|
|
|
// String implements fmt.Stringer.
|
2021-10-27 07:44:59 +00:00
|
|
|
//
|
2021-03-22 10:56:18 +00:00
|
|
|
// String is designed to be human-readable, and its format MAY differ between
|
|
|
|
// SDK versions.
|
2021-10-27 07:44:59 +00:00
|
|
|
func (m Type) String() string {
|
|
|
|
var m2 refs.ChecksumType
|
|
|
|
|
|
|
|
switch m {
|
|
|
|
default:
|
|
|
|
m2 = refs.UnknownChecksum
|
|
|
|
case TZ:
|
|
|
|
m2 = refs.TillichZemor
|
|
|
|
case SHA256:
|
|
|
|
m2 = refs.SHA256
|
|
|
|
}
|
|
|
|
|
|
|
|
return m2.String()
|
|
|
|
}
|