新しいARM Crypto Extensionだと、中国系のSM3とかSHA3とかSHA512とかの専用命令があるのだけど、Appleは比較的こういうところに投資をしてるので、Appleのチップだと実装されている。
パフォーマンス的な情報はインターネットに転がっていないので、試しに手元で実装してみた。データはいつもの通りのNSSでのデータ。
実装前のデータはこれ。
# mode in opreps cxreps context op time(sec) thrgput sha512_e 1Gb 15M 0 0.000 10000.000 10.000 168Mb
実装するとこうなる
# mode in opreps cxreps context op time(sec) thrgput sha512_e 4Gb 47M 0 0.000 10000.000 10.000 503Mb
SHA1、SHA256と同様に3倍くらい速くなる感じですね。
SHA256とは違って、ROUNDに対するレジスタが足りないので、extを使って、利用するベクタを選択しながらループしないといけないのでシンプルにはならない
#define ROUND(n, a, b, c, d, e, f, g, h, w0, w1, w2, w3, w4) \
{ \
uint64x2_t t, fg, de; \
t = vaddq_u64(a, vld1q_u64(K512 + n * 2)); \
t = vreinterpretq_u64_u8(vextq_u8(vreinterpretq_u8_u64(t), \
vreinterpretq_u8_u64(t), 8)); \
de = vreinterpretq_u64_u8(vextq_u8(vreinterpretq_u8_u64(w1), \
vreinterpretq_u8_u64(w2), 8)); \
fg = vreinterpretq_u64_u8(vextq_u8(vreinterpretq_u8_u64(w2), \
vreinterpretq_u8_u64(w3), 8)); \
w3 = vaddq_u64(w3, t); \
w3 = vsha512hq_u64(w3, fg, de); \
w4 = vaddq_u64(w1, w3); \
w3 = vsha512h2q_u64(w3, w1, w0); \
if (n < 32) { \
a = vsha512su0q_u64(a, b); \
a = vsha512su1q_u64(a, h, \
vextq_u8(vreinterpretq_u8_u64(e), \
vreinterpretq_u8_u64(f), 8)); \
} \
}
なお、SHA512のIntrinsicsはgccの最新であれば実装されているが、clangの場合は最新のコードでも実装されていないので、インラインアセンブラ使うなりアセンブラで書かないといけない
0 件のコメント:
コメントを投稿