github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/crypto/ripemd160/ripemd160.go (about) 1 // Copyright 2010 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 ripemd160 implements the RIPEMD-160 hash algorithm. 6 package ripemd160 // import "golang.org/x/crypto/ripemd160" 7 8 // RIPEMD-160 is designed by by Hans Dobbertin, Antoon Bosselaers, and Bart 9 // Preneel with specifications available at: 10 // http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/AB-9601.pdf. 11 12 import ( 13 "crypto" 14 "hash" 15 ) 16 17 func init() { 18 crypto.RegisterHash(crypto.RIPEMD160, New) 19 } 20 21 // The size of the checksum in bytes. 22 const Size = 20 23 24 // The block size of the hash algorithm in bytes. 25 const BlockSize = 64 26 27 const ( 28 _s0 = 0x67452301 29 _s1 = 0xefcdab89 30 _s2 = 0x98badcfe 31 _s3 = 0x10325476 32 _s4 = 0xc3d2e1f0 33 ) 34 35 // digest represents the partial evaluation of a checksum. 36 type digest struct { 37 s [5]uint32 // running context 38 x [BlockSize]byte // temporary buffer 39 nx int // index into x 40 tc uint64 // total count of bytes processed 41 } 42 43 func (d *digest) Reset() { 44 d.s[0], d.s[1], d.s[2], d.s[3], d.s[4] = _s0, _s1, _s2, _s3, _s4 45 d.nx = 0 46 d.tc = 0 47 } 48 49 // New returns a new hash.Hash computing the checksum. 50 func New() hash.Hash { 51 result := new(digest) 52 result.Reset() 53 return result 54 } 55 56 func (d *digest) Size() int { return Size } 57 58 func (d *digest) BlockSize() int { return BlockSize } 59 60 func (d *digest) Write(p []byte) (nn int, err error) { 61 nn = len(p) 62 d.tc += uint64(nn) 63 if d.nx > 0 { 64 n := len(p) 65 if n > BlockSize-d.nx { 66 n = BlockSize - d.nx 67 } 68 for i := 0; i < n; i++ { 69 d.x[d.nx+i] = p[i] 70 } 71 d.nx += n 72 if d.nx == BlockSize { 73 _Block(d, d.x[0:]) 74 d.nx = 0 75 } 76 p = p[n:] 77 } 78 n := _Block(d, p) 79 p = p[n:] 80 if len(p) > 0 { 81 d.nx = copy(d.x[:], p) 82 } 83 return 84 } 85 86 func (d0 *digest) Sum(in []byte) []byte { 87 // Make a copy of d0 so that caller can keep writing and summing. 88 d := *d0 89 90 // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. 91 tc := d.tc 92 var tmp [64]byte 93 tmp[0] = 0x80 94 if tc%64 < 56 { 95 d.Write(tmp[0 : 56-tc%64]) 96 } else { 97 d.Write(tmp[0 : 64+56-tc%64]) 98 } 99 100 // Length in bits. 101 tc <<= 3 102 for i := uint(0); i < 8; i++ { 103 tmp[i] = byte(tc >> (8 * i)) 104 } 105 d.Write(tmp[0:8]) 106 107 if d.nx != 0 { 108 panic("d.nx != 0") 109 } 110 111 var digest [Size]byte 112 for i, s := range d.s { 113 digest[i*4] = byte(s) 114 digest[i*4+1] = byte(s >> 8) 115 digest[i*4+2] = byte(s >> 16) 116 digest[i*4+3] = byte(s >> 24) 117 } 118 119 return append(in, digest[:]...) 120 }