Skip to content

Commit 98cf577

Browse files
committed
poly1305: Use MacResult for representing tags
This outsources constant time comparisons to `MacResult`, so downstream crates don't need to rely on additional crates to perform them beyond what `MacResult` is already using.
1 parent 26c8c12 commit 98cf577

File tree

3 files changed

+34
-23
lines changed

3 files changed

+34
-23
lines changed

poly1305/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ readme = "README.md"
1212

1313
[dependencies]
1414
byteorder = { version = "1", default-features = false }
15+
crypto-mac = "0.7"
1516
zeroize = { version = "0.9", optional = true, default-features = false }
1617

1718
[dev-dependencies]

poly1305/src/lib.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818

1919
// TODO: replace with `u32::{from_le_bytes, to_le_bytes}` in libcore (1.32+)
2020
extern crate byteorder;
21+
extern crate crypto_mac;
2122

2223
#[cfg(feature = "zeroize")]
2324
extern crate zeroize;
2425

2526
use byteorder::{ByteOrder, LE};
2627
use core::cmp::min;
28+
use crypto_mac::generic_array::{typenum::U16, GenericArray};
29+
use crypto_mac::MacResult;
2730
#[cfg(feature = "zeroize")]
2831
use zeroize::Zeroize;
2932

@@ -33,6 +36,9 @@ pub const KEY_SIZE: usize = 32;
3336
/// Size of the blocks Poly1305 acts upon
3437
pub const BLOCK_SIZE: usize = 16;
3538

39+
/// Poly1305 authentication tags
40+
pub type Tag = MacResult<U16>;
41+
3642
/// The Poly1305 universal hash function.
3743
///
3844
/// Note that Poly1305 is not a traditional MAC and is single-use only
@@ -135,7 +141,7 @@ impl Poly1305 {
135141
}
136142

137143
/// Get the hashed output
138-
pub fn result(mut self) -> [u8; BLOCK_SIZE] {
144+
pub fn result(mut self) -> Tag {
139145
if self.leftover > 0 {
140146
self.buffer[self.leftover] = 1;
141147

@@ -227,13 +233,13 @@ impl Poly1305 {
227233
f = u64::from(h3) + u64::from(self.pad[3]) + (f >> 32);
228234
h3 = f as u32;
229235

230-
let mut output = [0u8; BLOCK_SIZE];
231-
LE::write_u32(&mut output[0..4], h0);
232-
LE::write_u32(&mut output[4..8], h1);
233-
LE::write_u32(&mut output[8..12], h2);
234-
LE::write_u32(&mut output[12..16], h3);
236+
let mut tag = GenericArray::default();
237+
LE::write_u32(&mut tag[0..4], h0);
238+
LE::write_u32(&mut tag[4..8], h1);
239+
LE::write_u32(&mut tag[8..12], h2);
240+
LE::write_u32(&mut tag[12..16], h3);
235241

236-
output
242+
MacResult::new(tag)
237243
}
238244

239245
/// Compute a single block of Poly1305 using the internal buffer

poly1305/tests/lib.rs

+20-16
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ fn test_nacl_vector() {
2828
0xd9,
2929
];
3030

31-
assert_eq!(&Poly1305::new(&key).chain(&msg).result(), &expected[..]);
31+
let result1 = Poly1305::new(&key).chain(&msg).result();
32+
assert_eq!(&expected[..], result1.code().as_slice());
3233

33-
let result = Poly1305::new(&key)
34+
let result2 = Poly1305::new(&key)
3435
.chain(&msg[0..32])
3536
.chain(&msg[32..96])
3637
.chain(&msg[96..112])
@@ -44,7 +45,7 @@ fn test_nacl_vector() {
4445
.chain(&msg[130..131])
4546
.result();
4647

47-
assert_eq!(&result, &expected[..]);
48+
assert_eq!(&expected[..], result2.code().as_slice());
4849
}
4950

5051
#[test]
@@ -65,10 +66,9 @@ fn donna_self_test() {
6566
0x00,
6667
];
6768

68-
assert_eq!(
69-
&Poly1305::new(&wrap_key).chain(&wrap_msg).result(),
70-
&wrap_mac[..]
71-
);
69+
let result = Poly1305::new(&wrap_key).chain(&wrap_msg).result();
70+
71+
assert_eq!(&wrap_mac[..], result.code().as_slice());
7272

7373
let total_key = [
7474
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xff,
@@ -88,31 +88,35 @@ fn donna_self_test() {
8888
key.copy_from_slice(&repeat(i as u8).take(KEY_SIZE).collect::<Vec<_>>());
8989

9090
let msg: Vec<u8> = repeat(i as u8).take(256).collect();
91-
tpoly.input(&Poly1305::new(&key).chain(&msg[..i]).result());
91+
let tag = Poly1305::new(&key).chain(&msg[..i]).result();
92+
tpoly.input(tag.code().as_slice());
9293
}
9394

94-
assert_eq!(&tpoly.result(), &total_mac[..]);
95+
assert_eq!(&total_mac[..], tpoly.result().code().as_slice());
9596
}
9697

9798
#[test]
9899
fn test_tls_vectors() {
99100
// from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
100101
let key = b"this is 32-byte key for Poly1305";
101-
let msg = [0u8; 32];
102-
let expected = [
102+
103+
let msg1 = [0u8; 32];
104+
let expected1 = [
103105
0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 0x1c, 0xcc, 0x03,
104106
0x07,
105107
];
106108

107-
assert_eq!(&Poly1305::new(&key).chain(&msg).result(), &expected[..]);
109+
let result1 = Poly1305::new(&key).chain(&msg1).result();
110+
assert_eq!(&expected1[..], result1.code().as_slice());
108111

109-
let msg = b"Hello world!";
110-
let expected = [
112+
let msg2 = b"Hello world!";
113+
let expected2 = [
111114
0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 0xee, 0xf2, 0xb2,
112115
0xf0,
113116
];
114117

115-
assert_eq!(&Poly1305::new(&key).chain(&msg[..]).result(), &expected[..]);
118+
let result2 = Poly1305::new(&key).chain(&msg2[..]).result();
119+
assert_eq!(&expected2[..], result2.code().as_slice());
116120
}
117121

118122
#[test]
@@ -135,5 +139,5 @@ fn padded_input() {
135139

136140
let mut poly = Poly1305::new(&key);
137141
poly.input_padded(&msg);
138-
assert_eq!(&expected[..], poly.result());
142+
assert_eq!(&expected[..], poly.result().code().as_slice());
139143
}

0 commit comments

Comments
 (0)