2020-11-30

Apple M1のSHA512命令

新しい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 件のコメント: