package sm import ( "crypto" "hash" ) // Hash identifies a cryptographic hash function that is implemented in another // package. // I try to keep it consistent with the standard library type Hash struct { crypto.Hash } // HashFunc simply returns the value of h so that Hash implements SignerOpts. func (h Hash) HashFunc() crypto.Hash { return h.Hash } func (h Hash) String() string { switch h { case SM3: return "SM3" case SM3WithID: return "SM3WithID" default: // return "" return h.Hash.String() } } var ( SM3 Hash SM3WithID Hash maxHash Hash ) var SHA1 = Hash{crypto.SHA1} var SHA256 = Hash{crypto.SHA256} func init() { // A hack to get the maxHash in crypto. i := new(crypto.Hash) *i = 1 defer func() { _ = recover() SM3 = Hash{Hash: *i} SM3WithID = Hash{Hash: *i + 1} maxHash = Hash{Hash: *i + 2} }() for { (*i).Size() *i++ } } // Size returns the length, in bytes, of a digest resulting from the given hash // function. It doesn't require that the hash function in question be linked // into the program. func (h Hash) Size() int { switch h { case SM3, SM3WithID: return 32 default: return h.Hash.Size() } } var hashes = make(map[Hash]func() hash.Hash) // New returns a new hash.Hash calculating the given hash function. New panics // if the hash function is not linked into the binary. func (h Hash) New() hash.Hash { if h.Hash >= SM3.Hash && h.Hash < maxHash.Hash { f := hashes[h] if f != nil { return f() } } return h.Hash.New() } // Available reports whether the given hash function is linked into the binary. func (h Hash) Available() bool { if h.Hash >= SM3.Hash && h.Hash < maxHash.Hash { return true } return h.Hash.Available() } // RegisterHash registers a function that returns a new instance of the given // hash function. This is intended to be called from the init function in // packages that implement hash functions. func RegisterHash(h Hash, f func() hash.Hash) { if h.Hash >= maxHash.Hash { panic("crypto: RegisterHash of unknown hash function") } // if h.Hash < SM3.Hash { // crypto.RegisterHash(h.Hash, f) // } hashes[h] = f }