sum_ppc64le.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. // +build ppc64le,!gccgo,!appengine
  5. package poly1305
  6. //go:noescape
  7. func initialize(state *[7]uint64, key *[32]byte)
  8. //go:noescape
  9. func update(state *[7]uint64, msg []byte)
  10. //go:noescape
  11. func finalize(tag *[TagSize]byte, state *[7]uint64)
  12. // Sum generates an authenticator for m using a one-time key and puts the
  13. // 16-byte result into out. Authenticating two different messages with the same
  14. // key allows an attacker to forge messages at will.
  15. func Sum(out *[16]byte, m []byte, key *[32]byte) {
  16. h := newMAC(key)
  17. h.Write(m)
  18. h.Sum(out)
  19. }
  20. func newMAC(key *[32]byte) (h mac) {
  21. initialize(&h.state, key)
  22. return
  23. }
  24. type mac struct {
  25. state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 }
  26. buffer [TagSize]byte
  27. offset int
  28. }
  29. func (h *mac) Write(p []byte) (n int, err error) {
  30. n = len(p)
  31. if h.offset > 0 {
  32. remaining := TagSize - h.offset
  33. if n < remaining {
  34. h.offset += copy(h.buffer[h.offset:], p)
  35. return n, nil
  36. }
  37. copy(h.buffer[h.offset:], p[:remaining])
  38. p = p[remaining:]
  39. h.offset = 0
  40. update(&h.state, h.buffer[:])
  41. }
  42. if nn := len(p) - (len(p) % TagSize); nn > 0 {
  43. update(&h.state, p[:nn])
  44. p = p[nn:]
  45. }
  46. if len(p) > 0 {
  47. h.offset += copy(h.buffer[h.offset:], p)
  48. }
  49. return n, nil
  50. }
  51. func (h *mac) Sum(out *[16]byte) {
  52. state := h.state
  53. if h.offset > 0 {
  54. update(&state, h.buffer[:h.offset])
  55. }
  56. finalize(out, &state)
  57. }