package checksum import ( "crypto/sha256" "encoding/hex" "errors" "fmt" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" "git.frostfs.info/TrueCloudLab/tzhash/tz" ) // Checksum represents checksum of some digital data. // // Checksum is mutually compatible with git.frostfs.info/TrueCloudLab/frostfs-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 type Checksum refs.Checksum // Type represents the enumeration // of checksum types. type Type refs.ChecksumType const ( // Unknown is an undefined checksum type. Unknown Type = Type(refs.UnknownChecksum) // SHA256 is a SHA256 checksum type. SHA256 = Type(refs.SHA256) // TZ is a Tillich-Zémor checksum type. TZ = Type(refs.TillichZemor) ) // ReadFromV2 reads Checksum from the refs.Checksum message. Checks if the // message conforms to FrostFS API V2 protocol. // // See also WriteToV2. 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: } *c = Checksum(m) return nil } // WriteToV2 writes Checksum to the refs.Checksum message. // The message must not be nil. // // See also ReadFromV2. func (c Checksum) WriteToV2(m *refs.Checksum) { *m = (refs.Checksum)(c) } // Type returns checksum type. // // Zero Checksum has Unknown checksum type. // // See also SetTillichZemor and SetSHA256. func (c Checksum) Type() Type { v2 := (refs.Checksum)(c) switch v2.GetType() { case refs.SHA256: return SHA256 case refs.TillichZemor: return TZ default: return Unknown } } // 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() } // SetSHA256 sets checksum to SHA256 hash. // // See also Calculate. func (c *Checksum) SetSHA256(v [sha256.Size]byte) { v2 := (*refs.Checksum)(c) v2.SetType(refs.SHA256) v2.SetSum(v[:]) } // Calculate calculates checksum and sets it // to the passed checksum. Checksum must not be nil. // // 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: } } // SetTillichZemor sets checksum to Tillich-Zémor hash. // // See also Calculate. func (c *Checksum) SetTillichZemor(v [tz.Size]byte) { v2 := (*refs.Checksum)(c) v2.SetType(refs.TillichZemor) v2.SetSum(v[:]) } // 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())) } // String implements fmt.Stringer. // // String is designed to be human-readable, and its format MAY differ between // SDK versions. 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() }