ripemd160.go 2.6 KB

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