// Copyright 2019 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // +build ppc64le,!gccgo,!appengine package poly1305 //go:noescape func initialize(state *[7]uint64, key *[32]byte) //go:noescape func update(state *[7]uint64, msg []byte) //go:noescape func finalize(tag *[TagSize]byte, state *[7]uint64) // Sum generates an authenticator for m using a one-time key and puts the // 16-byte result into out. Authenticating two different messages with the same // key allows an attacker to forge messages at will. func Sum(out *[16]byte, m []byte, key *[32]byte) { h := newMAC(key) h.Write(m) h.Sum(out) } func newMAC(key *[32]byte) (h mac) { initialize(&h.state, key) return } type mac struct { state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 } buffer [TagSize]byte offset int } func (h *mac) Write(p []byte) (n int, err error) { n = len(p) if h.offset > 0 { remaining := TagSize - h.offset if n < remaining { h.offset += copy(h.buffer[h.offset:], p) return n, nil } copy(h.buffer[h.offset:], p[:remaining]) p = p[remaining:] h.offset = 0 update(&h.state, h.buffer[:]) } if nn := len(p) - (len(p) % TagSize); nn > 0 { update(&h.state, p[:nn]) p = p[nn:] } if len(p) > 0 { h.offset += copy(h.buffer[h.offset:], p) } return n, nil } func (h *mac) Sum(out *[16]byte) { state := h.state if h.offset > 0 { update(&state, h.buffer[:h.offset]) } finalize(out, &state) }