use super::HMAC;
use crate::crypto::md5;
use crate::crypto::sha1;
use crate::crypto::sha256;
use crate::encoding::hex;
use crate::hash::Hash;
use std::io::Write;
struct HmacTest {
hash: &'static str,
key: &'static [u8],
input: &'static [u8],
out: &'static str,
size: usize,
blocksize: usize,
}
impl HmacTest {
const fn new(
hash: &'static str,
key: &'static [u8],
input: &'static [u8],
out: &'static str,
size: usize,
blocksize: usize,
) -> Self {
Self {
hash,
key,
input,
out,
size,
blocksize,
}
}
}
const HMAC_TESTS: &[HmacTest] = &[
HmacTest::new(
"sha1",
&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
],
b"Sample #1",
"4f4ca3d5d68ba7cc0a1208c9c61e9c5da0403c0a",
sha1::SIZE,
sha1::BLOCK_SIZE,
),
HmacTest::new(
"sha1",
&[
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d,
0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43,
],
b"Sample #2",
"0922d3405faa3d194f82a45830737d5cc6c75d24",
sha1::SIZE,
sha1::BLOCK_SIZE,
),
HmacTest::new(
"sha1",
&[
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d,
0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3,
0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1,
0xb2, 0xb3,
],
b"Sample #3",
"bcf41eab8bb2d802f3d05caf7cb092ecf8d1a3aa",
sha1::SIZE,
sha1::BLOCK_SIZE,
),
HmacTest::new(
"md5",
b"Jefe",
b"what do ya want for nothing?",
"750c783e6ab0b503eaa86e310a5db738",
md5::SIZE,
md5::BLOCK_SIZE,
),
HmacTest::new(
"sha256",
&[
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
],
b"Hi There",
"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
sha256::SIZE,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha256",
b"Jefe",
b"what do ya want for nothing?",
"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
sha256::SIZE,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha256",
&[
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
],
&[
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
],
"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
sha256::SIZE,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha256",
&[
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
],
&[
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
],
"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
sha256::SIZE,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha256",
&[
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa,
],
b"Test Using Larger Than Block-Size Key - Hash Key First",
"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54",
sha256::SIZE,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha256",
&[
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa,
],
b"This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2",
sha256::SIZE,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha1",
&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
],
b"Sample message for keylen=blocklen",
"5fd596ee78d5553c8ff4e72d266dfd192366da29",
sha1::SIZE,
sha1::BLOCK_SIZE,
),
HmacTest::new(
"sha1",
&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13,
],
b"Sample message for keylen<blocklen",
"4c99ff0cb1b31bd33f8431dbaf4d17fcd356a807",
sha1::SIZE,
sha1::BLOCK_SIZE,
),
HmacTest::new(
"sha1",
&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63,
],
b"Sample message for keylen=blocklen",
"2d51b2f7750e410584662e38f133435f4c4fd42a",
sha1::SIZE,
sha1::BLOCK_SIZE,
),
HmacTest::new(
"sha224",
&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
],
b"Sample message for keylen=blocklen",
"c7405e3ae058e8cd30b08b4140248581ed174cb34e1224bcc1efc81b",
sha256::SIZE224,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha224",
&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b,
],
b"Sample message for keylen<blocklen",
"e3d249a8cfb67ef8b7a169e9a0a599714a2cecba65999a51beb8fbbe",
sha256::SIZE224,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha224",
&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63,
],
b"Sample message for keylen=blocklen",
"91c52509e5af8531601ae6230099d90bef88aaefb961f4080abc014d",
sha256::SIZE224,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha256",
&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
],
b"Sample message for keylen=blocklen",
"8bb9a1db9806f20df7f77b82138c7914d174d59e13dc4d0169c9057b133e1d62",
sha256::SIZE,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha256",
&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
],
b"Sample message for keylen<blocklen",
"a28cf43130ee696a98f14a37678b56bcfcbdd9e5cf69717fecf5480f0ebdf790",
sha256::SIZE,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha256",
&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63,
],
b"Sample message for keylen=blocklen",
"bdccb6c72ddeadb500ae768386cb38cc41c63dbb0878ddb9c7a38a431b78378d",
sha256::SIZE,
sha256::BLOCK_SIZE,
),
HmacTest::new(
"sha1",
&[],
b"message",
"d5d1ed05121417247616cfc8378f360a39da7cfa",
sha1::SIZE,
sha1::BLOCK_SIZE,
),
HmacTest::new(
"sha256",
&[],
b"message",
"eb08c1f56d5ddee07f7bdf80468083da06b64cf4fac64fe3a90883df5feacae4",
sha256::SIZE,
sha256::BLOCK_SIZE,
),
];
#[test]
fn test_hmac() {
for (i, tt) in HMAC_TESTS.iter().enumerate() {
let mut h: Box<dyn Hash> = match tt.hash {
"sha1" => Box::new(HMAC::new(sha1::Digest::new, tt.key)),
"sha256" => Box::new(HMAC::new(sha256::Digest::new, tt.key)),
"sha224" => Box::new(HMAC::new(sha256::Digest::new224, tt.key)),
"md5" => Box::new(HMAC::new(md5::Digest::new, tt.key)),
_ => panic!("unsupported hash {}", tt.hash),
};
assert_eq!(
h.size(),
tt.size,
"Size: got {}, want {}",
h.size(),
tt.size
);
assert_eq!(
h.block_size(),
tt.blocksize,
"block_size: got {}, want {}",
h.block_size(),
tt.blocksize
);
for j in 0..4 {
let n = h.write(tt.input).unwrap();
assert_eq!(
n,
tt.input.len(),
"test {}.{}: Write({}) = {}",
i,
j,
tt.input.len(),
n,
);
for k in 0..2 {
let sum = hex::encode_to_string(&h.sum(&[]));
assert_eq!(
sum, tt.out,
"test {}.{}.{}: have {} want {}\n",
i, j, k, sum, tt.out
);
}
h.reset();
}
}
}
#[test]
fn test_equal() {
let a = b"test";
let b = b"test1";
let c = b"test2";
assert!(super::equal(b, b), "Equal failed with equal arguments");
assert!(
!super::equal(a, b),
"Equal accepted a prefix of the second argument"
);
assert!(
!super::equal(b, a),
"Equal accepted a prefix of the first argument"
);
assert!(!super::equal(b, c), "Equal accepted unequal slices");
}
#[test]
fn test_write_after_sum() {
let mut h = HMAC::new(sha1::Digest::new, &[]);
h.write_all(b"hello").unwrap();
let sum_hello = h.sum(&[]);
let mut h = HMAC::new(sha1::Digest::new, &[]);
h.write_all(b"hello world").unwrap();
let sum_hello_world = h.sum(&[]);
let mut h = HMAC::new(sha1::Digest::new, &[]);
h.write_all(b"hello").unwrap();
let sum = h.sum(&[]);
assert_eq!(
sum, sum_hello,
"1st Sum after hello = {:?}, want {:?}",
sum, sum_hello,
);
let sum = h.sum(&[]);
assert_eq!(
sum, sum_hello,
"2st Sum after hello = {:?}, want {:?}",
sum, sum_hello,
);
h.write_all(b" world").unwrap();
let sum = h.sum(&[]);
assert_eq!(
sum, sum_hello_world,
"1st Sum after hello world = {:?}, want {:?}",
sum, sum_hello_world,
);
let sum = h.sum(&[]);
assert_eq!(
sum, sum_hello_world,
"2st Sum after hello world = {:?}, want {:?}",
sum, sum_hello_world,
);
h.reset();
h.write_all(b"hello").unwrap();
let sum = h.sum(&[]);
assert_eq!(
sum, sum_hello,
"Sum after reset + hello = {:?}, want {:?}",
sum, sum_hello,
);
}