poly1305.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright 2012 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 poly1305 implements Poly1305 one-time message authentication code as
  5. // specified in https://cr.yp.to/mac/poly1305-20050329.pdf.
  6. //
  7. // Poly1305 is a fast, one-time authentication function. It is infeasible for an
  8. // attacker to generate an authenticator for a message without the key. However, a
  9. // key must only be used for a single message. Authenticating two different
  10. // messages with the same key allows an attacker to forge authenticators for other
  11. // messages with the same key.
  12. //
  13. // Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
  14. // used with a fixed key in order to generate one-time keys from an nonce.
  15. // However, in this package AES isn't used and the one-time key is specified
  16. // directly.
  17. package poly1305 // import "golang.org/x/crypto/poly1305"
  18. import "crypto/subtle"
  19. // TagSize is the size, in bytes, of a poly1305 authenticator.
  20. const TagSize = 16
  21. // Sum generates an authenticator for msg using a one-time key and puts the
  22. // 16-byte result into out. Authenticating two different messages with the same
  23. // key allows an attacker to forge messages at will.
  24. func Sum(out *[16]byte, m []byte, key *[32]byte) {
  25. sum(out, m, key)
  26. }
  27. // Verify returns true if mac is a valid authenticator for m with the given key.
  28. func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
  29. var tmp [16]byte
  30. Sum(&tmp, m, key)
  31. return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
  32. }
  33. // New returns a new MAC computing an authentication
  34. // tag of all data written to it with the given key.
  35. // This allows writing the message progressively instead
  36. // of passing it as a single slice. Common users should use
  37. // the Sum function instead.
  38. //
  39. // The key must be unique for each message, as authenticating
  40. // two different messages with the same key allows an attacker
  41. // to forge messages at will.
  42. func New(key *[32]byte) *MAC {
  43. return &MAC{
  44. mac: newMAC(key),
  45. finalized: false,
  46. }
  47. }
  48. // MAC is an io.Writer computing an authentication tag
  49. // of the data written to it.
  50. //
  51. // MAC cannot be used like common hash.Hash implementations,
  52. // because using a poly1305 key twice breaks its security.
  53. // Therefore writing data to a running MAC after calling
  54. // Sum causes it to panic.
  55. type MAC struct {
  56. mac // platform-dependent implementation
  57. finalized bool
  58. }
  59. // Size returns the number of bytes Sum will return.
  60. func (h *MAC) Size() int { return TagSize }
  61. // Write adds more data to the running message authentication code.
  62. // It never returns an error.
  63. //
  64. // It must not be called after the first call of Sum.
  65. func (h *MAC) Write(p []byte) (n int, err error) {
  66. if h.finalized {
  67. panic("poly1305: write to MAC after Sum")
  68. }
  69. return h.mac.Write(p)
  70. }
  71. // Sum computes the authenticator of all data written to the
  72. // message authentication code.
  73. func (h *MAC) Sum(b []byte) []byte {
  74. var mac [TagSize]byte
  75. h.mac.Sum(&mac)
  76. h.finalized = true
  77. return append(b, mac[:]...)
  78. }