/* Copyright IBM Corp. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ package util import ( "crypto/rand" "fmt" "io" "time" "github.com/golang/protobuf/ptypes/timestamp" "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/bccsp/factory" ) // ComputeSHA256 returns SHA2-256 on data func ComputeSHA256(data []byte) (hash []byte) { hash, err := factory.GetDefault().Hash(data, &bccsp.SHA256Opts{}) if err != nil { panic(fmt.Errorf("Failed computing SHA256 on [% x]", data)) } return } // ComputeSHA3256 returns SHA3-256 on data func ComputeSHA3256(data []byte) (hash []byte) { hash, err := factory.GetDefault().Hash(data, &bccsp.SHA3_256Opts{}) if err != nil { panic(fmt.Errorf("Failed computing SHA3_256 on [% x]", data)) } return } // GenerateBytesUUID returns a UUID based on RFC 4122 returning the generated bytes func GenerateBytesUUID() []byte { uuid := make([]byte, 16) _, err := io.ReadFull(rand.Reader, uuid) if err != nil { panic(fmt.Sprintf("Error generating UUID: %s", err)) } // variant bits; see section 4.1.1 uuid[8] = uuid[8]&^0xc0 | 0x80 // version 4 (pseudo-random); see section 4.1.3 uuid[6] = uuid[6]&^0xf0 | 0x40 return uuid } // GenerateUUID returns a UUID based on RFC 4122 func GenerateUUID() string { uuid := GenerateBytesUUID() return idBytesToStr(uuid) } // CreateUtcTimestamp returns a google/protobuf/Timestamp in UTC func CreateUtcTimestamp() *timestamp.Timestamp { now := time.Now().UTC() secs := now.Unix() nanos := int32(now.UnixNano() - (secs * 1000000000)) return &(timestamp.Timestamp{Seconds: secs, Nanos: nanos}) } func idBytesToStr(id []byte) string { return fmt.Sprintf("%x-%x-%x-%x-%x", id[0:4], id[4:6], id[6:8], id[8:10], id[10:]) } // ToChaincodeArgs converts string args to []byte args func ToChaincodeArgs(args ...string) [][]byte { bargs := make([][]byte, len(args)) for i, arg := range args { bargs[i] = []byte(arg) } return bargs } // ConcatenateBytes is useful for combining multiple arrays of bytes, especially for // signatures or digests over multiple fields func ConcatenateBytes(data ...[]byte) []byte { finalLength := 0 for _, slice := range data { finalLength += len(slice) } result := make([]byte, finalLength) last := 0 for _, slice := range data { for i := range slice { result[i+last] = slice[i] } last += len(slice) } return result }