You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

poly1305.go 2.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. // Verify returns true if mac is a valid authenticator for m with the given
  22. // key.
  23. func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
  24. var tmp [16]byte
  25. Sum(&tmp, m, key)
  26. return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
  27. }
  28. // New returns a new MAC computing an authentication
  29. // tag of all data written to it with the given key.
  30. // This allows writing the message progressively instead
  31. // of passing it as a single slice. Common users should use
  32. // the Sum function instead.
  33. //
  34. // The key must be unique for each message, as authenticating
  35. // two different messages with the same key allows an attacker
  36. // to forge messages at will.
  37. func New(key *[32]byte) *MAC {
  38. return &MAC{
  39. mac: newMAC(key),
  40. finalized: false,
  41. }
  42. }
  43. // MAC is an io.Writer computing an authentication tag
  44. // of the data written to it.
  45. //
  46. // MAC cannot be used like common hash.Hash implementations,
  47. // because using a poly1305 key twice breaks its security.
  48. // Therefore writing data to a running MAC after calling
  49. // Sum causes it to panic.
  50. type MAC struct {
  51. mac // platform-dependent implementation
  52. finalized bool
  53. }
  54. // Size returns the number of bytes Sum will return.
  55. func (h *MAC) Size() int { return TagSize }
  56. // Write adds more data to the running message authentication code.
  57. // It never returns an error.
  58. //
  59. // It must not be called after the first call of Sum.
  60. func (h *MAC) Write(p []byte) (n int, err error) {
  61. if h.finalized {
  62. panic("poly1305: write to MAC after Sum")
  63. }
  64. return h.mac.Write(p)
  65. }
  66. // Sum computes the authenticator of all data written to the
  67. // message authentication code.
  68. func (h *MAC) Sum(b []byte) []byte {
  69. var mac [TagSize]byte
  70. h.mac.Sum(&mac)
  71. h.finalized = true
  72. return append(b, mac[:]...)
  73. }