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