diff --git a/config.properties b/config.properties index 2b2c397..d699413 100644 --- a/config.properties +++ b/config.properties @@ -1,6 +1,12 @@ # 应用配置 # 调试模式 (true/false) -debug=true +debug=false + +# 最大线程数 +maxThread=20 + +# 总数 +total=100000 # 地址列表 (格式: addX=ip:port) -addr1=192.168.110.240:8889 +addr1=172.1.41.129:8889 \ No newline at end of file diff --git a/src/main/java/com/sunyard/sge/database/SydApiBaseFunction.java b/src/main/java/com/sunyard/sge/database/SydApiBaseFunction.java index f273e63..7937edb 100644 --- a/src/main/java/com/sunyard/sge/database/SydApiBaseFunction.java +++ b/src/main/java/com/sunyard/sge/database/SydApiBaseFunction.java @@ -1,17 +1,22 @@ package com.sunyard.sge.database; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; import com.sunyard.SydApiException; import com.sunyard.log.ILogFactory; import com.sunyard.log.ILogger; import com.sunyard.proto.Util; +import com.sunyard.sge.bytes.BytesUtil; import com.sunyard.sge.database.pool.HsmLinkInfo; import com.sunyard.sge.log.LogbackFactory; +import com.sunyard.sge.plus.SydLibrary; import com.sunyard.sge.pool.ObjectInPool; import com.sunyard.util.SYMUtil; import racal.sunyard.main.SydApi4j; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; /** @@ -22,6 +27,10 @@ public class SydApiBaseFunction implements SydApi { private HsmLinkInfo[] linkInfos = null; private ObjectInPool oip = null; private boolean isShortLinkMode = false; + + // c 加速句柄,短链接。 + private PointerByReference phHandle = null; + private ILogFactory iLogFactory = new LogbackFactory(); private ILogger log = iLogFactory.getLogger(SydApiBaseFunction.class); @@ -85,10 +94,33 @@ public class SydApiBaseFunction implements SydApi { hsms = apis; isShortLinkMode = true; + + // c 加速链接 + if ( Env.isLinux() ) { + PointerByReference phHandle = new PointerByReference(); + int connectResult = SydLibrary.INSTANCE.SYD_Connect_Ex( + pcIpList, + iPortList, + pcIpList.length, + iConnectTimeOut, + iDealTimeOut, + 0, + phHandle); + + if ( 0 != connectResult ){ + throw new SydApiException("连接错误", -1); + } + this.phHandle = phHandle; + } return this; } public void SYD_Disconnect() { + if ( null != phHandle && Env.isLinux()) { + SydLibrary.INSTANCE.SYD_DisConnect_Ex(phHandle.getValue()); + phHandle = null; + } + if (null == hsms) { return; } @@ -494,9 +526,6 @@ public class SydApiBaseFunction implements SydApi { } } catch (SydApiException e) { - if (null == e) { - - } le = e; if (e.getRetCode() < 0) { log.error("HA 重试"); @@ -869,9 +898,48 @@ public class SydApiBaseFunction implements SydApi { return Arrays.equals(pcMac, mac); } + DataAndMac SYD_SM4_EncryptAndMac_ShortData_c(int iEncKeyIndex, int iMacKeyIndex, byte[] pcData) { + log.info("SYD_SM4_EncryptAndMac_ShortData_c {} {}", iEncKeyIndex, iMacKeyIndex); + try { + int enLen = BytesUtil.calculatePaddedLength(pcData.length); + byte[] encData = new byte[enLen]; + byte[] mac = new byte[16]; + IntByReference encDataLen = new IntByReference(encData.length); + + int i = SydLibrary.INSTANCE.SYD_SM4_Encrypt_Mac_ShortData( + phHandle.getValue(), + iEncKeyIndex, + iMacKeyIndex, + pcData, + pcData.length, + encData, + encDataLen, + mac + ); + + if (0 == i) { + byte[] data = new byte[encDataLen.getValue()]; + if (data.length == encData.length) { + data = encData; + } else { + System.arraycopy(encData, 0, data, 0, data.length); + } + + return new DataAndMac(data, mac); + } else { + throw new SydApiException(i); + } + } catch (SydApiException e) { + throw e; + } catch (Exception e) { + if (e.getCause() instanceof SydApiException) { + throw (SydApiException) e.getCause(); + } + throw new SydApiException("并行任务执行失败", 0xC101, e); + } + } /** - * 非依赖 C 实现,仅长连接依赖 C * * @param iEncKeyIndex:输入。加密所需要的密钥索引值 * @param iMacKeyIndex:输入。计算mac所需要的密钥索引值 @@ -884,11 +952,58 @@ public class SydApiBaseFunction implements SydApi { if (log.isDebugEnabled()) { log.debug("SYD_SM4_EncryptAndMac_ShortData:k1={} k2={}", iEncKeyIndex, iMacKeyIndex); } - // 参数检查在函数内部 - byte[] enData = SYD_SM4_ShortData(iEncKeyIndex, pcData, Consts.ECB_ENC); - // mac 长度放宽到 1040,因为密文填充 - byte[] mac = SYD_SM4Mac_ShortData(iMacKeyIndex, enData, 1040); - return new DataAndMac(enData, mac); + + if ( null != phHandle ) { + + return SYD_SM4_EncryptAndMac_ShortData_c(iEncKeyIndex, iMacKeyIndex, pcData); + + } else { + // 参数检查在函数内部 + byte[] enData = SYD_SM4_ShortData(iEncKeyIndex, pcData, Consts.ECB_ENC); + // mac 长度放宽到 1040,因为密文填充 + byte[] mac = SYD_SM4Mac_ShortData(iMacKeyIndex, enData, 1040); + return new DataAndMac(enData, mac); + } + } + + public DataAndMacCheck SYD_SM4_CheckMacAndDecrypt_ShortData_c(int iEncKeyIndex, int iMacKeyIndex, byte[] pcData, byte[] macs) { + log.info("SYD_SM4_CheckMacAndDecrypt_ShortData_c {} {}", iEncKeyIndex, iMacKeyIndex); + try { + + byte[] decryptedData = new byte[pcData.length]; + IntByReference decryptedDataLen = new IntByReference(decryptedData.length); + + + int i = SydLibrary.INSTANCE.SYD_SM4_Decrypt_Mac_ShortData( + phHandle.getValue(), + iEncKeyIndex, + iMacKeyIndex, + pcData, + pcData.length, + macs, + decryptedData, + decryptedDataLen + ); + + byte[] data = new byte[decryptedDataLen.getValue()]; + System.arraycopy(decryptedData, 0, data, 0, data.length); + + if (0 == i) { + return new DataAndMacCheck(data, true); + } + if (0x01000010 == i) { + return new DataAndMacCheck(data, false); + } else { + throw new SydApiException(i); + } + } catch (SydApiException e) { + throw e; + } catch (Exception e) { + if (e.getCause() instanceof SydApiException) { + throw (SydApiException) e.getCause(); + } + throw new SydApiException("并行任务执行失败", 0xC101, e); + } } @@ -899,14 +1014,21 @@ public class SydApiBaseFunction implements SydApi { log.debug("SYD_SM4_CheckMacAndDecrypt_ShortData:k1={} k2={}", iEncKeyIndex, iMacKeyIndex); } - boolean ret = SYD_SM4Mac_ShortData(iMacKeyIndex, pcData, 1040, mac); - byte[] data = null; - try { - data = SYD_SM4_ShortData(iEncKeyIndex, pcData, Consts.ECB_DEC); - } catch (Exception e) { - return new DataAndMacCheck(null, ret); + if( null != phHandle ) { + return SYD_SM4_CheckMacAndDecrypt_ShortData_c(iEncKeyIndex, iMacKeyIndex, pcData, mac); + } else { + boolean ret = SYD_SM4Mac_ShortData(iMacKeyIndex, pcData, 1040, mac); + byte[] data = null; + if (!ret){ + return new DataAndMacCheck(data, ret); + } + try { + data = SYD_SM4_ShortData(iEncKeyIndex, pcData, Consts.ECB_DEC); + } catch (Exception e) { + return new DataAndMacCheck(null, ret); + } + return new DataAndMacCheck(data, ret); } - return new DataAndMacCheck(data, ret); } @@ -968,13 +1090,56 @@ public class SydApiBaseFunction implements SydApi { datas.add(pcDatum.getData()); } - boolean[] macCheck = SYD_SM4Mac_BatchData(iMacKeyIndex, datas, macs); - List enData = SYD_SM4_BatchData(iEncKeyIndex, datas, Consts.ECB_DEC); +// boolean[] macCheck = SYD_SM4Mac_BatchData(iMacKeyIndex, datas, macs); +// List enData = SYD_SM4_BatchData(iEncKeyIndex, datas, Consts.ECB_DEC); +// +// List ret = new ArrayList<>(enData.size()); +// for (int i = 0; i < enData.size(); i++) { +// DataAndMacCheck damc = new DataAndMacCheck(enData.get(i), macCheck[i]); +// ret.add(damc); +// } - List ret = new ArrayList<>(enData.size()); - for (int i = 0; i < enData.size(); i++) { - DataAndMacCheck damc = new DataAndMacCheck(enData.get(i), macCheck[i]); - ret.add(damc); + // 批量执行MAC校验 + boolean[] macCheck = SYD_SM4Mac_BatchData(iMacKeyIndex, datas, macs); + + // 分离通过和未通过MAC校验的数据 + List validIndices = new ArrayList<>(); + List validData = new ArrayList<>(); + List validKeyIndices = new ArrayList<>(); + + for (int i = 0; i < macCheck.length; i++) { + if (macCheck[i]) { + validIndices.add(i); + validData.add(datas.get(i)); + validKeyIndices.add(iEncKeyIndex[i]); + } + } + + // 仅对通过MAC校验的数据进行批量解密 + List decryptedData; + if (validData.isEmpty()) { + decryptedData = Collections.emptyList(); + } else { + // 转换为数组(根据SYD_SM4_BatchData的接口要求) + int[] validKeysArray = validKeyIndices.stream() + .mapToInt(Integer::intValue) + .toArray(); + // 使用过滤后的密钥索引和数据 + decryptedData = SYD_SM4_BatchData(validKeysArray, validData, Consts.ECB_DEC); + } + + // 构建结果集 + List ret = new ArrayList<>(pcData.size()); + int decryptedIndex = 0; + + for (int i = 0; i < pcData.size(); i++) { + if (macCheck[i]) { + // 对于通过校验的条目,使用解密数据 + ret.add(new DataAndMacCheck(decryptedData.get(decryptedIndex++), true)); + } else { + // 对于未通过校验的条目,返回null + ret.add(new DataAndMacCheck(null, false)); + } } return ret; diff --git a/src/main/resources/linux-x86-64/libsunyard.so b/src/main/resources/linux-x86-64/libsunyard.so index 86ae168..b85cbf7 100644 Binary files a/src/main/resources/linux-x86-64/libsunyard.so and b/src/main/resources/linux-x86-64/libsunyard.so differ diff --git a/src/test/java/test/FuncTest.java b/src/test/java/test/FuncTest.java index f27608c..25a2ed7 100644 --- a/src/test/java/test/FuncTest.java +++ b/src/test/java/test/FuncTest.java @@ -355,6 +355,10 @@ public class FuncTest { DataAndMacCheck de_data1 = api.SYD_SM4_CheckMacAndDecrypt_ShortData(keyEnc, keyMac, en_data1.getData(), en_data1.getMac()); System.out.println("step3 " + de_data1.getMacCheck()); + //错误测试 + System.out.println("MAC校验失败,不继续进行解密测试"); + DataAndMacCheck de_data_err = api.SYD_SM4_CheckMacAndDecrypt_ShortData(keyEnc, keyMac, en_data1.getData(), new byte[16]); + System.out.println("错误测试返回MAC校验结果:"+de_data_err.getMacCheck()); try { DataAndMac en_data2 = api.SYD_SM4_EncryptAndMac_ShortData(keyEnc, keyMac, data2); @@ -436,6 +440,18 @@ public class FuncTest { System.out.println("short link"); } + System.out.println("批量数据mac校验并解密,mac校验失败测试"); + + en_data.get(1).setMac(new byte[16]); + + List de_data1 = api.SYD_SM4_CheckMacAndDecrypt_BatchData(keyEnc, keyMac, en_data); + int index = 0; + for (DataAndMacCheck item : de_data1) { + boolean macCheck = item.getMacCheck(); + + System.out.println("索引 " + (index++) + ":"+"MAC校验结果为:"+macCheck); + } + System.out.println("-------- 批量数据加密计算MAC,校验MAC解密功能测试结束 --------\n"); } diff --git a/src/test/java/test/TestAll.java b/src/test/java/test/TestAll.java index 0af5a21..f6d41f6 100644 --- a/src/test/java/test/TestAll.java +++ b/src/test/java/test/TestAll.java @@ -456,17 +456,26 @@ public class TestAll { int keyEnc = 0; int keyMac = 0; - SydApiBuilder builder = new SydApiBuilder( - config.getIps(), - config.getPorts(), - 1000, - 2000 - ); +// SydApiBuilder builder = new SydApiBuilder( +// config.getIps(), +// config.getPorts(), +// 1000, +// 2000 +// ); +// +// ThreadLocal Api = new ThreadLocal() { +// @Override +// protected SydApi initialValue() { +// return builder.build(); +// } +// }; ThreadLocal Api = new ThreadLocal() { @Override protected SydApi initialValue() { - return builder.build(); + SydApi api = new SydApi4Database(); + api.SYD_Short_Connect_Ex(config.getIps(),config.getPorts(),1000,2000); + return api; } }; diff --git a/src/test/java/test/TestMAC.java b/src/test/java/test/TestMAC.java new file mode 100644 index 0000000..36c2ce4 --- /dev/null +++ b/src/test/java/test/TestMAC.java @@ -0,0 +1,829 @@ +package test; + +import com.sunyard.sge.database.*; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class TestMAC { + private static final String[] ipListElec = new String[]{"127.0.0.1", "172.1.41.129"}; + private static final String[] ipListLight = new String[]{"192.168.110.240", "192.168.100.45"}; + + private static final String[] ipList = ipListLight; + private static final String[] ipListErr = new String[]{"172.2.41.216", "172.2.41.129"}; + + public static final int ECB_DEC = 0; + public static final int ECB_ENC = 1; + + + public static void setLog() { + System.setProperty("com.sunyard.sydapi4j.debug", "false"); + } + + + private static void startPerformanceFile() { + try (FileWriter fw = new FileWriter(PERF_RESULT_FILE, true); + BufferedWriter bw = new BufferedWriter(fw)) { + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String timeStr = sdf.format(now); + bw.write("==================== Performance Test Start: " + timeStr + " ===================="); + bw.newLine(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void stopPerformanceFile() { + try (FileWriter fw = new FileWriter(PERF_RESULT_FILE, true); + BufferedWriter bw = new BufferedWriter(fw)) { + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String timeStr = sdf.format(now); + bw.write("==================== Performance Test End: " + timeStr + " ===================="); + bw.newLine(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void writeToPerformanceFile(String interfaceName, int dataLen, int machineCount, int threadNum, int totalRequests, double tps, double avgLatency) { + try (FileWriter fw = new FileWriter(PERF_RESULT_FILE, true); + BufferedWriter bw = new BufferedWriter(fw)) { + String line = String.format("%s\t%d\t%d\t%d\t%d\t%.2f\t%.2f", + interfaceName, dataLen, machineCount, threadNum, totalRequests, tps, avgLatency); + bw.write(line); + bw.newLine(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void writeToPerformanceFile(String interfaceName, int dataLen, int machineCount, int threadNum, int totalRequests, String tps, double avgLatency) { + try (FileWriter fw = new FileWriter(PERF_RESULT_FILE, true); + BufferedWriter bw = new BufferedWriter(fw)) { + String line = String.format("%s\t%d\t%d\t%d\t%d\t%s\t%.2f", + interfaceName, dataLen, machineCount, threadNum, totalRequests, tps, avgLatency); + bw.write(line); + bw.newLine(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void writeToPerformanceFile2(String interfaceName, String dataLen, int machineCount, int threadNum, double totalRequests) { + try (FileWriter fw = new FileWriter(PERF_RESULT_FILE, true); + BufferedWriter bw = new BufferedWriter(fw)) { + String line = String.format("%s\t%s\t%d\t%d\t%.2f", + interfaceName, dataLen, machineCount, threadNum, totalRequests); + bw.write(line); + bw.newLine(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + public static void menu1(Config config, Choise choise, TestMAC test) throws Exception { + + FuncTest funcTest = new FuncTest(config); + + + while (true) { + System.out.println("请选择测试项:"); +// System.out.println("1. 功能单项测试"); +// System.out.println("2. 功能全量测试"); + System.out.println("1. 性能单项测试"); + System.out.println("2. 性能全量测试"); + + System.out.println("-1. 退出"); + + switch (choise.getAsInt()) { +// case 1: +// SydApi.SYD_SetLogConfig("./logs", 3); +// funcTest.funcMenu(config, choise, funcTest); +// break; +// case 2: +// funcTest.funcAll(); +// break; + case 1: + SydApi.SYD_SetLogConfig("./logs", 0); + perfMenu(config, choise, test); + break; + case 2: + SydApi.SYD_SetLogConfig("./logs", 0); + startPerformanceFile(); + test.perfAll(); + stopPerformanceFile(); + break; + default: + System.exit(0); + } + } + } + + + public void sm4ShortEndes() throws InterruptedException { + System.out.println("-------- SM4短数据加解密性能测试开始 --------"); + sm4ShortEnde(1, config.getTotal(), 1024); + sm4ShortEnde(40, config.getTotal(), 1024); + System.out.println("-------- SM4短数据加解密性能测试结束 --------\n"); + } + + private static final String PERF_RESULT_FILE = "performance_results.txt"; + + + public void sm4ShortEnde(int numberOfThreads, int totalRequest, int plainLen) throws InterruptedException { + byte[] data = new byte[plainLen]; + SydApiBuilder builder = new SydApiBuilder( + config.getIps(), + config.getPorts(), + 1000, + 2000 + ); + + ThreadLocal Api = new ThreadLocal() { + @Override + protected SydApi initialValue() { + return builder.build(); + } + }; + + ExecutorService poolEnc = Executors.newFixedThreadPool(numberOfThreads); + long start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolEnc.submit(() -> { + SydApi api = Api.get(); + api.SYD_SM4_ShortData(0, data, ECB_ENC); + }); + } + poolEnc.shutdown(); + poolEnc.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + long end = System.currentTimeMillis(); + long duration = end - start; + double tps = totalRequest * 1000.0 / duration; + double throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("加密共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + double avgLatencyEnc = numberOfThreads * duration * 1.0 / totalRequest; + System.out.println("平均延时(加密): " + String.format("%.2f", avgLatencyEnc) + " ms"); + + writeToPerformanceFile("SM4短数据加密", 1024, 1, numberOfThreads, totalRequest, tps, avgLatencyEnc); + + SydApi apiTest = Api.get(); + byte[] res = apiTest.SYD_SM4_ShortData(0, data, ECB_ENC); + + ExecutorService poolDec = Executors.newFixedThreadPool(numberOfThreads); + start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolDec.submit(() -> { + SydApi api = Api.get(); + byte[] plain = api.SYD_SM4_ShortData(0, res, ECB_DEC); + }); + } + poolDec.shutdown(); + poolDec.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + end = System.currentTimeMillis(); + duration = end - start; + tps = totalRequest * 1000.0 / duration; + throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("解密共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + double avgLatencyDec = numberOfThreads * duration * 1.0 / totalRequest; + System.out.println("平均延时(解密): " + String.format("%.2f", avgLatencyDec) + " ms"); + + writeToPerformanceFile("SM4短数据解密", 1024, 1, numberOfThreads, totalRequest, tps, avgLatencyDec); + } + + public void sm4BatchEndes() throws InterruptedException { + System.out.println("-------- SM4批量数据加解密性能测试开始 --------"); + sm4BatchEnde(1, config.getTotal(), 1024); + sm4BatchEnde(40, config.getTotal(), 1024); + System.out.println("-------- SM4批量数据加解密性能测试结束 --------\n"); + } + + public void sm4BatchEnde(int numberOfThreads, int totalRequest, int plainLen) throws InterruptedException { + int[] keyIdx = new int[]{0, 0, 0, 0}; + List data = new ArrayList<>(); + data.add(new byte[1024]); + data.add(new byte[1024]); + data.add(new byte[1024]); + data.add(new byte[1024]); + + SydApiBuilder builder = new SydApiBuilder( + config.getIps(), + config.getPorts(), + 1000, + 2000 + ); + + ThreadLocal Api = new ThreadLocal() { + @Override + protected SydApi initialValue() { + return builder.build(); + } + }; + + ExecutorService poolEnc = Executors.newFixedThreadPool(numberOfThreads); + long start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolEnc.submit(() -> { + SydApi api = Api.get(); + api.SYD_SM4_BatchData(keyIdx, data, ECB_ENC); + }); + } + poolEnc.shutdown(); + poolEnc.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + long end = System.currentTimeMillis(); + long duration = end - start; + double tps = totalRequest * 1000.0 / duration; + double throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("加密共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + double avgLatency = numberOfThreads * duration * 1.0 / totalRequest; + writeToPerformanceFile("SM4批量数据加密", 1024, 1, numberOfThreads, totalRequest, String.format("%.2f", tps) + " x 4", avgLatency); + + SydApi apiTest = Api.get(); + List res = apiTest.SYD_SM4_BatchData(keyIdx, data, ECB_ENC); + + ExecutorService poolDec = Executors.newFixedThreadPool(numberOfThreads); + start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolDec.submit(() -> { + SydApi api = Api.get(); + List plain = api.SYD_SM4_BatchData(keyIdx, res, ECB_DEC); + }); + } + poolDec.shutdown(); + poolDec.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + end = System.currentTimeMillis(); + duration = end - start; + tps = totalRequest * 1000.0 / duration; + throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("解密共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + avgLatency = numberOfThreads * duration * 1.0 / totalRequest; + writeToPerformanceFile("SM4批量数据解密", 1024, 1, numberOfThreads, totalRequest, tps, avgLatency); + } + + + public void sm4macShortEndes() throws InterruptedException { + System.out.println("-------- SM4MAC短数据性能测试开始 --------"); + sm4macShortEnde(1, config.getTotal(), 1024); + sm4macShortEnde(40, config.getTotal(), 1024); + System.out.println("-------- SM4MAC短数据性能测试结束 --------\n"); + } + + + public void sm4macShortEnde(int numberOfThreads, int totalRequest, int plainLen) throws InterruptedException { + byte[] data = new byte[plainLen]; + SydApiBuilder builder = new SydApiBuilder( + config.getIps(), + config.getPorts(), + 1000, + 2000 + ); + + ThreadLocal Api = new ThreadLocal() { + @Override + protected SydApi initialValue() { + return builder.build(); + } + }; + + ExecutorService poolEnc = Executors.newFixedThreadPool(numberOfThreads); + long start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolEnc.submit(() -> { + SydApi api = Api.get(); + api.SYD_SM4Mac_ShortData(0, data); + }); + } + poolEnc.shutdown(); + poolEnc.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + long end = System.currentTimeMillis(); + long duration = end - start; + double tps = totalRequest * 1000.0 / duration; + double throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + double avgLatency = numberOfThreads * duration * 1.0 / totalRequest; + writeToPerformanceFile("SM4MAC 短数据", 1024, 1, numberOfThreads, totalRequest, tps, avgLatency); + } + + public void sm4macBatchEndes() throws InterruptedException { + System.out.println("-------- SM4MAC批量数据性能测试开始 --------"); + sm4macBatchEnde(1, config.getTotal(), 1024); + sm4macBatchEnde(40, config.getTotal(), 1024); + System.out.println("-------- SM4MAC 批量数据性能测试结束 --------\n"); + } + + public void sm4macBatchEnde(int numberOfThreads, int totalRequest, int plainLen) throws InterruptedException { + int[] keyIdx = new int[]{0, 0, 0, 0}; + SydApiBuilder builder = new SydApiBuilder( + config.getIps(), + config.getPorts(), + 1000, + 2000 + ); + + ThreadLocal Api = new ThreadLocal() { + @Override + protected SydApi initialValue() { + return builder.build(); + } + }; + List data = new ArrayList<>(); + data.add(new byte[1024]); + data.add(new byte[1024]); + data.add(new byte[1024]); + data.add(new byte[1024]); + + ExecutorService poolEnc = Executors.newFixedThreadPool(numberOfThreads); + long start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolEnc.submit(() -> { + SydApi api = Api.get(); + List s = api.SYD_SM4Mac_BatchData(keyIdx, data); + }); + } + poolEnc.shutdown(); + poolEnc.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + long end = System.currentTimeMillis(); + long duration = end - start; + double tps = totalRequest * 1000.0 / duration; + double throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + double avgLatency = numberOfThreads * duration * 1.0 / totalRequest; + writeToPerformanceFile("SM4MAC 批量数据", 1024, 1, numberOfThreads, totalRequest, String.format("%.2f", tps) + " x 4", avgLatency); + } + + public void sm3ShortEndes() throws InterruptedException { + System.out.println("-------- SM3短数据性能测试开始 --------"); + sm3ShortEnde(1, config.getTotal(), 1024); + sm3ShortEnde(40, config.getTotal(), 1024); + System.out.println("-------- SM3短数据性能测试结束 --------\n"); + } + + public void sm3ShortEnde(int numberOfThreads, int totalRequest, int plainLen) throws InterruptedException { + byte[] data = new byte[plainLen]; + SydApiBuilder builder = new SydApiBuilder( + config.getIps(), + config.getPorts(), + 1000, + 2000 + ); + + ThreadLocal Api = new ThreadLocal() { + @Override + protected SydApi initialValue() { + return builder.build(); + } + }; + + ExecutorService poolEnc = Executors.newFixedThreadPool(numberOfThreads); + long start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolEnc.submit(() -> { + SydApi api = Api.get(); + api.SYD_SM3_Hash_ShortData(data); + }); + } + poolEnc.shutdown(); + poolEnc.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + long end = System.currentTimeMillis(); + long duration = end - start; + double tps = totalRequest * 1000.0 / duration; + double throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + double avgLatency = numberOfThreads * duration * 1.0 / totalRequest; + writeToPerformanceFile("SM3 短数据", 1024, 1, numberOfThreads, totalRequest, tps, avgLatency); + } + + public void sm4ShortMacEndes() throws InterruptedException { + System.out.println("-------- SM4短数据加密生成MAC,验证MAC解密性能测试开始 --------"); + System.out.println("单线程"); + sm4ShortMacEnde(1, config.getTotal(), 1024); + + System.out.println("40 线程"); + sm4ShortMacEnde(40, config.getTotal(), 1024); + System.out.println("-------- SM4短数据加密生成MAC,验证MAC解密性能测试结束 --------\n"); + } + + public void sm4ShortMacEnde(int numberOfThreads, int totalRequest, int plainLen) throws InterruptedException { + byte[] data = new byte[plainLen]; + int keyEnc = 0; + int keyMac = 0; + + SydApiBuilder builder = new SydApiBuilder( + config.getIps(), + config.getPorts(), + 1000, + 2000 + ); + + ThreadLocal Api = new ThreadLocal() { + @Override + protected SydApi initialValue() { + return builder.build(); + } + }; + + SydApi apiTest = Api.get(); + DataAndMac ret = apiTest.SYD_SM4_EncryptAndMac_ShortData(keyEnc, keyMac, data); + + + ExecutorService poolEnc = Executors.newFixedThreadPool(numberOfThreads); + long start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolEnc.submit(() -> { + SydApi api = Api.get(); + api.SYD_SM4_EncryptAndMac_ShortData(keyEnc, keyMac, data); + }); + } + poolEnc.shutdown(); + poolEnc.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + long end = System.currentTimeMillis(); + long duration = end - start; + double tps = totalRequest * 1000.0 / duration; + double throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("加密共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + double avgLatency = numberOfThreads * duration * 1.0 / totalRequest; + writeToPerformanceFile("SM4短数据加密并生成MAC", 1024, 1, numberOfThreads, totalRequest, tps, avgLatency); + + + ExecutorService poolDec = Executors.newFixedThreadPool(numberOfThreads); + start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolDec.submit(() -> { + SydApi api = Api.get(); + api.SYD_SM4_CheckMacAndDecrypt_ShortData(keyEnc, keyMac, ret.getData(), ret.getMac()); + }); + } + poolDec.shutdown(); + poolDec.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + end = System.currentTimeMillis(); + duration = end - start; + tps = totalRequest * 1000.0 / duration; + throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("解密共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + avgLatency = numberOfThreads * duration * 1.0 / totalRequest; + writeToPerformanceFile("SM4短数据解密并校验MAC", 1024, 1, numberOfThreads, totalRequest, tps, avgLatency); + } + + public void sm4BatchMacEndes() throws InterruptedException { + System.out.println("-------- SM4批量数据加密生成MAC,验证MAC解密性能测试开始 --------"); + System.out.println("单线程"); + sm4BatchMacEnde(1, config.getTotal(), 1024); + System.out.println("40 线程"); + sm4BatchMacEnde(40, config.getTotal(), 1024); + System.out.println("-------- SM4批量数据加密生成MAC,验证MAC解密性能测试结束 --------\n"); + } + + public void sm4BatchMacEnde(int numberOfThreads, int totalRequest, int plainLen) throws InterruptedException { + int[] keyEnc = new int[]{0, 0, 0, 0}; + int[] keyMac = new int[]{0, 0, 0, 0}; + List data = new ArrayList<>(); + data.add(new byte[plainLen]); + data.add(new byte[plainLen]); + data.add(new byte[plainLen]); + data.add(new byte[plainLen]); + + SydApiBuilder builder = new SydApiBuilder( + config.getIps(), + config.getPorts(), + 1000, + 2000 + ); + + + ThreadLocal Api = new ThreadLocal() { + @Override + protected SydApi initialValue() { + return builder.build(); + } + }; + SydApi apiTest = Api.get(); + List ret = apiTest.SYD_SM4_EncryptAndMac_BatchData(keyEnc, keyMac, data); + + + ExecutorService poolEnc = Executors.newFixedThreadPool(numberOfThreads); + long start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolEnc.submit(() -> { + SydApi api = Api.get(); + api.SYD_SM4_EncryptAndMac_BatchData(keyEnc, keyMac, data); + }); + } + poolEnc.shutdown(); + poolEnc.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + long end = System.currentTimeMillis(); + long duration = end - start; + double tps = totalRequest * 1000.0 / duration; + double throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("加密共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + double avgLatency = numberOfThreads * duration * 1.0 / totalRequest; + writeToPerformanceFile("SM4批量数据加密并生成MAC", 1024, 1, numberOfThreads, totalRequest, String.format("%.2f", tps) + " x 4", avgLatency); + + ExecutorService poolDec = Executors.newFixedThreadPool(numberOfThreads); + start = System.currentTimeMillis(); + for (int i = 0; i < totalRequest; i++) { + poolDec.submit(() -> { + SydApi api = Api.get(); + api.SYD_SM4_CheckMacAndDecrypt_BatchData(keyEnc, keyMac, ret); + }); + } + poolDec.shutdown(); + poolDec.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + + end = System.currentTimeMillis(); + duration = end - start; + tps = totalRequest * 1000.0 / duration; + throughput = totalRequest * 1000.0 / duration * plainLen / 1024 / 1024; + + System.out.println("并发数: " + numberOfThreads); + System.out.println("解密共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("TPS: " + String.format("%.2f", tps)); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + avgLatency = numberOfThreads * duration * 1.0 / totalRequest; + writeToPerformanceFile("SM4批量数据解密并校验MAC", 1024, 1, numberOfThreads, totalRequest, String.format("%.2f", tps) + " x 4", avgLatency); + } + + + public void sm4LongEnde() { + System.out.println("-------- SM4长数据加解密性能测试开始 --------"); + + byte[] data = new byte[2048]; + int key = 0; +// ByteBuffer enDataBuff = ByteBuffer.allocate(100 * 1024 * 1024 + 16); + + SydApiBuilder builder = new SydApiBuilder( + config.getIps(), + config.getPorts(), + 1000, + 2000 + ); + + long start = System.currentTimeMillis(); + SydApi api = builder.build(); + + ISM4 sm4 = api.initSM4(key, ECB_ENC); + for (int i = 0; i < 100 * 1024 * 1024 / data.length; i++) { + sm4.update(data); + } + byte[] res = sm4.finish(); + + long end = System.currentTimeMillis(); + long duration = end - start; + double throughput = 100.0 * 1000 / duration; + + System.out.println("加密共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + writeToPerformanceFile2("SM4长数据加密", "100M", 1, 1, throughput); + + start = System.currentTimeMillis(); + + sm4 = api.initSM4(key, ECB_DEC); + for (int i = 0; i < 100 * 1024 * 1024 / data.length; i++) { + sm4.update(data); + } + // sm4.finish(); + + end = System.currentTimeMillis(); + duration = end - start; + throughput = 100.0 * 1000 / duration; + + System.out.println("解密共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + writeToPerformanceFile2("SM4长数据解密", "100M", 1, 1, throughput); + + System.out.println("-------- SM4长数据加解密性能测试结束 --------\\n"); + + } + + public void sm4MacLongEnde() { + System.out.println("-------- SM4MAC长数据性能测试开始 --------"); + + byte[] data = new byte[2048]; + + SydApiBuilder builder = new SydApiBuilder( + config.getIps(), + config.getPorts(), + 1000, + 2000 + ); + + long start = System.currentTimeMillis(); + SydApi api = builder.build(); + + ISM4Mac sm4mac = api.initSM4Mac(0); + for (int i = 0; i < 100 * 1024 * 1024 / data.length; i++) { + sm4mac.update(data); + } + sm4mac.digest(); + + long end = System.currentTimeMillis(); + long duration = end - start; + double throughput = 100.0 * 1000 / duration; + + System.out.println("共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + writeToPerformanceFile2("SM4长数据MAC", "100M", 1, 1, throughput); + + System.out.println("-------- SM4MAC长数据性能测试结束 --------"); + } + + public void sm3LongEnde() { + System.out.println("-------- SM3长数据性能测试开始 --------"); + + byte[] data = new byte[2048]; + + SydApiBuilder builder = new SydApiBuilder( + config.getIps(), + config.getPorts(), + 1000, + 2000 + ); + + long start = System.currentTimeMillis(); + SydApi api = builder.build(); + + ISM3 sm3 = api.initSM3(); + for (int i = 0; i < 100 * 1024 * 1024 / data.length; i++) { + sm3.update(data); + } + sm3.digest(); + + long end = System.currentTimeMillis(); + long duration = end - start; + double throughput = 100.0 * 1000 / duration; + + System.out.println("共花费 " + String.format("%.2f", duration / 1000.0) + " 秒"); + System.out.println("吞吐量: " + String.format("%.2f", throughput) + " MB/S"); + writeToPerformanceFile2("SM3长数据", "100MB", 1, 1, throughput); + + System.out.println("-------- SM3长数据性能测试结束 --------"); + } + + + public void perfAll() throws InterruptedException { + this.sm4ShortEndes(); + this.sm4BatchEndes(); +// this.sm4macShortEndes(); +// this.sm4macBatchEndes(); +// this.sm3ShortEndes(); + this.sm4ShortMacEndes(); + this.sm4BatchMacEndes(); + +// this.sm4LongEnde(); +// this.sm4MacLongEnde(); +// this.sm3LongEnde(); + } + + + public static void showmenu() { + System.out.println("请选择测试项:"); + System.out.println("1.SM4 短数据加解密"); + System.out.println("2.SM4 批量数据加解密"); +// System.out.println("3.SM4MAC 短数据"); +// System.out.println("4.SM4MAC 批量数据"); +// System.out.println("5.SM3 短数据"); + System.out.println("6.SM4 短数据加密后生成MAC,解密验证MAC"); + System.out.println("7.SM4 批量数据加密后生成MAC,解密验证MAC"); +// System.out.println("8.SM4 长数据加解密"); +// System.out.println("9.SM4 长数据MAC"); +// System.out.println("10.SM3 长数据"); +// System.out.println("11. 短数据 SM4+MAC性能测试"); +// System.out.println("12. 批量数据 SM4+MAC性能测试"); + System.out.println("-1.退出"); + } + + public static void perfMenu(Config config, Choise choise, TestMAC test) throws Exception { + + boolean flag = true; + + while (flag) { + showmenu(); + switch (choise.getAsInt()) { + case 1: + test.sm4ShortEndes(); + break; + case 2: + test.sm4BatchEndes(); + break; +// case 3: +// test.sm4macShortEndes(); +// break; +// case 4: +// test.sm4macBatchEndes(); +// break; +// case 5: +// test.sm3ShortEndes(); +// break; + case 6: + test.sm4ShortMacEndes(); + break; + case 7: + test.sm4BatchMacEndes(); + break; +// case 8: +// test.sm4LongEnde(); +// break; +// case 9: +// test.sm4MacLongEnde(); +// break; +// case 10: +// test.sm3LongEnde(); +// break; +// case 11: { +// test.sm4ShortMacEndes(); +// break; +// } +// case 12: { +// test.sm4BatchMacEndes(); +// break; +// } + case -1: + flag = false; + break; + } + } + } + + + private static Config config = null; + + public static void main(String[] args) throws Exception { + + // 载入配置文件 + config = Config.loadConfig(); + if (config == null || config.isDebug()) { + System.setProperty("com.sunyard.sydapi4j.debug", "true"); + } + + System.out.println("ips=" + Arrays.toString(config.getIps())); + System.out.println("ports=" + Arrays.toString(config.getPorts())); + System.out.println("debug=" + config.isDebug()); + + + TestMAC test = new TestMAC(); + Choise choise = new Choise(args); + menu1(config, choise, test); + + } + +}