Skip to content

Commit 225a0ba

Browse files
author
Andreas Auernhammer
committed
redefine the API (backward breaking change)
This change makes it possible to include poly1305 in https://github.com/aead/poly. Remove go master from travis
1 parent cddc25d commit 225a0ba

File tree

5 files changed

+64
-63
lines changed

5 files changed

+64
-63
lines changed

.travis.yml

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ go:
55
- 1.6
66
- 1.7
77
- 1.8
8-
- master
98

109
env:
1110
- TRAVIS_GOARCH=amd64

poly1305.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ var errWriteAfterSum = errors.New("checksum already computed - adding more data
2424

2525
// Verify returns true if and only if the mac is a valid authenticator
2626
// for msg with the given key.
27-
func Verify(mac *[TagSize]byte, msg []byte, key *[32]byte) bool {
28-
var sum [TagSize]byte
29-
Sum(&sum, msg, key)
27+
func Verify(mac *[TagSize]byte, msg []byte, key [32]byte) bool {
28+
sum := Sum(msg, key)
3029
return subtle.ConstantTimeCompare(sum[:], mac[:]) == 1
3130
}

poly1305_amd64.go

+25-21
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,32 @@ func update(state *[7]uint64, msg []byte)
2020
//go:noescape
2121
func finalize(tag *[TagSize]byte, state *[7]uint64)
2222

23-
// Sum generates an authenticator for msg using a one-time key and puts the
24-
// 16-byte result into out. Authenticating two different messages with the same
25-
// key allows an attacker to forge messages at will.
26-
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
23+
// Sum generates an authenticator for msg using a one-time key and returns the
24+
// 16-byte result. Authenticating two different messages with the same key allows
25+
// an attacker to forge messages at will.
26+
func Sum(msg []byte, key [32]byte) [TagSize]byte {
2727
if len(msg) == 0 {
2828
msg = []byte{}
2929
}
30-
30+
var out [TagSize]byte
3131
var state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 }
32-
initialize(&state, key)
32+
initialize(&state, &key)
3333
update(&state, msg)
34-
finalize(out, &state)
34+
finalize(&out, &state)
35+
return out
3536
}
3637

37-
// New returns a hash.Hash computing the poly1305 sum.
38+
// New returns a Hash computing the poly1305 sum.
3839
// Notice that Poly1305 is insecure if one key is used twice.
39-
func New(key *[32]byte) *Hash {
40+
func New(key [32]byte) *Hash {
4041
p := new(Hash)
41-
initialize(&(p.state), key)
42+
initialize(&(p.state), &key)
4243
return p
4344
}
4445

45-
// Hash implements a Poly1305 writer interface.
46+
// Hash implements the poly1305 authenticator.
4647
// Poly1305 cannot be used like common hash.Hash implementations,
4748
// because of using a poly1305 key twice breaks its security.
48-
// So poly1305.Hash does not support some kind of reset.
4949
type Hash struct {
5050
state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 }
5151

@@ -54,11 +54,13 @@ type Hash struct {
5454
done bool
5555
}
5656

57+
// Size returns the number of bytes Sum will append.
58+
func (p *Hash) Size() int { return TagSize }
59+
5760
// Write adds more data to the running Poly1305 hash.
58-
// This function returns an non-nil error, if a call
59-
// to Write happens after the hash's Sum function was
60-
// called. So it's not possible to compute the checksum
61-
// and than add more data.
61+
// This function should return a non-nil error if a call
62+
// to Write happens after a call to Sum. So it is not possible
63+
// to compute the checksum and than add more data.
6264
func (p *Hash) Write(msg []byte) (int, error) {
6365
if p.done {
6466
return 0, errWriteAfterSum
@@ -89,16 +91,18 @@ func (p *Hash) Write(msg []byte) (int, error) {
8991
return n, nil
9092
}
9193

92-
// Sum computes the Poly1305 checksum of the previously
93-
// processed data and writes it to out. It is legal to
94-
// call this function more than one time.
95-
func (p *Hash) Sum(out *[TagSize]byte) {
94+
// Sum appends the Pol1305 hash of the previously
95+
// processed data to b and returns the resulting slice.
96+
// It is safe to call this function multiple times.
97+
func (p *Hash) Sum(b []byte) []byte {
98+
var out [TagSize]byte
9699
state := p.state
97100

98101
if p.off > 0 {
99102
update(&state, p.buf[:p.off])
100103
}
101104

102-
finalize(out, &state)
105+
finalize(&out, &state)
103106
p.done = true
107+
return append(b, out[:]...)
104108
}

poly1305_ref.go

+23-19
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,39 @@ const (
1313
finalBlock = uint32(0)
1414
)
1515

16-
// Sum generates an authenticator for msg using a one-time key and puts the
17-
// 16-byte result into out. Authenticating two different messages with the same
18-
// key allows an attacker to forge messages at will.
19-
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
16+
// Sum generates an authenticator for msg using a one-time key and returns the
17+
// 16-byte result. Authenticating two different messages with the same key allows
18+
// an attacker to forge messages at will.
19+
func Sum(msg []byte, key [32]byte) [TagSize]byte {
2020
var (
2121
h, r [5]uint32
2222
s [4]uint32
2323
block [TagSize]byte
2424
off int
2525
)
26+
var out [TagSize]byte
2627

27-
initialize(&r, &s, key)
28+
initialize(&r, &s, &key)
2829

2930
n := len(msg) & (^(TagSize - 1))
3031
if n > 0 {
3132
update(msg[:n], msgBlock, &h, &r)
3233
msg = msg[n:]
3334
}
34-
3535
if len(msg) > 0 {
3636
off += copy(block[:], msg)
3737
block[off] = 1
3838
update(block[:], finalBlock, &h, &r)
3939
}
40-
41-
finalize(out, &h, &s)
40+
finalize(&out, &h, &s)
41+
return out
4242
}
4343

4444
// New returns a hash.Hash computing the poly1305 sum.
4545
// Notice that Poly1305 is insecure if one key is used twice.
46-
func New(key *[32]byte) *Hash {
46+
func New(key [32]byte) *Hash {
4747
p := new(Hash)
48-
initialize(&(p.r), &(p.s), key)
48+
initialize(&(p.r), &(p.s), &key)
4949
return p
5050
}
5151

@@ -62,11 +62,13 @@ type Hash struct {
6262
done bool
6363
}
6464

65+
// Size returns the number of bytes Sum will append.
66+
func (p *Hash) Size() int { return TagSize }
67+
6568
// Write adds more data to the running Poly1305 hash.
66-
// This function returns an non-nil error, if a call
67-
// to Write happens after the hash's Sum function was
68-
// called. So it's not possible to compute the checksum
69-
// and than add more data.
69+
// This function should return a non-nil error if a call
70+
// to Write happens after a call to Sum. So it is not possible
71+
// to compute the checksum and than add more data.
7072
func (p *Hash) Write(msg []byte) (int, error) {
7173
if p.done {
7274
return 0, errWriteAfterSum
@@ -97,10 +99,11 @@ func (p *Hash) Write(msg []byte) (int, error) {
9799
return n, nil
98100
}
99101

100-
// Sum computes the Poly1305 checksum of the previously
101-
// processed data and writes it to out. It is legal to
102-
// call this function more than one time.
103-
func (p *Hash) Sum(out *[TagSize]byte) {
102+
// Sum appends the Pol1305 hash of the previously
103+
// processed data to b and returns the resulting slice.
104+
// It is safe to call this function multiple times.
105+
func (p *Hash) Sum(b []byte) []byte {
106+
var out [TagSize]byte
104107
h := p.h
105108

106109
if p.off > 0 {
@@ -111,8 +114,9 @@ func (p *Hash) Sum(out *[TagSize]byte) {
111114
update(buf[:], finalBlock, &h, &(p.r))
112115
}
113116

114-
finalize(out, &h, &(p.s))
117+
finalize(&out, &h, &(p.s))
115118
p.done = true
119+
return append(b, out[:]...)
116120
}
117121

118122
func initialize(r *[5]uint32, s *[4]uint32, key *[32]byte) {

poly1305_test.go

+14-19
Original file line numberDiff line numberDiff line change
@@ -57,44 +57,41 @@ var vectors = []struct {
5757
}
5858

5959
func TestVectors(t *testing.T) {
60-
var out [16]byte
6160
var key [32]byte
6261

6362
for i, v := range vectors {
6463
msg := v.msg
6564
copy(key[:], v.key)
6665

67-
Sum(&out, msg, &key)
66+
out := Sum(msg, key)
6867
if !bytes.Equal(out[:], v.tag) {
6968
t.Errorf("Test vector %d : got: %x expected: %x", i, out[:], v.tag)
7069
}
7170

72-
h := New(&key)
71+
h := New(key)
7372
h.Write(msg)
74-
h.Sum(&out)
75-
if !bytes.Equal(out[:], v.tag) {
76-
t.Errorf("Test vector %d : got: %x expected: %x", i, out[:], v.tag)
73+
tag := h.Sum(nil)
74+
if !bytes.Equal(tag[:], v.tag) {
75+
t.Errorf("Test vector %d : got: %x expected: %x", i, tag[:], v.tag)
7776
}
7877

7978
var mac [16]byte
8079
copy(mac[:], v.tag)
81-
if !Verify(&mac, msg, &key) {
80+
if !Verify(&mac, msg, key) {
8281
t.Errorf("Test vector %d : Verify failed", i)
8382
}
8483
}
8584
}
8685

8786
func TestWriteAfterSum(t *testing.T) {
88-
var sum [TagSize]byte
89-
9087
msg := make([]byte, 64)
9188
for i := range msg {
92-
h := New(new([32]byte))
89+
h := New([32]byte{})
9390

9491
if _, err := h.Write(msg[:i]); err != nil {
9592
t.Fatalf("Iteration %d: poly1305.Hash returned unexpected error: %s", i, err)
9693
}
97-
h.Sum(&sum)
94+
h.Sum(nil)
9895
if _, err := h.Write(nil); err == nil {
9996
t.Fatalf("Iteration %d: poly1305.Hash returned no error for write after sum", i)
10097
}
@@ -107,7 +104,7 @@ func TestWrite(t *testing.T) {
107104
key[i] = byte(i)
108105
}
109106

110-
h := New(&key)
107+
h := New(key)
111108

112109
var msg1 []byte
113110
msg0 := make([]byte, 64)
@@ -116,11 +113,10 @@ func TestWrite(t *testing.T) {
116113
msg1 = append(msg1, msg0[:i]...)
117114
}
118115

119-
var tag0, tag1 [TagSize]byte
120-
h.Sum(&tag0)
121-
Sum(&tag1, msg1, &key)
116+
tag0 := h.Sum(nil)
117+
tag1 := Sum(msg1, key)
122118

123-
if tag0 != tag1 {
119+
if !bytes.Equal(tag0[:], tag1[:]) {
124120
t.Fatalf("Sum differ from poly1305.Sum\n Sum: %s \n poly1305.Sum: %s", hex.EncodeToString(tag0[:]), hex.EncodeToString(tag1[:]))
125121
}
126122
}
@@ -138,7 +134,6 @@ func BenchmarkWriteUnaligned_1K(b *testing.B) { benchmarkWrite(b, 1024, true) }
138134

139135
func benchmarkSum(b *testing.B, size int, unalign bool) {
140136
var key [32]byte
141-
var tag [16]byte
142137

143138
msg := make([]byte, size)
144139
if unalign {
@@ -148,13 +143,13 @@ func benchmarkSum(b *testing.B, size int, unalign bool) {
148143
b.SetBytes(int64(size))
149144
b.ResetTimer()
150145
for i := 0; i < b.N; i++ {
151-
Sum(&tag, msg, &key)
146+
Sum(msg, key)
152147
}
153148
}
154149

155150
func benchmarkWrite(b *testing.B, size int, unalign bool) {
156151
var key [32]byte
157-
h := New(&key)
152+
h := New(key)
158153

159154
msg := make([]byte, size)
160155
if unalign {

0 commit comments

Comments
 (0)