...

Source file src/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go

Documentation: github.com/ProtonMail/go-crypto/openpgp/internal/algorithm

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package algorithm
     6  
     7  import (
     8  	"crypto"
     9  	"fmt"
    10  	"hash"
    11  )
    12  
    13  // Hash is an official hash function algorithm. See RFC 4880, section 9.4.
    14  type Hash interface {
    15  	// Id returns the algorithm ID, as a byte, of Hash.
    16  	Id() uint8
    17  	// Available reports whether the given hash function is linked into the binary.
    18  	Available() bool
    19  	// HashFunc simply returns the value of h so that Hash implements SignerOpts.
    20  	HashFunc() crypto.Hash
    21  	// New returns a new hash.Hash calculating the given hash function. New
    22  	// panics if the hash function is not linked into the binary.
    23  	New() hash.Hash
    24  	// Size returns the length, in bytes, of a digest resulting from the given
    25  	// hash function. It doesn't require that the hash function in question be
    26  	// linked into the program.
    27  	Size() int
    28  	// String is the name of the hash function corresponding to the given
    29  	// OpenPGP hash id.
    30  	String() string
    31  }
    32  
    33  // The following vars mirror the crypto/Hash supported hash functions.
    34  var (
    35  	SHA1     Hash = cryptoHash{2, crypto.SHA1}
    36  	SHA256   Hash = cryptoHash{8, crypto.SHA256}
    37  	SHA384   Hash = cryptoHash{9, crypto.SHA384}
    38  	SHA512   Hash = cryptoHash{10, crypto.SHA512}
    39  	SHA224   Hash = cryptoHash{11, crypto.SHA224}
    40  	SHA3_256 Hash = cryptoHash{12, crypto.SHA3_256}
    41  	SHA3_512 Hash = cryptoHash{14, crypto.SHA3_512}
    42  )
    43  
    44  // HashById represents the different hash functions specified for OpenPGP. See
    45  // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-14
    46  var (
    47  	HashById = map[uint8]Hash{
    48  		SHA256.Id():   SHA256,
    49  		SHA384.Id():   SHA384,
    50  		SHA512.Id():   SHA512,
    51  		SHA224.Id():   SHA224,
    52  		SHA3_256.Id(): SHA3_256,
    53  		SHA3_512.Id(): SHA3_512,
    54  	}
    55  )
    56  
    57  // cryptoHash contains pairs relating OpenPGP's hash identifier with
    58  // Go's crypto.Hash type. See RFC 4880, section 9.4.
    59  type cryptoHash struct {
    60  	id uint8
    61  	crypto.Hash
    62  }
    63  
    64  // Id returns the algorithm ID, as a byte, of cryptoHash.
    65  func (h cryptoHash) Id() uint8 {
    66  	return h.id
    67  }
    68  
    69  var hashNames = map[uint8]string{
    70  	SHA256.Id():   "SHA256",
    71  	SHA384.Id():   "SHA384",
    72  	SHA512.Id():   "SHA512",
    73  	SHA224.Id():   "SHA224",
    74  	SHA3_256.Id(): "SHA3-256",
    75  	SHA3_512.Id(): "SHA3-512",
    76  }
    77  
    78  func (h cryptoHash) String() string {
    79  	s, ok := hashNames[h.id]
    80  	if !ok {
    81  		panic(fmt.Sprintf("Unsupported hash function %d", h.id))
    82  	}
    83  	return s
    84  }
    85  
    86  // HashIdToHash returns a crypto.Hash which corresponds to the given OpenPGP
    87  // hash id.
    88  func HashIdToHash(id byte) (h crypto.Hash, ok bool) {
    89  	if hash, ok := HashById[id]; ok {
    90  		return hash.HashFunc(), true
    91  	}
    92  	return 0, false
    93  }
    94  
    95  // HashIdToHashWithSha1 returns a crypto.Hash which corresponds to the given OpenPGP
    96  // hash id, allowing sha1.
    97  func HashIdToHashWithSha1(id byte) (h crypto.Hash, ok bool) {
    98  	if hash, ok := HashById[id]; ok {
    99  		return hash.HashFunc(), true
   100  	}
   101  
   102  	if id == SHA1.Id() {
   103  		return SHA1.HashFunc(), true
   104  	}
   105  
   106  	return 0, false
   107  }
   108  
   109  // HashIdToString returns the name of the hash function corresponding to the
   110  // given OpenPGP hash id.
   111  func HashIdToString(id byte) (name string, ok bool) {
   112  	if hash, ok := HashById[id]; ok {
   113  		return hash.String(), true
   114  	}
   115  	return "", false
   116  }
   117  
   118  // HashToHashId returns an OpenPGP hash id which corresponds the given Hash.
   119  func HashToHashId(h crypto.Hash) (id byte, ok bool) {
   120  	for id, hash := range HashById {
   121  		if hash.HashFunc() == h {
   122  			return id, true
   123  		}
   124  	}
   125  
   126  	return 0, false
   127  }
   128  
   129  // HashToHashIdWithSha1 returns an OpenPGP hash id which corresponds the given Hash,
   130  // allowing instances of SHA1
   131  func HashToHashIdWithSha1(h crypto.Hash) (id byte, ok bool) {
   132  	for id, hash := range HashById {
   133  		if hash.HashFunc() == h {
   134  			return id, true
   135  		}
   136  	}
   137  
   138  	if h == SHA1.HashFunc() {
   139  		return SHA1.Id(), true
   140  	}
   141  
   142  	return 0, false
   143  }
   144  

View as plain text