Welcome to mirror list, hosted at ThFree Co, Russian Federation.

MacThroughputTest.java « speedy « test « crypto « spongycastle « org « java « test « src « core - gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ffbc673f9aa0e9d66cf51ebb9cc5ead6890863f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package org.spongycastle.crypto.test.speedy;

import java.security.SecureRandom;

import org.spongycastle.crypto.CipherParameters;
import org.spongycastle.crypto.KeyGenerationParameters;
import org.spongycastle.crypto.Mac;
import org.spongycastle.crypto.digests.SHA1Digest;
import org.spongycastle.crypto.engines.AESFastEngine;
import org.spongycastle.crypto.engines.NullEngine;
import org.spongycastle.crypto.generators.Poly1305KeyGenerator;
import org.spongycastle.crypto.macs.CMac;
import org.spongycastle.crypto.macs.GMac;
import org.spongycastle.crypto.macs.HMac;
import org.spongycastle.crypto.macs.Poly1305;
import org.spongycastle.crypto.macs.SipHash;
import org.spongycastle.crypto.macs.SkeinMac;
import org.spongycastle.crypto.modes.GCMBlockCipher;
import org.spongycastle.crypto.params.KeyParameter;
import org.spongycastle.crypto.params.ParametersWithIV;

/**
 * Microbenchmark of MACs on short, medium, long messages, with optional object creation cost.
 */
public class MacThroughputTest
{

    private static final long CLOCK_SPEED = 2400000000L;

    private static final SecureRandom RANDOM = new SecureRandom();
    private static Poly1305KeyGenerator kg = new Poly1305KeyGenerator();;

    private static final byte[] SHORT_MESSAGE = new byte[16];
    private static final byte[] MEDIUM_MESSAGE = new byte[256];
    private static final byte[] LONG_MESSAGE = new byte[8192];
    static
    {
        RANDOM.nextBytes(SHORT_MESSAGE);
        RANDOM.nextBytes(MEDIUM_MESSAGE);
        RANDOM.nextBytes(LONG_MESSAGE);
    }

    private static final int SHORT_MESSAGE_COUNT = 20000000;
    private static final int MEDIUM_MESSAGE_COUNT = 2200000;
    private static final int LONG_MESSAGE_COUNT = 80000;

    static
    {
        kg.init(new KeyGenerationParameters(RANDOM, 256));
    }

    private static KeyParameter generatePoly1305Key()
    {
        return new KeyParameter(kg.generateKey());
    }

    public static void main(String[] args)
    {
        testMac(new HMac(new SHA1Digest()), new KeyParameter(generateNonce(20)), 3);
        testMac(new SkeinMac(SkeinMac.SKEIN_512, 128), new KeyParameter(generateNonce(64)), 2);
        testMac(new SipHash(), new KeyParameter(generateNonce(16)), 1);
        testMac(new CMac(new AESFastEngine()), new KeyParameter(generateNonce(16)), 3);
        testMac(new GMac(new GCMBlockCipher(new AESFastEngine())), new ParametersWithIV(new KeyParameter(
                generateNonce(16)), generateNonce(16)), 5);
        testMac(new Poly1305(new NullEngine(16)), new ParametersWithIV(generatePoly1305Key(), generateNonce(16)), 1);
        testMac(new Poly1305(new AESFastEngine()), new ParametersWithIV(generatePoly1305Key(), generateNonce(16)), 1);
        testMac(new Poly1305Reference(new NullEngine(16)), new ParametersWithIV(generatePoly1305Key(),
                generateNonce(16)), 1);
    }

    private static byte[] generateNonce(int sizeBytes)
    {
        byte[] nonce = new byte[16];
        RANDOM.nextBytes(nonce);
        return nonce;
    }

    private static void testMac(Mac mac, CipherParameters params, int rateFactor)
    {
        System.out.println("=========================");

        long total = testRun(mac, params, false, MEDIUM_MESSAGE, adjust(MEDIUM_MESSAGE_COUNT, rateFactor));
        System.out.printf("%s Warmup 1 run time: %,d ms\n", mac.getAlgorithmName(), total / 1000000);
        total = testRun(mac, params, false, MEDIUM_MESSAGE, adjust(MEDIUM_MESSAGE_COUNT, rateFactor));
        System.out.printf("%s Warmup 2 run time: %,d ms\n", mac.getAlgorithmName(), total / 1000000);
        System.gc();
        try
        {
            Thread.sleep(1000);
        } catch (InterruptedException e)
        {
        }

        test("Short", mac, params, false, SHORT_MESSAGE, adjust(SHORT_MESSAGE_COUNT, rateFactor));
        // test("Short", mac, params, true, SHORT_MESSAGE, adjust(SHORT_MESSAGE_COUNT, rateFactor));
        test("Medium", mac, params, false, MEDIUM_MESSAGE, adjust(MEDIUM_MESSAGE_COUNT, rateFactor));
        // test("Medium", mac, params, true, MEDIUM_MESSAGE, adjust(MEDIUM_MESSAGE_COUNT,
        // rateFactor));
        test("Long", mac, params, false, LONG_MESSAGE, adjust(LONG_MESSAGE_COUNT, rateFactor));
        // test("Long", mac, params, true, LONG_MESSAGE, adjust(LONG_MESSAGE_COUNT, rateFactor));
    }

    private static int adjust(int iterationCount, int rateFactor)
    {
        return (int)(iterationCount * (1.0f / rateFactor));
    }

    private static void test(String name,
                             Mac mac,
                             CipherParameters params,
                             boolean initPerMessage,
                             byte[] message,
                             int adjustedCount)
    {
        System.out.println("=========================");
        long total = testRun(mac, params, initPerMessage, message, adjustedCount);

        long averageRuntime = total / adjustedCount;
        System.out.printf("%s %-7s%s Total run time:   %,d ms\n", mac.getAlgorithmName(), name, initPerMessage ? "*"
                : " ", total / 1000000);
        System.out.printf("%s %-7s%s Average run time: %,d ns\n", mac.getAlgorithmName(), name, initPerMessage ? "*"
                : " ", averageRuntime);
        final long mbPerSecond = (long)((double)message.length / averageRuntime * 1000000000 / (1024 * 1024));
        System.out.printf("%s %-7s%s Average speed:    %,d MB/s\n", mac.getAlgorithmName(), name, initPerMessage ? "*"
                : " ", mbPerSecond);
        System.out.printf("%s %-7s%s Average speed:    %,f c/b\n", mac.getAlgorithmName(), name, initPerMessage ? "*"
                : " ", CLOCK_SPEED / (double)(mbPerSecond * (1024 * 1024)));
    }

    private static long testRun(Mac mac,
                                CipherParameters params,
                                boolean initPerMessage,
                                byte[] message,
                                int adjustedCount)
    {
        byte[] out = new byte[mac.getMacSize()];

        if (!initPerMessage)
        {
            mac.init(params);
        }
        long start = System.nanoTime();

        for (int i = 0; i < adjustedCount; i++)
        {
            if (initPerMessage)
            {
                mac.init(params);
            }
            mac.update(message, 0, message.length);
            mac.doFinal(out, 0);
        }
        long total = System.nanoTime() - start;
        return total;
    }
}