Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions poly1305.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
// found in the LICENSE file.

// Package poly1305 implements Poly1305 one-time message authentication code
// defined in RFC 7539..
// defined in RFC 7539.
//
// Poly1305 is a fast, one-time authentication function. It is infeasible for an
// attacker to generate an authenticator for a message without the key.
// However, a key must only be used for a single message. Authenticating two
// However, a key must be used only for a single message. Authenticating two
// different messages with the same key allows an attacker to forge
// authenticators for other messages with the same key.
package poly1305 // import "github.com/aead/poly1305"
Expand Down
7 changes: 5 additions & 2 deletions poly1305_AVX2_amd64.s
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ DATA fixPermutation<>+0x78(SB)/4, $6
DATA fixPermutation<>+0x7c(SB)/4, $7
GLOBL fixPermutation<>(SB), RODATA, $128

// func initializeAVX2(state *[AVX2Size]byte, key *[32]byte)
TEXT ·initializeAVX2(SB), $0-16
MOVQ state+0(FP), DI
MOVQ key+8(FP), SI
Expand Down Expand Up @@ -301,7 +302,8 @@ TEXT ·initializeAVX2(SB), $0-16

RET

TEXT ·updateAVX2(SB), $0-24
// func updateAVX2(state *[AVX2Size]byte, msg []byte)
TEXT ·updateAVX2(SB), $0-32
MOVQ state+0(FP), DI
MOVQ msg+8(FP), SI
MOVQ msg_len+16(FP), DX
Expand Down Expand Up @@ -815,8 +817,9 @@ DONE:
MOVD X4, 320(DI)
RET

// func finalizeAVX2(tag *[TagSize]byte, state *[AVX2Size]byte)
TEXT ·finalizeAVX2(SB), $0-16
MOVQ out+0(FP), SI
MOVQ tag+0(FP), SI
MOVQ state+8(FP), DI

VZEROUPPER
Expand Down
29 changes: 17 additions & 12 deletions poly1305_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (
"io"
)

const (
AVX2Size = 512
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe don't export the constant, clients should not know anything about the internal implementation...

AVX2Buffer = 8 * TagSize
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here...

)

var useAVX2 = supportsAVX2()

//go:noescape
Expand All @@ -19,21 +24,21 @@ func supportsAVX2() bool
func initialize(state *[7]uint64, key *[32]byte)

//go:noescape
func initializeAVX2(state *[512]byte, key *[32]byte)
func initializeAVX2(state *[AVX2Size]byte, key *[32]byte)

//go:noescape
func update(state *[7]uint64, msg []byte)

//go:noescape
func updateAVX2(state *[512]byte, msg []byte)
func updateAVX2(state *[AVX2Size]byte, msg []byte)

//go:noescape
func finalize(tag *[TagSize]byte, state *[7]uint64)

//go:noescape
func finalizeAVX2(tag *[TagSize]byte, state *[512]byte)
func finalizeAVX2(tag *[TagSize]byte, state *[AVX2Size]byte)

// compiler asserts - check that poly1305Hash and poly1305HashAVX2 implements the hash interface
// compiler asserts - check that poly1305Hash and poly1305HashAVX2 implement the hash interface
var (
_ (hash) = &poly1305Hash{}
_ (hash) = &poly1305HashAVX2{}
Expand All @@ -53,8 +58,8 @@ func Sum(msg []byte, key [32]byte) [TagSize]byte {
msg = []byte{}
}
var out [TagSize]byte
if useAVX2 && len(msg) > 8*TagSize {
var state [512]byte
if useAVX2 && len(msg) > AVX2Buffer {
var state [AVX2Size]byte
initializeAVX2(&state, &key)
updateAVX2(&state, msg)
finalizeAVX2(&out, &state)
Expand Down Expand Up @@ -95,7 +100,7 @@ func (h *Hash) Size() int { return TagSize }
// Write adds more data to the running Poly1305 hash.
// This function should return a non-nil error if a call
// to Write happens after a call to Sum. So it is not possible
// to compute the checksum and than add more data.
// to compute the checksum and then add more data.
func (h *Hash) Write(msg []byte) (int, error) {
if h.done {
return 0, errWriteAfterSum
Expand Down Expand Up @@ -123,7 +128,7 @@ func (h *poly1305Hash) Write(p []byte) (n int, err error) {
n = len(p)
if h.off > 0 {
dif := TagSize - h.off
if n <= dif {
if n < dif {
h.off += copy(h.buf[h.off:], p)
return n, nil
}
Expand All @@ -132,7 +137,7 @@ func (h *poly1305Hash) Write(p []byte) (n int, err error) {
p = p[dif:]
h.off = 0
}
// process full 16-byte blocks
// process full multiples of 16-byte blocks
if nn := len(p) & (^(TagSize - 1)); nn > 0 {
update(&(h.state), p[:nn])
p = p[nn:]
Expand All @@ -155,7 +160,7 @@ func (h *poly1305Hash) Sum(b []byte) []byte {

type poly1305HashAVX2 struct {
// r[0] | r^2[0] | r[1] | r^2[1] | r[2] | r^2[2] | r[3] | r^2[3] | r[4] | r^2[4] | r[1]*5 | r^2[1]*5 | r[2]*5 | r^2[2]*5 r[3]*5 | r^2[3]*5 r[4]*5 | r^2[4]*5
state [512]byte
state [AVX2Size]byte

buffer [8 * TagSize]byte
offset int
Expand All @@ -165,7 +170,7 @@ func (h *poly1305HashAVX2) Write(p []byte) (n int, err error) {
n = len(p)
if h.offset > 0 {
remaining := 8*TagSize - h.offset
if n <= remaining {
if n < remaining {
h.offset += copy(h.buffer[h.offset:], p)
return n, nil
}
Expand All @@ -174,7 +179,7 @@ func (h *poly1305HashAVX2) Write(p []byte) (n int, err error) {
p = p[remaining:]
h.offset = 0
}
// process full 8*16-byte blocks
// process full multiples of 8*16-byte blocks
if nn := len(p) & (^(8*TagSize - 1)); nn > 0 {
updateAVX2(&h.state, p[:nn])
p = p[nn:]
Expand Down
108 changes: 54 additions & 54 deletions poly1305_amd64.s
Original file line number Diff line number Diff line change
Expand Up @@ -11,53 +11,67 @@ DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
GLOBL ·poly1305Mask<>(SB), RODATA, $16

#define POLY1305_ADD(msg, h0, h1, h2) \
ADDQ 0(msg), h0; \
ADCQ 8(msg), h1; \
ADCQ $1, h2; \
ADDQ 0(msg), h0 \
ADCQ 8(msg), h1 \
ADCQ $1, h2 \
LEAQ 16(msg), msg

#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3) \
MOVQ r0, AX; \
MULQ h0; \
MOVQ AX, t0; \
MOVQ DX, t1; \
MOVQ r0, AX; \
MULQ h1; \
ADDQ AX, t1; \
ADCQ $0, DX; \
MOVQ r0, t2; \
IMULQ h2, t2; \
ADDQ DX, t2; \
MOVQ r0, AX \
MULQ h0 \
MOVQ AX, t0 \
MOVQ DX, t1 \
MOVQ r0, AX \
MULQ h1 \
ADDQ AX, t1 \
ADCQ $0, DX \
MOVQ r0, t2 \
IMULQ h2, t2 \
ADDQ DX, t2 \
\
MOVQ r1, AX; \
MULQ h0; \
ADDQ AX, t1; \
ADCQ $0, DX; \
MOVQ DX, h0; \
MOVQ r1, t3; \
IMULQ h2, t3; \
MOVQ r1, AX; \
MULQ h1; \
ADDQ AX, t2; \
ADCQ DX, t3; \
ADDQ h0, t2; \
ADCQ $0, t3; \
MOVQ r1, AX \
MULQ h0 \
ADDQ AX, t1 \
ADCQ $0, DX \
MOVQ DX, h0 \
MOVQ r1, t3 \
IMULQ h2, t3 \
MOVQ r1, AX \
MULQ h1 \
ADDQ AX, t2 \
ADCQ DX, t3 \
ADDQ h0, t2 \
ADCQ $0, t3 \
\
MOVQ t0, h0; \
MOVQ t1, h1; \
MOVQ t2, h2; \
ANDQ $3, h2; \
MOVQ t2, t0; \
ANDQ $0XFFFFFFFFFFFFFFFC, t0; \
ADDQ t0, h0; \
ADCQ t3, h1; \
ADCQ $0, h2; \
SHRQ $2, t3, t2; \
SHRQ $2, t3; \
ADDQ t2, h0; \
ADCQ t3, h1; \
MOVQ t0, h0 \
MOVQ t1, h1 \
MOVQ t2, h2 \
ANDQ $3, h2 \
MOVQ t2, t0 \
ANDQ $0XFFFFFFFFFFFFFFFC, t0 \
ADDQ t0, h0 \
ADCQ t3, h1 \
ADCQ $0, h2 \
SHRQ $2, t3, t2 \
SHRQ $2, t3 \
ADDQ t2, h0 \
ADCQ t3, h1 \
ADCQ $0, h2

// func initialize(state *[7]uint64, key *[32]byte)
TEXT ·initialize(SB), $0-16
MOVQ state+0(FP), DI
MOVQ key+8(FP), SI

// state[0...7] is initialized with zero
MOVOU 0(SI), X0
MOVOU 16(SI), X1
MOVOU ·poly1305Mask<>(SB), X2
PAND X2, X0
MOVOU X0, 24(DI)
MOVOU X1, 40(DI)
RET

// func update(state *[7]uint64, msg []byte)
TEXT ·update(SB), $0-32
MOVQ state+0(FP), DI
Expand Down Expand Up @@ -111,20 +125,6 @@ DONE:
MOVQ R10, 16(DI)
RET

// func initialize(state *[7]uint64, key *[32]byte)
TEXT ·initialize(SB), $0-16
MOVQ state+0(FP), DI
MOVQ key+8(FP), SI

// state[0...7] is initialized with zero
MOVOU 0(SI), X0
MOVOU 16(SI), X1
MOVOU ·poly1305Mask<>(SB), X2
PAND X2, X0
MOVOU X0, 24(DI)
MOVOU X1, 40(DI)
RET

// func finalize(tag *[TagSize]byte, state *[7]uint64)
TEXT ·finalize(SB), $0-16
MOVQ tag+0(FP), DI
Expand Down
8 changes: 4 additions & 4 deletions poly1305_ref.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (p *Hash) Size() int { return TagSize }
// Write adds more data to the running Poly1305 hash.
// This function should return a non-nil error if a call
// to Write happens after a call to Sum. So it is not possible
// to compute the checksum and than add more data.
// to compute the checksum and then add more data.
func (p *Hash) Write(msg []byte) (int, error) {
if p.done {
return 0, errWriteAfterSum
Expand All @@ -77,7 +77,7 @@ func (p *Hash) Write(msg []byte) (int, error) {

if p.off > 0 {
dif := TagSize - p.off
if n <= dif {
if n < dif {
p.off += copy(p.buf[p.off:], msg)
return n, nil
}
Expand All @@ -87,7 +87,7 @@ func (p *Hash) Write(msg []byte) (int, error) {
p.off = 0
}

// process full 16-byte blocks
// process full multiples of 16-byte blocks
if nn := len(msg) & (^(TagSize - 1)); nn > 0 {
update(msg[:nn], msgBlock, &(p.h), &(p.r))
msg = msg[nn:]
Expand All @@ -100,7 +100,7 @@ func (p *Hash) Write(msg []byte) (int, error) {
return n, nil
}

// Sum appends the Pol1305 hash of the previously
// Sum appends the Poly1305 hash of the previously
// processed data to b and returns the resulting slice.
// It is safe to call this function multiple times.
func (p *Hash) Sum(b []byte) []byte {
Expand Down
Loading