长话短说(真的很长)——我使用 Ted Krovetz 的实现来计算UMAC
和UMAC AE
加密(http://www.fastcrypto.org/)。
当我用 编译我的代码(和/或 中的测试umac.c
)时-std=c99
,计算UMAC
的结果与预期的完全不同(并且是错误的)。当我删除此选项时,一切都像魅力一样。
有什么想法可能导致这种情况吗?我可以做些什么来检查发生了什么以及产生不同结果的原因?
$ gcc --version
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
$ uname -a
xxx 3.13.0-43-generic #72-Ubuntu SMP .. x86_64 x86_64 x86_64 GNU/Linux
我不使用任何其他选项 - 仅使用和不使用-std=c99
.
再说几句:
我会尝试联系 Ted Krovetz 并询问他(这可能是一些错误或其他东西),但这不是重点。这个问题有点笼统,这个具体问题可以看作是例子。
我跑了valgrind
——没什么特别的。添加-Wall
和-Wextra
-什么都没有。听起来像 UB,但valgrind
不会抱怨任何事情。
这种情况非常有趣,我花了很多天和头疼的时间才明白,问题不在于我的代码(我使用这个实现来实现一个复杂的协议),而在于算法,尤其是这个选项。所以我决定征求意见。
这个在 C 和 C++ 中都有效的代码在用每种语言编译时会产生不同的行为吗?根本不相关,因为我们在这里谈论的是同一种语言。
没有“-std=c99”的这种巨大的 fprintf 速度差异很接近,但还不够。
编辑
这是我的测试结果和我所做的(源/标题只是下载,我没有更改任何内容):
$ ll
total 176K
-rw-r----- 1 kk kk 63K Jan 20 11:00 rijndael-alg-fst.c
-rw-r----- 1 kk kk 2.0K Jan 20 11:00 rijndael-alg-fst.h
-rw-r----- 1 kk kk 3.4K Jan 20 11:00 umac_ae.h
-rw-r----- 1 kk kk 76K Jan 20 11:00 umac.c
-rw-r----- 1 kk kk 4.2K Jan 20 11:00 umac.h
$ gcc -c *.c
$ gcc *.o
$ ./a.out
AES Test :::
Digest is : 3AD78E726C1EC02B7EBFE92B23D9EC34
Digest should be: 3AD78E726C1EC02B7EBFE92B23D9EC34
UMAC Test :::
Msg Should be Is
--- --------- --
'a' * 0 : 4D61E4F5AAB959C8 4D61E4F5AAB959C8
'a' * 3 : 67C1700CA30B532D 67C1700CA30B532D
'a' * 1024 : 05CB9405EC38D9F0 05CB9405EC38D9F0
'a' * 32768 : 048C543CB72443A4 048C543CB72443A4
Verifying consistancy of single- and multiple-call interfaces.
Done.
Authenticating 44 byte messages: 6.45 cpb.
Authenticating 64 byte messages: 4.18 cpb.
Authenticating 256 byte messages: 1.63 cpb.
Authenticating 512 byte messages: 1.20 cpb.
Authenticating 552 byte messages: 1.22 cpb.
Authenticating 1024 byte messages: 1.00 cpb.
Authenticating 1500 byte messages: 1.04 cpb.
Authenticating 8192 byte messages: 0.90 cpb.
Authenticating 262144 byte messages: 0.89 cpb.
UMAC-AE Tests :::
0 bytes ('abc' * 0):
Encrypt/decrypt match, tags match
Should be: 0000000000000000
Is : E8D1DAC3EA21E56D
3 bytes ('abc' * 1):
Encrypt/decrypt match, tags match
Should be: 0000000000000000
Is : 6BEDBA31E074E2A4
48 bytes ('abc' * 16):
Encrypt/decrypt match, tags match
Should be: 0000000000000000
Is : A3F6069B913969DA
300 bytes ('abc' * 100):
Encrypt/decrypt match, tags match
Should be: 0000000000000000
Is : C5B7F3822179FC36
3000000 bytes ('abc' * 1000000):
Encrypt/decrypt match, tags match
Should be: 0000000000000000
Is : EE7F50FDDA60AA04
16 bytes, 38.12 cpb
32 bytes, 25.04 cpb
64 bytes, 19.39 cpb
128 bytes, 16.41 cpb
256 bytes, 14.79 cpb
512 bytes, 13.96 cpb
1024 bytes, 13.79 cpb
2048 bytes, 13.46 cpb
4096 bytes, 13.47 cpb
$ ll
total 176K
-rw-r----- 1 kk kk 63K Jan 20 11:00 rijndael-alg-fst.c
-rw-r----- 1 kk kk 2.0K Jan 20 11:00 rijndael-alg-fst.h
-rw-r----- 1 kk kk 3.4K Jan 20 11:00 umac_ae.h
-rw-r----- 1 kk kk 76K Jan 20 11:00 umac.c
-rw-r----- 1 kk kk 4.2K Jan 20 11:00 umac.h
$ gcc -std=c99 -c *.c
$ gcc -std=c99 *.o
$ ./a.out
AES Test :::
Digest is : 3AD78E726C1EC02B7EBFE92B23D9EC34
Digest should be: 3AD78E726C1EC02B7EBFE92B23D9EC34
UMAC Test :::
Msg Should be Is
--- --------- --
'a' * 0 : 4D61E4F5AAB959C8 9492DE86794C9F2B
'a' * 3 : 67C1700CA30B532D CF9505F52928360E
'a' * 1024 : 05CB9405EC38D9F0 9C48C0D4EFAFAA37
'a' * 32768 : 048C543CB72443A4 7F63C29BB54BB141
Verifying consistancy of single- and multiple-call interfaces.
Done.
Authenticating 44 byte messages: 7.91 cpb.
Authenticating 64 byte messages: 5.20 cpb.
Authenticating 256 byte messages: 3.03 cpb.
Authenticating 512 byte messages: 2.60 cpb.
Authenticating 552 byte messages: 2.71 cpb.
Authenticating 1024 byte messages: 2.41 cpb.
Authenticating 1500 byte messages: 2.43 cpb.
Authenticating 8192 byte messages: 2.27 cpb.
Authenticating 262144 byte messages: 2.23 cpb.
UMAC-AE Tests :::
0 bytes ('abc' * 0):
Encrypt/decrypt match, tags match
Should be: 0000000000000000
Is : 899C50FD244BBA83
3 bytes ('abc' * 1):
Encrypt/decrypt match, tags match
Should be: 0000000000000000
Is : 892D14F581A3A4DD
48 bytes ('abc' * 16):
Encrypt/decrypt match, tags match
Should be: 0000000000000000
Is : 621AB4A63383F3C5
300 bytes ('abc' * 100):
Encrypt/decrypt match, tags match
Should be: 0000000000000000
Is : 324BEF6489F57787
3000000 bytes ('abc' * 1000000):
Encrypt/decrypt match, tags match
Should be: 0000000000000000
Is : 1A25FE3714C9345A
16 bytes, 40.80 cpb
32 bytes, 25.87 cpb
64 bytes, 20.50 cpb
128 bytes, 17.72 cpb
256 bytes, 15.93 cpb
512 bytes, 15.33 cpb
1024 bytes, 14.88 cpb
2048 bytes, 14.71 cpb
4096 bytes, 14.48 cpb
我刚刚在另一台机器上测试过,和我的一样。