|
- // 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)
- }
|