1// Copyright 2019 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// +build !gccgo,!purego
6
7package poly1305
8
9//go:noescape
10func update(state *macState, msg []byte)
11
12// mac is a wrapper for macGeneric that redirects calls that would have gone to
13// updateGeneric to update.
14//
15// Its Write and Sum methods are otherwise identical to the macGeneric ones, but
16// using function pointers would carry a major performance cost.
17type mac struct{ macGeneric }
18
19func (h *mac) Write(p []byte) (int, error) {
20	nn := len(p)
21	if h.offset > 0 {
22		n := copy(h.buffer[h.offset:], p)
23		if h.offset+n < TagSize {
24			h.offset += n
25			return nn, nil
26		}
27		p = p[n:]
28		h.offset = 0
29		update(&h.macState, h.buffer[:])
30	}
31	if n := len(p) - (len(p) % TagSize); n > 0 {
32		update(&h.macState, p[:n])
33		p = p[n:]
34	}
35	if len(p) > 0 {
36		h.offset += copy(h.buffer[h.offset:], p)
37	}
38	return nn, nil
39}
40
41func (h *mac) Sum(out *[16]byte) {
42	state := h.macState
43	if h.offset > 0 {
44		update(&state, h.buffer[:h.offset])
45	}
46	finalize(out, &state.h, &state.s)
47}
48