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 package poly1305 // import "golang.org/x/crypto/poly1305" 19 20 import "crypto/subtle" 21 22 // TagSize is the size, in bytes, of a poly1305 authenticator. 23 const TagSize = 16 24 25 // Verify returns true if mac is a valid authenticator for m with the given 26 // key. 27 func Verify(mac *[16]byte, m []byte, key *[32]byte) bool { 28 var tmp [16]byte 29 Sum(&tmp, m, key) 30 return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1 31 } 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 49 // MAC is an io.Writer computing an authentication tag 50 // of the data written to it. 51 // 52 // MAC cannot be used like common hash.Hash implementations, 53 // because using a poly1305 key twice breaks its security. 54 // Therefore writing data to a running MAC after calling 55 // Sum causes it to panic. 56 type MAC struct { 57 mac // platform-dependent implementation 58 59 finalized bool 60 } 61 62 // Size returns the number of bytes Sum will return. 63 func (h *MAC) Size() int { return TagSize } 64 65 // Write adds more data to the running message authentication code. 66 // It never returns an error. 67 // 68 // It must not be called after the first call of Sum. 69 func (h *MAC) Write(p []byte) (n int, err error) { 70 if h.finalized { 71 panic("poly1305: write to MAC after Sum") 72 } 73 return h.mac.Write(p) 74 } 75 76 // Sum computes the authenticator of all data written to the 77 // message authentication code. 78 func (h *MAC) Sum(b []byte) []byte { 79 var mac [TagSize]byte 80 h.mac.Sum(&mac) 81 h.finalized = true 82 return append(b, mac[:]...) 83 } 84