github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/golang.org/x/crypto/md4/md4.go (about)

     1  // Copyright 2009 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 md4 implements the MD4 hash algorithm as defined in RFC 1320.
     6  //
     7  // Deprecated: MD4 is cryptographically broken and should should only be used
     8  // where compatibility with legacy systems, not security, is the goal. Instead,
     9  // use a secure hash like SHA-256 (from crypto/sha256).
    10  package md4 // import "golang.org/x/crypto/md4"
    11  
    12  import (
    13  	"crypto"
    14  	"hash"
    15  )
    16  
    17  func init() {
    18  	crypto.RegisterHash(crypto.MD4, New)
    19  }
    20  
    21  // The size of an MD4 checksum in bytes.
    22  const Size = 16
    23  
    24  // The blocksize of MD4 in bytes.
    25  const BlockSize = 64
    26  
    27  const (
    28  	_Chunk = 64
    29  	_Init0 = 0x67452301
    30  	_Init1 = 0xEFCDAB89
    31  	_Init2 = 0x98BADCFE
    32  	_Init3 = 0x10325476
    33  )
    34  
    35  // digest represents the partial evaluation of a checksum.
    36  type digest struct {
    37  	s   [4]uint32
    38  	x   [_Chunk]byte
    39  	nx  int
    40  	len uint64
    41  }
    42  
    43  func (d *digest) Reset() {
    44  	d.s[0] = _Init0
    45  	d.s[1] = _Init1
    46  	d.s[2] = _Init2
    47  	d.s[3] = _Init3
    48  	d.nx = 0
    49  	d.len = 0
    50  }
    51  
    52  // New returns a new hash.Hash computing the MD4 checksum.
    53  func New() hash.Hash {
    54  	d := new(digest)
    55  	d.Reset()
    56  	return d
    57  }
    58  
    59  func (d *digest) Size() int { return Size }
    60  
    61  func (d *digest) BlockSize() int { return BlockSize }
    62  
    63  func (d *digest) Write(p []byte) (nn int, err error) {
    64  	nn = len(p)
    65  	d.len += uint64(nn)
    66  	if d.nx > 0 {
    67  		n := len(p)
    68  		if n > _Chunk-d.nx {
    69  			n = _Chunk - d.nx
    70  		}
    71  		for i := 0; i < n; i++ {
    72  			d.x[d.nx+i] = p[i]
    73  		}
    74  		d.nx += n
    75  		if d.nx == _Chunk {
    76  			_Block(d, d.x[0:])
    77  			d.nx = 0
    78  		}
    79  		p = p[n:]
    80  	}
    81  	n := _Block(d, p)
    82  	p = p[n:]
    83  	if len(p) > 0 {
    84  		d.nx = copy(d.x[:], p)
    85  	}
    86  	return
    87  }
    88  
    89  func (d0 *digest) Sum(in []byte) []byte {
    90  	// Make a copy of d0, so that caller can keep writing and summing.
    91  	d := new(digest)
    92  	*d = *d0
    93  
    94  	// Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
    95  	len := d.len
    96  	var tmp [64]byte
    97  	tmp[0] = 0x80
    98  	if len%64 < 56 {
    99  		d.Write(tmp[0 : 56-len%64])
   100  	} else {
   101  		d.Write(tmp[0 : 64+56-len%64])
   102  	}
   103  
   104  	// Length in bits.
   105  	len <<= 3
   106  	for i := uint(0); i < 8; i++ {
   107  		tmp[i] = byte(len >> (8 * i))
   108  	}
   109  	d.Write(tmp[0:8])
   110  
   111  	if d.nx != 0 {
   112  		panic("d.nx != 0")
   113  	}
   114  
   115  	for _, s := range d.s {
   116  		in = append(in, byte(s>>0))
   117  		in = append(in, byte(s>>8))
   118  		in = append(in, byte(s>>16))
   119  		in = append(in, byte(s>>24))
   120  	}
   121  	return in
   122  }