4

長い (本当に長い) 短い話 - 私は Ted Krovetz の実装を計算UMACUMAC 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

別のマシンでテストしたところ、私のマシンと同じです。

4

3 に答える 3

4

UBのように聞こえますが、

そうである必要はありません。同じプログラムが C99 と C90 として異なって解釈される原因となる既知の相違点がいくつかあります。

しかし、valgrind は何も文句を言いません。

どちらの標準でも、Valgrind はすべての未定義の動作に対して警告にさえ近づきません。

頭に浮かぶ最初の違い (ただし、優れたコンパイラであれば警告が出力されるはずです) は、整数定数の型です3000000000。32 ビットintおよび 64 ビットlongの では、C90 コンパイラ3000000000unsigned long. C99 では、unsigned long接尾辞のない整数定数が持つことができる型のリストにないため、 (signed)3000000000として型指定されます。long long

見ない限り、暗号化コードには多くの大きな整数定数が含まれている可能性が高いため、これは 1 つの可能性です。

もちろん、C90 または C99 として解釈されるコードには未定義の動作が存在する可能性があり、コンパイラが C90 モードと C99 モードで異なる結果を生成することは許されます。私が言っているのは、存在する必要がないということだけです。

于 2015-01-19T17:41:38.777 に答える