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