gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ripemd160.go (2710B)


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